Version 2.0.0-dev.56.0
Merge commit '0ff6c20c6660bd123c49fb09d09994577e3de097' into dev
diff --git a/BUILD.gn b/BUILD.gn
index fe6513a..f4f9bec 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -13,7 +13,7 @@
testonly = true
}
deps = [
- ":runtime",
+ ":runtime_kernel",
]
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a13f6d2..563a2fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,50 @@
+## 2.0.0-dev.56.0
+
+### Language
+
+* Invocations of noSuchMethod receive default values for optional args.
+ * The following program used to print "No arguments passed", and now prints
+ "First argument is 3".
+
+```dart
+abstract class B {
+ void m([int x = 3]);
+}
+
+class A implements B {
+ noSuchMethod(Invocation i) {
+ if (i.positionalArguments.length == 0) {
+ print("No arguments passed");
+ } else {
+ print("First argument is ${i.positionalArguments[0]}");
+ }
+ }
+}
+
+void main() {
+ A().m();
+}
+```
+
+### Core library changes
+
+* `dart:core`
+ * Deprecated the `NoSuchMethodError` constructor.
+
+* `dart:mirrors`
+ * Marked `MirrorsUsed` as deprecated. The mirrors library is no longer
+ supported by dart2js, and `MirrorsUsed` only affected dart2js.
+
+* `dart:io`
+ * Added `X509Certificate.der`, `X509Certificate.pem`, and
+ `X509Certificate.sha1`.
+
+### Tool Changes
+
+#### dartfmt
+
+ * Support metadata annotations on enum cases.
+
## 2.0.0-dev.55.0
### Language
diff --git a/DEPS b/DEPS
index 6e0ad81..204088f 100644
--- a/DEPS
+++ b/DEPS
@@ -47,15 +47,11 @@
# Scripts that make 'git cl format' work.
"clang_format_scripts_rev": "c09c8deeac31f05bd801995c475e7c8070f9ecda",
- "gperftools_revision": "02eeed29df112728564a5dde6417fa4622b57a06",
+ "gperftools_revision": "9608fa3bcf8020d35f59fbf70cd3cbe4b015b972",
# Revisions of /third_party/* dependencies.
"args_tag": "1.4.1",
- "async_tag": "2.0.6",
- "barback-0.13.0_rev": "34853",
- "barback-0.14.0_rev": "36398",
- "barback-0.14.1_rev": "38525",
- "barback_tag" : "0.15.2+14",
+ "async_tag": "2.0.7",
"bazel_worker_tag": "v0.1.9",
"boolean_selector_tag" : "1.0.3",
"boringssl_gen_rev": "344f455fd13d46f054726638e76026156ea73aa9",
@@ -63,7 +59,7 @@
"charcode_tag": "v1.1.1",
"chrome_rev" : "19997",
"cli_util_tag" : "0.1.2+1",
- "collection_tag": "1.14.6",
+ "collection_tag": "1.14.9",
"convert_tag": "2.0.1",
"crypto_tag" : "2.0.2+1",
"csslib_tag" : "0.14.1",
@@ -81,7 +77,7 @@
# minutes later.
#
# For more details, see https://github.com/dart-lang/sdk/issues/30164
- "dart_style_tag": "1.0.12", # Please see the note above before updating.
+ "dart_style_tag": "1.0.14", # Please see the note above before updating.
"dartdoc_tag" : "v0.19.0",
"fixnum_tag": "0.10.5",
@@ -93,12 +89,12 @@
"http_parser_tag" : "3.1.1",
"http_retry_tag": "0.1.1",
"http_tag" : "0.11.3+16",
- "http_throttle_tag" : "1.0.1",
+ "http_throttle_tag" : "1.0.2",
"idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
"intl_tag": "0.15.2",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "2.0.6",
- "linter_tag": "0.1.50",
+ "linter_tag": "0.1.51",
"logging_tag": "0.11.3+1",
"markdown_tag": "1.1.1",
"matcher_tag": "0.12.1+4",
@@ -135,7 +131,7 @@
"test_process_tag": "1.0.1",
"term_glyph_tag": "1.0.0",
"test_reflective_loader_tag": "0.1.4",
- "test_tag": "0.12.30+1",
+ "test_tag": "0.12.38",
"tuple_tag": "v1.0.1",
"typed_data_tag": "1.1.3",
"usage_tag": "3.3.0",
@@ -200,8 +196,6 @@
Var("dart_git") + "args.git" + "@" + Var("args_tag"),
Var("dart_root") + "/third_party/pkg/async":
Var("dart_git") + "async.git" + "@" + Var("async_tag"),
- Var("dart_root") + "/third_party/pkg/barback":
- Var("dart_git") + "barback.git" + "@" + Var("barback_tag"),
Var("dart_root") + "/third_party/pkg/bazel_worker":
Var("dart_git") + "bazel_worker.git" + "@" + Var("bazel_worker_tag"),
Var("dart_root") + "/third_party/pkg/boolean_selector":
diff --git a/build/dart/dart_action.gni b/build/dart/dart_action.gni
index f5bf967..6bd19d7 100644
--- a/build/dart/dart_action.gni
+++ b/build/dart/dart_action.gni
@@ -6,6 +6,12 @@
import("dart_host_sdk_toolchain.gni")
import("prebuilt_dart_sdk.gni")
+_is_fuchsia = defined(is_fuchsia_tree) && is_fuchsia_tree
+
+if (_is_fuchsia) {
+ import("//build/dart/dart.gni")
+}
+
# This file defines templates for running and compiling Dart code during
# Dart's build.
#
@@ -90,6 +96,87 @@
}
}
+template("_prebuilt_tool_action") {
+ assert(defined(invoker.binary),
+ "The path to where the prebuilt binary lives must be defined")
+ assert(defined(invoker.target),
+ "The target to use if the prebuilt doesn't exist must be defined")
+
+ vm_args = []
+ if (defined(invoker.vm_args)) {
+ vm_args += invoker.vm_args
+ }
+
+ if (_is_fuchsia || prebuilt_dart_exe_works) {
+ not_needed(invoker, ["target"])
+ action(target_name) {
+ forward_variables_from(invoker, [
+ "outputs",
+ "deps",
+ "visibility",
+ "depfile",
+ ])
+ script = "$_dart_root/build/gn_run_binary.py"
+
+ inputs = []
+ if (defined(invoker.inputs)) {
+ inputs += invoker.inputs
+ }
+
+ if (defined(invoker.script)) {
+ inputs += [ invoker.script ]
+ }
+ if (defined(invoker.packages)) {
+ inputs += [ invoker.packages ]
+ }
+
+ args = [
+ "compiled_action",
+ rebase_path(invoker.binary),
+ ] + vm_args
+ if (defined(invoker.packages)) {
+ args += [
+ "--packages=" + rebase_path(invoker.packages),
+ ]
+ }
+ if (defined(invoker.script)) {
+ args += [ rebase_path(invoker.script) ]
+ }
+ args += invoker.args
+ }
+ } else {
+ not_needed(invoker, ["binary"])
+ _compiled_action(target_name) {
+ forward_variables_from(invoker, [
+ "inputs",
+ "outputs",
+ "deps",
+ "visibility",
+ "depfile",
+ ])
+
+ if (defined(invoker.script)) {
+ inputs += [ invoker.script ]
+ }
+ if (defined(invoker.packages)) {
+ inputs += [ invoker.packages ]
+ }
+
+ tool = invoker.target
+ args = vm_args
+ if (defined(invoker.packages)) {
+ args += [
+ "--packages=" + rebase_path(invoker.packages),
+ ]
+ }
+ if (defined(invoker.script)) {
+ args += [ rebase_path(invoker.script) ]
+ }
+ args += invoker.args
+ }
+ }
+}
+
# A template for running Dart scripts during the build using the prebuilt Dart
# SDK. This should *not* be used for generating snapshots. It uses the dart
# binary from the prebuilt Dart SDK if one is available, and dart_bootstrap
@@ -121,67 +208,28 @@
assert(!defined(invoker.sources),
"prebuilt_dart_action doesn't take a sources arg. Use inputs instead.")
- vm_args = []
- if (defined(invoker.vm_args)) {
- vm_args += invoker.vm_args
- }
-
- if (prebuilt_dart_exe_works) {
- action(target_name) {
- forward_variables_from(invoker, [
- "inputs",
- "outputs",
- "deps",
- "visibility",
- "depfile",
- ])
- script = "$_dart_root/build/gn_run_binary.py"
- prebuilt_dart_binary =
+ _prebuilt_tool_action(target_name) {
+ forward_variables_from(invoker, "*")
+ if (_is_fuchsia) {
+ binary = prebuilt_dart
+ } else {
+ binary =
"$_dart_root/tools/sdks/$host_os/dart-sdk/bin/dart$executable_suffix"
-
- inputs += [ invoker.script ]
- if (defined(invoker.packages)) {
- inputs += [ invoker.packages ]
- }
-
- args = [
- "compiled_action",
- rebase_path(prebuilt_dart_binary),
- ] + vm_args
- if (defined(invoker.packages)) {
- args += [
- "--packages=" + rebase_path(invoker.packages),
- ]
- }
- args += [ rebase_path(invoker.script) ] + invoker.args
}
- } else {
- _compiled_action(target_name) {
- forward_variables_from(invoker, [
- "inputs",
- "outputs",
- "deps",
- "visibility",
- "depfile",
- ])
-
- inputs += [ invoker.script ]
- if (defined(invoker.packages)) {
- inputs += [ invoker.packages ]
- }
-
- tool = "$_dart_root/runtime/bin:dart_bootstrap"
- args = vm_args
- if (defined(invoker.packages)) {
- args += [
- "--packages=" + rebase_path(invoker.packages),
- ]
- }
- args += [ rebase_path(invoker.script) ] + invoker.args
- }
+ target = "$_dart_root/runtime/bin:dart_bootstrap"
}
}
+if (_is_fuchsia) {
+template("_prebuilt_gen_snapshot_action") {
+ _prebuilt_tool_action(target_name) {
+ forward_variables_from(invoker, "*")
+ binary = prebuilt_gen_snapshot
+ target = "error"
+ }
+}
+}
+
# This template runs the specified tool produced by the in-progress build.
#
# Parameters:
@@ -272,20 +320,26 @@
# visibility
template("dart_action") {
assert(defined(invoker.script), "script must be defined for $target_name")
- _built_tool_action(target_name) {
- tool = "$_dart_root/runtime/bin:dart"
- forward_variables_from(invoker, [
- "args",
- "depfile",
- "deps",
- "inputs",
- "outputs",
- "packages",
- "script",
- "tool",
- "visibility",
- "vm_args",
- ])
+ if (!_is_fuchsia || !use_prebuilt_dart_sdk) {
+ _built_tool_action(target_name) {
+ tool = "$_dart_root/runtime/bin:dart"
+ forward_variables_from(invoker, [
+ "args",
+ "depfile",
+ "deps",
+ "inputs",
+ "outputs",
+ "packages",
+ "script",
+ "tool",
+ "visibility",
+ "vm_args",
+ ])
+ }
+ } else {
+ prebuilt_dart_action(target_name) {
+ forward_variables_from(invoker, "*")
+ }
}
}
@@ -312,20 +366,28 @@
# visibility
template("dart_bootstrap_action") {
assert(defined(invoker.script), "script must be defined for $target_name")
- _built_tool_action(target_name) {
- tool = "$_dart_root/runtime/bin:dart_bootstrap"
- forward_variables_from(invoker, [
- "args",
- "depfile",
- "deps",
- "inputs",
- "outputs",
- "packages",
- "script",
- "tool",
- "visibility",
- "vm_args",
- ])
+ if (!_is_fuchsia || !use_prebuilt_dart_sdk) {
+ _built_tool_action(target_name) {
+ tool = "$_dart_root/runtime/bin:dart_bootstrap"
+ forward_variables_from(invoker, [
+ "args",
+ "depfile",
+ "deps",
+ "inputs",
+ "outputs",
+ "packages",
+ "script",
+ "tool",
+ "visibility",
+ "vm_args",
+ ])
+ }
+ } else {
+ # We already have a prebuilt dart at the right version, so there is no
+ # reason to use dart_bootstrap.
+ prebuilt_dart_action(target_name) {
+ forward_variables_from(invoker, "*")
+ }
}
}
@@ -350,18 +412,24 @@
template("gen_snapshot_action") {
assert(!defined(invoker.script),
"script must not be defined for $target_name. If there is a script use args instead.")
- _built_tool_action(target_name) {
- tool = "$_dart_root/runtime/bin:gen_snapshot"
- forward_variables_from(invoker, [
- "args",
- "depfile",
- "deps",
- "inputs",
- "outputs",
- "packages",
- "tool",
- "visibility",
- "vm_args",
- ])
+ if (!_is_fuchsia || !use_prebuilt_dart_sdk) {
+ _built_tool_action(target_name) {
+ tool = "$_dart_root/runtime/bin:gen_snapshot"
+ forward_variables_from(invoker, [
+ "args",
+ "depfile",
+ "deps",
+ "inputs",
+ "outputs",
+ "packages",
+ "tool",
+ "visibility",
+ "vm_args",
+ ])
+ }
+ } else {
+ _prebuilt_gen_snapshot_action(target_name) {
+ forward_variables_from(invoker, "*")
+ }
}
}
diff --git a/build/dart/prebuilt_dart_sdk.gni b/build/dart/prebuilt_dart_sdk.gni
index 59e519c..2a5be7b 100644
--- a/build/dart/prebuilt_dart_sdk.gni
+++ b/build/dart/prebuilt_dart_sdk.gni
@@ -6,7 +6,8 @@
_dart_root = rebase_path("../..")
-_prebuilt_dart_exe = "$_dart_root/tools/sdks/$host_os/dart-sdk/bin/dart$executable_suffix"
+_prebuilt_dart_exe =
+ "$_dart_root/tools/sdks/$host_os/dart-sdk/bin/dart$executable_suffix"
# When the first argument is "exec_script", gn_run_binary.py always exits with
# status 0, but gives non-empty output when the command it is given fails.
diff --git a/docs/language/dart.sty b/docs/language/dart.sty
index 6f5a870..468a8e8 100644
--- a/docs/language/dart.sty
+++ b/docs/language/dart.sty
@@ -21,7 +21,9 @@
\def\GET{\builtinId{get}}
\def\IMPLEMENTS{\builtinId{implements}}
\def\IMPORT{\builtinId{import}}
+\def\INTERFACE{\builtinId{interface}}
\def\LIBRARY{\builtinId{library}}
+\def\MIXIN{\builtinId{mixin}}
\def\OPERATOR{\builtinId{operator}}
\def\PART{\builtinId{part}}
\def\SET{\builtinId{set}}
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 3d99fb8..4ad9e1d 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -45,6 +45,8 @@
% - Specify `call` for Dart 2 (no function type given to enclosing class).
% - Clarify that an identifier reference denoting a top-level, static, or
% local function evaluates to the closurization of that declaration.
+% - Make `mixin` and `interface` built-in identifiers.
+% - Make `async` *not* a reserved word inside async functions.
%
% 1.15
% - Change how language specification describes control flow.
@@ -6847,8 +6849,10 @@
\GET{};
\IMPLEMENTS{};
\IMPORT{};
+ \INTERFACE{};
\LIBRARY{};
\OPERATOR{};
+ \MIXIN{};
\PART{};
\SET{};
\STATIC{};
@@ -6891,7 +6895,7 @@
}
\LMHash{}
-It is a compile-time error if any of the identifiers \ASYNC, \AWAIT{} or \YIELD{} is used as an identifier in a function body marked with either \ASYNC{}, \ASYNC* or \SYNC*.
+It is a compile-time error if either of the identifiers \AWAIT{} or \YIELD{} is used as an identifier in a function body marked with either \ASYNC{}, \ASYNC* or \SYNC*.
\rationale{
For compatibility reasons, new constructs cannot rely upon new reserved words or even built-in identifiers.
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index a04fb4a..2182796 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -121,7 +121,7 @@
}
logger.log(Level.INFO, 'tmpSrcDir: ${args.tmpSrcDirPath}');
return inputRaw
- .transform(SYSTEM_ENCODING.decoder)
+ .transform(systemEncoding.decoder)
.transform(new LineSplitter())
.transform(new InputConverter(args.tmpSrcDirPath, args.srcPathMap));
}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 453a520..3e2656a 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- 1.20.2
+ 1.20.3
</h1>
<p>
This document contains a specification of the API provided by the
@@ -276,6 +276,7 @@
<p><a href="#domain_execution">Execution</a></p><ul><li><a href="#request_execution.createContext">execution.createContext</a></li>
<li><a href="#request_execution.deleteContext">execution.deleteContext</a></li>
+<li><a href="#request_execution.getSuggestions">execution.getSuggestions</a></li>
<li><a href="#request_execution.mapUri">execution.mapUri</a></li>
<li><a class="deprecated" href="#request_execution.setSubscriptions">execution.setSubscriptions</a></li>
</ul>
@@ -2263,6 +2264,7 @@
+
<h3>Requests</h3><dl><dt class="request"><a name="request_execution.createContext">execution.createContext</a></dt><dd><div class="box"><pre>request: {
"id": String
"method": "execution.createContext"
@@ -2317,6 +2319,110 @@
<p>
The identifier of the execution context that is to be deleted.
</p>
+ </dd></dl></dd><dt class="request"><a name="request_execution.getSuggestions">execution.getSuggestions</a></dt><dd><div class="box"><pre>request: {
+ "id": String
+ "method": "execution.getSuggestions"
+ "params": {
+ "<b>code</b>": String
+ "<b>offset</b>": int
+ "<b>contextFile</b>": <a href="#type_FilePath">FilePath</a>
+ "<b>contextOffset</b>": int
+ "<b>variables</b>": List<<a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a>>
+ "<b>expressions</b>": <span style="color:#999999">optional</span> List<<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>>
+ }
+}</pre><br><pre>response: {
+ "id": String
+ "error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
+ "result": {
+ "<b>suggestions</b>": <span style="color:#999999">optional</span> List<<a href="#type_CompletionSuggestion">CompletionSuggestion</a>>
+ "<b>expressions</b>": <span style="color:#999999">optional</span> List<<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>>
+ }
+}</pre></div>
+ <p>
+ Request completion suggestions for the given runtime context.
+ </p>
+ <p>
+ It might take one or two requests of this type to get completion
+ suggestions. The first request should have only "code", "offset",
+ and "variables", but not "expressions". If there are sub-expressions that
+ can have different runtime types, and are considered to be safe to
+ evaluate at runtime (e.g. getters), so using their actual runtime types
+ can improve completion results, the server will not include the
+ "suggestions" field in the response, and instead will return the
+ "expressions" field. The client will use debug API to get current runtime
+ types for these sub-expressions and send another request, this time with
+ "expressions". If there are no interesting sub-expressions to get
+ runtime types for, or when the "expressions" field is provided by the
+ client, the server will return "suggestions" in the response.
+ </p>
+
+
+ <h4>parameters:</h4><dl><dt class="field"><b>code: String</b></dt><dd>
+
+ <p>
+ The code to get suggestions in.
+ </p>
+ </dd><dt class="field"><b>offset: int</b></dt><dd>
+
+ <p>
+ The offset within the code to get suggestions at.
+ </p>
+ </dd><dt class="field"><b>contextFile: <a href="#type_FilePath">FilePath</a></b></dt><dd>
+
+ <p>
+ The path of the context file, e.g. the file of the current debugger
+ frame. The combination of the context file and context offset can
+ be used to ensure that all variables of the context are available
+ for completion (with their static types).
+ </p>
+ </dd><dt class="field"><b>contextOffset: int</b></dt><dd>
+
+ <p>
+ The offset in the context file, e.g. the line offset in the current
+ debugger frame.
+ </p>
+ </dd><dt class="field"><b>variables: List<<a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a>></b></dt><dd>
+
+ <p>
+ The runtime context variables that are potentially referenced in the
+ code.
+ </p>
+ </dd><dt class="field"><b>expressions: List<<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ The list of sub-expressions in the code for which the client wants
+ to provide runtime types. It does not have to be the full list of
+ expressions requested by the server, for missing expressions their
+ static types will be used.
+ </p>
+ <p>
+ When this field is omitted, the server will return completion
+ suggestions only when there are no interesting sub-expressions in the
+ given code. The client may provide an empty list, in this case the
+ server will return completion suggestions.
+ </p>
+ </dd></dl><h4>returns:</h4><dl><dt class="field"><b>suggestions: List<<a href="#type_CompletionSuggestion">CompletionSuggestion</a>><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ The completion suggestions. In contrast to usual completion request,
+ suggestions for private elements also will be provided.
+ </p>
+ <p>
+ If there are sub-expressions that can have different runtime types,
+ and are considered to be safe to evaluate at runtime (e.g. getters),
+ so using their actual runtime types can improve completion results,
+ the server omits this field in the response, and instead will return
+ the "expressions" field.
+ </p>
+ </dd><dt class="field"><b>expressions: List<<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ The list of sub-expressions in the code for which the server would
+ like to know runtime types to provide better completion suggestions.
+ </p>
+ <p>
+ This field is omitted the field "suggestions" is returned.
+ </p>
</dd></dl></dd><dt class="request"><a name="request_execution.mapUri">execution.mapUri</a></dt><dd><div class="box"><pre>request: {
"<b>id</b>": String
"method": "execution.mapUri"
@@ -2543,6 +2649,10 @@
+
+
+
+
<dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
<p>
A directive to begin overlaying the contents of a file. The supplied
@@ -3199,7 +3309,7 @@
An enumeration of the kinds of folding regions.
</p>
- <dl><dt class="value">COMMENT</dt><dt class="value">CLASS_MEMBER</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">TOP_LEVEL_DECLARATION</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
+ <dl><dt class="value">ANNOTATIONS</dt><dt class="value">CLASS_BODY</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">FILE_HEADER</dt><dt class="value">FUNCTION_BODY</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
<p>
A description of a region that can be folded.
</p>
@@ -4250,6 +4360,103 @@
API reaches version 1.0.
</p>
+ </dd></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionExpression">RuntimeCompletionExpression: object</a></dt><dd>
+ <p>
+ An expression for which we want to know its runtime type.
+ In expressions like `a.b.c.where((e) => e.^)` we want to know the
+ runtime type of `a.b.c` to enforce it statically at the time when we
+ compute completion suggestions, and get better type for `e`.
+ </p>
+
+ <dl><dt class="field"><b>offset: int</b></dt><dd>
+
+ <p>
+ The offset of the expression in the code for completion.
+ </p>
+ </dd><dt class="field"><b>length: int</b></dt><dd>
+
+ <p>
+ The length of the expression in the code for completion.
+ </p>
+ </dd><dt class="field"><b>type: <a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ When the expression is sent from the server to the client, the
+ type is omitted. The client should fill the type when it sends the
+ request to the server again.
+ </p>
+ </dd></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType: object</a></dt><dd>
+ <p>
+ A type at runtime.
+ </p>
+
+ <dl><dt class="field"><b>libraryPath: <a href="#type_FilePath">FilePath</a><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ The path of the library that has this type.
+ Omitted if the type is not declared in any library, e.g. "dynamic",
+ or "void".
+ </p>
+ </dd><dt class="field"><b>kind: <a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></b></dt><dd>
+
+ <p>
+ The kind of the type.
+ </p>
+ </dd><dt class="field"><b>name: String<span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ The name of the type. Omitted if the type does not have a name, e.g.
+ an inline function type.
+ </p>
+ </dd><dt class="field"><b>typeArguments: List<<a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a>><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ The type arguments of the type.
+ Omitted if the type does not have type parameters.
+ </p>
+ </dd><dt class="field"><b>returnType: <a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ If the type is a function type, the return type of the function.
+ Omitted if the type is not a function type.
+ </p>
+ </dd><dt class="field"><b>parameterTypes: List<<a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a>><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ If the type is a function type, the types of the function parameters
+ of all kinds - required, optional positional, and optional named.
+ Omitted if the type is not a function type.
+ </p>
+ </dd><dt class="field"><b>parameterNames: List<String><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ If the type is a function type, the names of the function parameters
+ of all kinds - required, optional positional, and optional named.
+ The names of positional parameters are empty strings.
+ Omitted if the type is not a function type.
+ </p>
+ </dd></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind: String</a></dt><dd>
+ <p>
+ An enumeration of the kinds of runtime expression types.
+ </p>
+
+ <dl><dt class="value">DYNAMIC</dt><dt class="value">FUNCTION</dt><dt class="value">INTERFACE</dt></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionVariable">RuntimeCompletionVariable: object</a></dt><dd>
+ <p>
+ A variable in a runtime context.
+ </p>
+
+ <dl><dt class="field"><b>name: String</b></dt><dd>
+
+ <p>
+ The name of the variable.
+ The name "this" has a special meaning and is used as an implicit
+ target for runtime completion, and in explicit "this" references.
+ </p>
+ </dd><dt class="field"><b>type: <a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></b></dt><dd>
+
+ <p>
+ The type of the variable.
+ </p>
</dd></dl></dd><dt class="typeDefinition"><a name="type_SearchId">SearchId: String</a></dt><dd>
<p>
@@ -4832,7 +5039,7 @@
TODO: 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.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</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.closingLabels">closingLabels</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><li><a href="#request_diagnostic.getServerPort">getServerPort</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_ClosingLabel">ClosingLabel</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_ElementDeclaration">ElementDeclaration</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_ImportedElements">ImportedElements</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</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_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</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_EXTRACT_WIDGET">EXTRACT_WIDGET</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.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</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.closingLabels">closingLabels</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.getSuggestions">getSuggestions</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><li><a href="#request_diagnostic.getServerPort">getServerPort</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_ClosingLabel">ClosingLabel</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_ElementDeclaration">ElementDeclaration</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_ImportedElements">ImportedElements</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</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_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</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_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</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_EXTRACT_WIDGET">EXTRACT_WIDGET</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/protocol/protocol.dart b/pkg/analysis_server/lib/protocol/protocol.dart
index 9e77ed7..730887e 100644
--- a/pkg/analysis_server/lib/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/protocol/protocol.dart
@@ -14,26 +14,6 @@
export 'package:analyzer_plugin/protocol/protocol.dart' show Enum;
/**
- * A [RequestHandler] that supports [startup] and [shutdown] methods.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DomainHandler implements RequestHandler {
- /**
- * Perform any operations associated with the shutdown of the domain. It is
- * not guaranteed that this method will be called. If it is, it will be
- * called after the last [Request] has been made.
- */
- void shutdown() {}
-
- /**
- * Perform any operations associated with the startup of the domain. This
- * will be called before the first [Request].
- */
- void startup() {}
-}
-
-/**
* A notification that can be sent from the server about an event that occurred.
*
* Clients may not extend, implement or mix-in this class.
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 148fc49..fcd4300 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -196,6 +196,13 @@
const String EXECUTION_REQUEST_CREATE_CONTEXT_CONTEXT_ROOT = 'contextRoot';
const String EXECUTION_REQUEST_DELETE_CONTEXT = 'execution.deleteContext';
const String EXECUTION_REQUEST_DELETE_CONTEXT_ID = 'id';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS = 'execution.getSuggestions';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_CODE = 'code';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_CONTEXT_FILE = 'contextFile';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_CONTEXT_OFFSET = 'contextOffset';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_EXPRESSIONS = 'expressions';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_VARIABLES = 'variables';
const String EXECUTION_REQUEST_MAP_URI = 'execution.mapUri';
const String EXECUTION_REQUEST_MAP_URI_FILE = 'file';
const String EXECUTION_REQUEST_MAP_URI_ID = 'id';
@@ -204,6 +211,8 @@
const String EXECUTION_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS =
'subscriptions';
const String EXECUTION_RESPONSE_CREATE_CONTEXT_ID = 'id';
+const String EXECUTION_RESPONSE_GET_SUGGESTIONS_EXPRESSIONS = 'expressions';
+const String EXECUTION_RESPONSE_GET_SUGGESTIONS_SUGGESTIONS = 'suggestions';
const String EXECUTION_RESPONSE_MAP_URI_FILE = 'file';
const String EXECUTION_RESPONSE_MAP_URI_URI = 'uri';
const String FLUTTER_NOTIFICATION_OUTLINE = 'flutter.outline';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index cd60f28..7175c14 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -9504,6 +9504,422 @@
}
/**
+ * execution.getSuggestions params
+ *
+ * {
+ * "code": String
+ * "offset": int
+ * "contextFile": FilePath
+ * "contextOffset": int
+ * "variables": List<RuntimeCompletionVariable>
+ * "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ExecutionGetSuggestionsParams implements RequestParams {
+ String _code;
+
+ int _offset;
+
+ String _contextFile;
+
+ int _contextOffset;
+
+ List<RuntimeCompletionVariable> _variables;
+
+ List<RuntimeCompletionExpression> _expressions;
+
+ /**
+ * The code to get suggestions in.
+ */
+ String get code => _code;
+
+ /**
+ * The code to get suggestions in.
+ */
+ void set code(String value) {
+ assert(value != null);
+ this._code = value;
+ }
+
+ /**
+ * The offset within the code to get suggestions at.
+ */
+ int get offset => _offset;
+
+ /**
+ * The offset within the code to get suggestions at.
+ */
+ void set offset(int value) {
+ assert(value != null);
+ this._offset = value;
+ }
+
+ /**
+ * The path of the context file, e.g. the file of the current debugger frame.
+ * The combination of the context file and context offset can be used to
+ * ensure that all variables of the context are available for completion
+ * (with their static types).
+ */
+ String get contextFile => _contextFile;
+
+ /**
+ * The path of the context file, e.g. the file of the current debugger frame.
+ * The combination of the context file and context offset can be used to
+ * ensure that all variables of the context are available for completion
+ * (with their static types).
+ */
+ void set contextFile(String value) {
+ assert(value != null);
+ this._contextFile = value;
+ }
+
+ /**
+ * The offset in the context file, e.g. the line offset in the current
+ * debugger frame.
+ */
+ int get contextOffset => _contextOffset;
+
+ /**
+ * The offset in the context file, e.g. the line offset in the current
+ * debugger frame.
+ */
+ void set contextOffset(int value) {
+ assert(value != null);
+ this._contextOffset = value;
+ }
+
+ /**
+ * The runtime context variables that are potentially referenced in the code.
+ */
+ List<RuntimeCompletionVariable> get variables => _variables;
+
+ /**
+ * The runtime context variables that are potentially referenced in the code.
+ */
+ void set variables(List<RuntimeCompletionVariable> value) {
+ assert(value != null);
+ this._variables = value;
+ }
+
+ /**
+ * The list of sub-expressions in the code for which the client wants to
+ * provide runtime types. It does not have to be the full list of expressions
+ * requested by the server, for missing expressions their static types will
+ * be used.
+ *
+ * When this field is omitted, the server will return completion suggestions
+ * only when there are no interesting sub-expressions in the given code. The
+ * client may provide an empty list, in this case the server will return
+ * completion suggestions.
+ */
+ List<RuntimeCompletionExpression> get expressions => _expressions;
+
+ /**
+ * The list of sub-expressions in the code for which the client wants to
+ * provide runtime types. It does not have to be the full list of expressions
+ * requested by the server, for missing expressions their static types will
+ * be used.
+ *
+ * When this field is omitted, the server will return completion suggestions
+ * only when there are no interesting sub-expressions in the given code. The
+ * client may provide an empty list, in this case the server will return
+ * completion suggestions.
+ */
+ void set expressions(List<RuntimeCompletionExpression> value) {
+ this._expressions = value;
+ }
+
+ ExecutionGetSuggestionsParams(String code, int offset, String contextFile,
+ int contextOffset, List<RuntimeCompletionVariable> variables,
+ {List<RuntimeCompletionExpression> expressions}) {
+ this.code = code;
+ this.offset = offset;
+ this.contextFile = contextFile;
+ this.contextOffset = contextOffset;
+ this.variables = variables;
+ this.expressions = expressions;
+ }
+
+ factory ExecutionGetSuggestionsParams.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ String code;
+ if (json.containsKey("code")) {
+ code = jsonDecoder.decodeString(jsonPath + ".code", json["code"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "code");
+ }
+ int offset;
+ if (json.containsKey("offset")) {
+ offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "offset");
+ }
+ String contextFile;
+ if (json.containsKey("contextFile")) {
+ contextFile = jsonDecoder.decodeString(
+ jsonPath + ".contextFile", json["contextFile"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "contextFile");
+ }
+ int contextOffset;
+ if (json.containsKey("contextOffset")) {
+ contextOffset = jsonDecoder.decodeInt(
+ jsonPath + ".contextOffset", json["contextOffset"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "contextOffset");
+ }
+ List<RuntimeCompletionVariable> variables;
+ if (json.containsKey("variables")) {
+ variables = jsonDecoder.decodeList(
+ jsonPath + ".variables",
+ json["variables"],
+ (String jsonPath, Object json) =>
+ new RuntimeCompletionVariable.fromJson(
+ jsonDecoder, jsonPath, json));
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "variables");
+ }
+ List<RuntimeCompletionExpression> expressions;
+ if (json.containsKey("expressions")) {
+ expressions = jsonDecoder.decodeList(
+ jsonPath + ".expressions",
+ json["expressions"],
+ (String jsonPath, Object json) =>
+ new RuntimeCompletionExpression.fromJson(
+ jsonDecoder, jsonPath, json));
+ }
+ return new ExecutionGetSuggestionsParams(
+ code, offset, contextFile, contextOffset, variables,
+ expressions: expressions);
+ } else {
+ throw jsonDecoder.mismatch(
+ jsonPath, "execution.getSuggestions params", json);
+ }
+ }
+
+ factory ExecutionGetSuggestionsParams.fromRequest(Request request) {
+ return new ExecutionGetSuggestionsParams.fromJson(
+ new RequestDecoder(request), "params", request.params);
+ }
+
+ @override
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ result["code"] = code;
+ result["offset"] = offset;
+ result["contextFile"] = contextFile;
+ result["contextOffset"] = contextOffset;
+ result["variables"] = variables
+ .map((RuntimeCompletionVariable value) => value.toJson())
+ .toList();
+ if (expressions != null) {
+ result["expressions"] = expressions
+ .map((RuntimeCompletionExpression value) => value.toJson())
+ .toList();
+ }
+ return result;
+ }
+
+ @override
+ Request toRequest(String id) {
+ return new Request(id, "execution.getSuggestions", toJson());
+ }
+
+ @override
+ String toString() => json.encode(toJson());
+
+ @override
+ bool operator ==(other) {
+ if (other is ExecutionGetSuggestionsParams) {
+ return code == other.code &&
+ offset == other.offset &&
+ contextFile == other.contextFile &&
+ contextOffset == other.contextOffset &&
+ listEqual(
+ variables,
+ other.variables,
+ (RuntimeCompletionVariable a, RuntimeCompletionVariable b) =>
+ a == b) &&
+ listEqual(
+ expressions,
+ other.expressions,
+ (RuntimeCompletionExpression a, RuntimeCompletionExpression b) =>
+ a == b);
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, code.hashCode);
+ hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+ hash = JenkinsSmiHash.combine(hash, contextFile.hashCode);
+ hash = JenkinsSmiHash.combine(hash, contextOffset.hashCode);
+ hash = JenkinsSmiHash.combine(hash, variables.hashCode);
+ hash = JenkinsSmiHash.combine(hash, expressions.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+}
+
+/**
+ * execution.getSuggestions result
+ *
+ * {
+ * "suggestions": optional List<CompletionSuggestion>
+ * "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ExecutionGetSuggestionsResult implements ResponseResult {
+ List<CompletionSuggestion> _suggestions;
+
+ List<RuntimeCompletionExpression> _expressions;
+
+ /**
+ * The completion suggestions. In contrast to usual completion request,
+ * suggestions for private elements also will be provided.
+ *
+ * If there are sub-expressions that can have different runtime types, and
+ * are considered to be safe to evaluate at runtime (e.g. getters), so using
+ * their actual runtime types can improve completion results, the server
+ * omits this field in the response, and instead will return the
+ * "expressions" field.
+ */
+ List<CompletionSuggestion> get suggestions => _suggestions;
+
+ /**
+ * The completion suggestions. In contrast to usual completion request,
+ * suggestions for private elements also will be provided.
+ *
+ * If there are sub-expressions that can have different runtime types, and
+ * are considered to be safe to evaluate at runtime (e.g. getters), so using
+ * their actual runtime types can improve completion results, the server
+ * omits this field in the response, and instead will return the
+ * "expressions" field.
+ */
+ void set suggestions(List<CompletionSuggestion> value) {
+ this._suggestions = value;
+ }
+
+ /**
+ * The list of sub-expressions in the code for which the server would like to
+ * know runtime types to provide better completion suggestions.
+ *
+ * This field is omitted the field "suggestions" is returned.
+ */
+ List<RuntimeCompletionExpression> get expressions => _expressions;
+
+ /**
+ * The list of sub-expressions in the code for which the server would like to
+ * know runtime types to provide better completion suggestions.
+ *
+ * This field is omitted the field "suggestions" is returned.
+ */
+ void set expressions(List<RuntimeCompletionExpression> value) {
+ this._expressions = value;
+ }
+
+ ExecutionGetSuggestionsResult(
+ {List<CompletionSuggestion> suggestions,
+ List<RuntimeCompletionExpression> expressions}) {
+ this.suggestions = suggestions;
+ this.expressions = expressions;
+ }
+
+ factory ExecutionGetSuggestionsResult.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ List<CompletionSuggestion> suggestions;
+ if (json.containsKey("suggestions")) {
+ suggestions = jsonDecoder.decodeList(
+ jsonPath + ".suggestions",
+ json["suggestions"],
+ (String jsonPath, Object json) =>
+ new CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json));
+ }
+ List<RuntimeCompletionExpression> expressions;
+ if (json.containsKey("expressions")) {
+ expressions = jsonDecoder.decodeList(
+ jsonPath + ".expressions",
+ json["expressions"],
+ (String jsonPath, Object json) =>
+ new RuntimeCompletionExpression.fromJson(
+ jsonDecoder, jsonPath, json));
+ }
+ return new ExecutionGetSuggestionsResult(
+ suggestions: suggestions, expressions: expressions);
+ } else {
+ throw jsonDecoder.mismatch(
+ jsonPath, "execution.getSuggestions result", json);
+ }
+ }
+
+ factory ExecutionGetSuggestionsResult.fromResponse(Response response) {
+ return new ExecutionGetSuggestionsResult.fromJson(
+ new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+ "result",
+ response.result);
+ }
+
+ @override
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ if (suggestions != null) {
+ result["suggestions"] = suggestions
+ .map((CompletionSuggestion value) => value.toJson())
+ .toList();
+ }
+ if (expressions != null) {
+ result["expressions"] = expressions
+ .map((RuntimeCompletionExpression value) => value.toJson())
+ .toList();
+ }
+ return result;
+ }
+
+ @override
+ Response toResponse(String id) {
+ return new Response(id, result: toJson());
+ }
+
+ @override
+ String toString() => json.encode(toJson());
+
+ @override
+ bool operator ==(other) {
+ if (other is ExecutionGetSuggestionsResult) {
+ return listEqual(suggestions, other.suggestions,
+ (CompletionSuggestion a, CompletionSuggestion b) => a == b) &&
+ listEqual(
+ expressions,
+ other.expressions,
+ (RuntimeCompletionExpression a, RuntimeCompletionExpression b) =>
+ a == b);
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
+ hash = JenkinsSmiHash.combine(hash, expressions.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+}
+
+/**
* execution.launchData params
*
* {
@@ -15227,6 +15643,585 @@
}
/**
+ * RuntimeCompletionExpression
+ *
+ * {
+ * "offset": int
+ * "length": int
+ * "type": optional RuntimeCompletionExpressionType
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionExpression implements HasToJson {
+ int _offset;
+
+ int _length;
+
+ RuntimeCompletionExpressionType _type;
+
+ /**
+ * The offset of the expression in the code for completion.
+ */
+ int get offset => _offset;
+
+ /**
+ * The offset of the expression in the code for completion.
+ */
+ void set offset(int value) {
+ assert(value != null);
+ this._offset = value;
+ }
+
+ /**
+ * The length of the expression in the code for completion.
+ */
+ int get length => _length;
+
+ /**
+ * The length of the expression in the code for completion.
+ */
+ void set length(int value) {
+ assert(value != null);
+ this._length = value;
+ }
+
+ /**
+ * When the expression is sent from the server to the client, the type is
+ * omitted. The client should fill the type when it sends the request to the
+ * server again.
+ */
+ RuntimeCompletionExpressionType get type => _type;
+
+ /**
+ * When the expression is sent from the server to the client, the type is
+ * omitted. The client should fill the type when it sends the request to the
+ * server again.
+ */
+ void set type(RuntimeCompletionExpressionType value) {
+ this._type = value;
+ }
+
+ RuntimeCompletionExpression(int offset, int length,
+ {RuntimeCompletionExpressionType type}) {
+ this.offset = offset;
+ this.length = length;
+ this.type = type;
+ }
+
+ factory RuntimeCompletionExpression.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ int offset;
+ if (json.containsKey("offset")) {
+ offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "offset");
+ }
+ int length;
+ if (json.containsKey("length")) {
+ length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "length");
+ }
+ RuntimeCompletionExpressionType type;
+ if (json.containsKey("type")) {
+ type = new RuntimeCompletionExpressionType.fromJson(
+ jsonDecoder, jsonPath + ".type", json["type"]);
+ }
+ return new RuntimeCompletionExpression(offset, length, type: type);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "RuntimeCompletionExpression", json);
+ }
+ }
+
+ @override
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ result["offset"] = offset;
+ result["length"] = length;
+ if (type != null) {
+ result["type"] = type.toJson();
+ }
+ return result;
+ }
+
+ @override
+ String toString() => json.encode(toJson());
+
+ @override
+ bool operator ==(other) {
+ if (other is RuntimeCompletionExpression) {
+ return offset == other.offset &&
+ length == other.length &&
+ type == other.type;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+ hash = JenkinsSmiHash.combine(hash, length.hashCode);
+ hash = JenkinsSmiHash.combine(hash, type.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+}
+
+/**
+ * RuntimeCompletionExpressionType
+ *
+ * {
+ * "libraryPath": optional FilePath
+ * "kind": RuntimeCompletionExpressionTypeKind
+ * "name": optional String
+ * "typeArguments": optional List<RuntimeCompletionExpressionType>
+ * "returnType": optional RuntimeCompletionExpressionType
+ * "parameterTypes": optional List<RuntimeCompletionExpressionType>
+ * "parameterNames": optional List<String>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionExpressionType implements HasToJson {
+ String _libraryPath;
+
+ RuntimeCompletionExpressionTypeKind _kind;
+
+ String _name;
+
+ List<RuntimeCompletionExpressionType> _typeArguments;
+
+ RuntimeCompletionExpressionType _returnType;
+
+ List<RuntimeCompletionExpressionType> _parameterTypes;
+
+ List<String> _parameterNames;
+
+ /**
+ * The path of the library that has this type. Omitted if the type is not
+ * declared in any library, e.g. "dynamic", or "void".
+ */
+ String get libraryPath => _libraryPath;
+
+ /**
+ * The path of the library that has this type. Omitted if the type is not
+ * declared in any library, e.g. "dynamic", or "void".
+ */
+ void set libraryPath(String value) {
+ this._libraryPath = value;
+ }
+
+ /**
+ * The kind of the type.
+ */
+ RuntimeCompletionExpressionTypeKind get kind => _kind;
+
+ /**
+ * The kind of the type.
+ */
+ void set kind(RuntimeCompletionExpressionTypeKind value) {
+ assert(value != null);
+ this._kind = value;
+ }
+
+ /**
+ * The name of the type. Omitted if the type does not have a name, e.g. an
+ * inline function type.
+ */
+ String get name => _name;
+
+ /**
+ * The name of the type. Omitted if the type does not have a name, e.g. an
+ * inline function type.
+ */
+ void set name(String value) {
+ this._name = value;
+ }
+
+ /**
+ * The type arguments of the type. Omitted if the type does not have type
+ * parameters.
+ */
+ List<RuntimeCompletionExpressionType> get typeArguments => _typeArguments;
+
+ /**
+ * The type arguments of the type. Omitted if the type does not have type
+ * parameters.
+ */
+ void set typeArguments(List<RuntimeCompletionExpressionType> value) {
+ this._typeArguments = value;
+ }
+
+ /**
+ * If the type is a function type, the return type of the function. Omitted
+ * if the type is not a function type.
+ */
+ RuntimeCompletionExpressionType get returnType => _returnType;
+
+ /**
+ * If the type is a function type, the return type of the function. Omitted
+ * if the type is not a function type.
+ */
+ void set returnType(RuntimeCompletionExpressionType value) {
+ this._returnType = value;
+ }
+
+ /**
+ * If the type is a function type, the types of the function parameters of
+ * all kinds - required, optional positional, and optional named. Omitted if
+ * the type is not a function type.
+ */
+ List<RuntimeCompletionExpressionType> get parameterTypes => _parameterTypes;
+
+ /**
+ * If the type is a function type, the types of the function parameters of
+ * all kinds - required, optional positional, and optional named. Omitted if
+ * the type is not a function type.
+ */
+ void set parameterTypes(List<RuntimeCompletionExpressionType> value) {
+ this._parameterTypes = value;
+ }
+
+ /**
+ * If the type is a function type, the names of the function parameters of
+ * all kinds - required, optional positional, and optional named. The names
+ * of positional parameters are empty strings. Omitted if the type is not a
+ * function type.
+ */
+ List<String> get parameterNames => _parameterNames;
+
+ /**
+ * If the type is a function type, the names of the function parameters of
+ * all kinds - required, optional positional, and optional named. The names
+ * of positional parameters are empty strings. Omitted if the type is not a
+ * function type.
+ */
+ void set parameterNames(List<String> value) {
+ this._parameterNames = value;
+ }
+
+ RuntimeCompletionExpressionType(RuntimeCompletionExpressionTypeKind kind,
+ {String libraryPath,
+ String name,
+ List<RuntimeCompletionExpressionType> typeArguments,
+ RuntimeCompletionExpressionType returnType,
+ List<RuntimeCompletionExpressionType> parameterTypes,
+ List<String> parameterNames}) {
+ this.libraryPath = libraryPath;
+ this.kind = kind;
+ this.name = name;
+ this.typeArguments = typeArguments;
+ this.returnType = returnType;
+ this.parameterTypes = parameterTypes;
+ this.parameterNames = parameterNames;
+ }
+
+ factory RuntimeCompletionExpressionType.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ String libraryPath;
+ if (json.containsKey("libraryPath")) {
+ libraryPath = jsonDecoder.decodeString(
+ jsonPath + ".libraryPath", json["libraryPath"]);
+ }
+ RuntimeCompletionExpressionTypeKind kind;
+ if (json.containsKey("kind")) {
+ kind = new RuntimeCompletionExpressionTypeKind.fromJson(
+ jsonDecoder, jsonPath + ".kind", json["kind"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "kind");
+ }
+ String name;
+ if (json.containsKey("name")) {
+ name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]);
+ }
+ List<RuntimeCompletionExpressionType> typeArguments;
+ if (json.containsKey("typeArguments")) {
+ typeArguments = jsonDecoder.decodeList(
+ jsonPath + ".typeArguments",
+ json["typeArguments"],
+ (String jsonPath, Object json) =>
+ new RuntimeCompletionExpressionType.fromJson(
+ jsonDecoder, jsonPath, json));
+ }
+ RuntimeCompletionExpressionType returnType;
+ if (json.containsKey("returnType")) {
+ returnType = new RuntimeCompletionExpressionType.fromJson(
+ jsonDecoder, jsonPath + ".returnType", json["returnType"]);
+ }
+ List<RuntimeCompletionExpressionType> parameterTypes;
+ if (json.containsKey("parameterTypes")) {
+ parameterTypes = jsonDecoder.decodeList(
+ jsonPath + ".parameterTypes",
+ json["parameterTypes"],
+ (String jsonPath, Object json) =>
+ new RuntimeCompletionExpressionType.fromJson(
+ jsonDecoder, jsonPath, json));
+ }
+ List<String> parameterNames;
+ if (json.containsKey("parameterNames")) {
+ parameterNames = jsonDecoder.decodeList(jsonPath + ".parameterNames",
+ json["parameterNames"], jsonDecoder.decodeString);
+ }
+ return new RuntimeCompletionExpressionType(kind,
+ libraryPath: libraryPath,
+ name: name,
+ typeArguments: typeArguments,
+ returnType: returnType,
+ parameterTypes: parameterTypes,
+ parameterNames: parameterNames);
+ } else {
+ throw jsonDecoder.mismatch(
+ jsonPath, "RuntimeCompletionExpressionType", json);
+ }
+ }
+
+ @override
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ if (libraryPath != null) {
+ result["libraryPath"] = libraryPath;
+ }
+ result["kind"] = kind.toJson();
+ if (name != null) {
+ result["name"] = name;
+ }
+ if (typeArguments != null) {
+ result["typeArguments"] = typeArguments
+ .map((RuntimeCompletionExpressionType value) => value.toJson())
+ .toList();
+ }
+ if (returnType != null) {
+ result["returnType"] = returnType.toJson();
+ }
+ if (parameterTypes != null) {
+ result["parameterTypes"] = parameterTypes
+ .map((RuntimeCompletionExpressionType value) => value.toJson())
+ .toList();
+ }
+ if (parameterNames != null) {
+ result["parameterNames"] = parameterNames;
+ }
+ return result;
+ }
+
+ @override
+ String toString() => json.encode(toJson());
+
+ @override
+ bool operator ==(other) {
+ if (other is RuntimeCompletionExpressionType) {
+ return libraryPath == other.libraryPath &&
+ kind == other.kind &&
+ name == other.name &&
+ listEqual(
+ typeArguments,
+ other.typeArguments,
+ (RuntimeCompletionExpressionType a,
+ RuntimeCompletionExpressionType b) =>
+ a == b) &&
+ returnType == other.returnType &&
+ listEqual(
+ parameterTypes,
+ other.parameterTypes,
+ (RuntimeCompletionExpressionType a,
+ RuntimeCompletionExpressionType b) =>
+ a == b) &&
+ listEqual(parameterNames, other.parameterNames,
+ (String a, String b) => a == b);
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, libraryPath.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, name.hashCode);
+ hash = JenkinsSmiHash.combine(hash, typeArguments.hashCode);
+ hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
+ hash = JenkinsSmiHash.combine(hash, parameterTypes.hashCode);
+ hash = JenkinsSmiHash.combine(hash, parameterNames.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+}
+
+/**
+ * RuntimeCompletionExpressionTypeKind
+ *
+ * enum {
+ * DYNAMIC
+ * FUNCTION
+ * INTERFACE
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionExpressionTypeKind implements Enum {
+ static const RuntimeCompletionExpressionTypeKind DYNAMIC =
+ const RuntimeCompletionExpressionTypeKind._("DYNAMIC");
+
+ static const RuntimeCompletionExpressionTypeKind FUNCTION =
+ const RuntimeCompletionExpressionTypeKind._("FUNCTION");
+
+ static const RuntimeCompletionExpressionTypeKind INTERFACE =
+ const RuntimeCompletionExpressionTypeKind._("INTERFACE");
+
+ /**
+ * A list containing all of the enum values that are defined.
+ */
+ static const List<RuntimeCompletionExpressionTypeKind> VALUES =
+ const <RuntimeCompletionExpressionTypeKind>[DYNAMIC, FUNCTION, INTERFACE];
+
+ @override
+ final String name;
+
+ const RuntimeCompletionExpressionTypeKind._(this.name);
+
+ factory RuntimeCompletionExpressionTypeKind(String name) {
+ switch (name) {
+ case "DYNAMIC":
+ return DYNAMIC;
+ case "FUNCTION":
+ return FUNCTION;
+ case "INTERFACE":
+ return INTERFACE;
+ }
+ throw new Exception('Illegal enum value: $name');
+ }
+
+ factory RuntimeCompletionExpressionTypeKind.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json is String) {
+ try {
+ return new RuntimeCompletionExpressionTypeKind(json);
+ } catch (_) {
+ // Fall through
+ }
+ }
+ throw jsonDecoder.mismatch(
+ jsonPath, "RuntimeCompletionExpressionTypeKind", json);
+ }
+
+ @override
+ String toString() => "RuntimeCompletionExpressionTypeKind.$name";
+
+ String toJson() => name;
+}
+
+/**
+ * RuntimeCompletionVariable
+ *
+ * {
+ * "name": String
+ * "type": RuntimeCompletionExpressionType
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionVariable implements HasToJson {
+ String _name;
+
+ RuntimeCompletionExpressionType _type;
+
+ /**
+ * The name of the variable. The name "this" has a special meaning and is
+ * used as an implicit target for runtime completion, and in explicit "this"
+ * references.
+ */
+ String get name => _name;
+
+ /**
+ * The name of the variable. The name "this" has a special meaning and is
+ * used as an implicit target for runtime completion, and in explicit "this"
+ * references.
+ */
+ void set name(String value) {
+ assert(value != null);
+ this._name = value;
+ }
+
+ /**
+ * The type of the variable.
+ */
+ RuntimeCompletionExpressionType get type => _type;
+
+ /**
+ * The type of the variable.
+ */
+ void set type(RuntimeCompletionExpressionType value) {
+ assert(value != null);
+ this._type = value;
+ }
+
+ RuntimeCompletionVariable(String name, RuntimeCompletionExpressionType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ factory RuntimeCompletionVariable.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ String name;
+ if (json.containsKey("name")) {
+ name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "name");
+ }
+ RuntimeCompletionExpressionType type;
+ if (json.containsKey("type")) {
+ type = new RuntimeCompletionExpressionType.fromJson(
+ jsonDecoder, jsonPath + ".type", json["type"]);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "type");
+ }
+ return new RuntimeCompletionVariable(name, type);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "RuntimeCompletionVariable", json);
+ }
+ }
+
+ @override
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ result["name"] = name;
+ result["type"] = type.toJson();
+ return result;
+ }
+
+ @override
+ String toString() => json.encode(toJson());
+
+ @override
+ bool operator ==(other) {
+ if (other is RuntimeCompletionVariable) {
+ return name == other.name && type == other.type;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, name.hashCode);
+ hash = JenkinsSmiHash.combine(hash, type.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+}
+
+/**
* search.findElementReferences params
*
* {
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 110ad96..92eb394 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -108,7 +108,7 @@
* The version of the analysis server. The value should be replaced
* automatically during the build.
*/
- static final String VERSION = '1.20.2';
+ static final String VERSION = '1.20.3';
/**
* The options of this server instance.
@@ -382,7 +382,7 @@
sink = io.stdout;
} else if (name.startsWith('file:')) {
String path = name.substring('file:'.length);
- sink = new io.File(path).openWrite(mode: io.FileMode.APPEND);
+ sink = new io.File(path).openWrite(mode: io.FileMode.append);
}
}
_analysisPerformanceLogger = new PerformanceLog(sink);
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index bea49f1..ee82362 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -3,7 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -23,6 +25,7 @@
* Returns a list of folding regions, not `null`.
*/
List<FoldingRegion> compute() {
+ _addFileHeaderRegion();
_unit.accept(new _DartUnitFoldingComputerVisitor(this));
if (_firstDirective != null &&
@@ -36,6 +39,67 @@
return _foldingRegions;
}
+
+ void _addFileHeaderRegion() {
+ Token firstToken = _unit.beginToken;
+ while (firstToken?.type == TokenType.SCRIPT_TAG) {
+ firstToken = firstToken.next;
+ }
+
+ final Token firstComment = firstToken?.precedingComments;
+ if (firstComment == null ||
+ firstComment.type != TokenType.SINGLE_LINE_COMMENT) {
+ return;
+ }
+
+ // Walk through the comments looking for a blank line to signal the end of
+ // the file header.
+ Token lastComment = firstComment;
+ while (lastComment.next != null) {
+ lastComment = lastComment.next;
+
+ // If we ran out of tokens, use the original token as starting position.
+ final hasBlankLine =
+ _hasBlankLineBetween(lastComment, lastComment.next ?? firstToken);
+
+ // Also considerd non-single-line-comments as the end
+ final nextCommentIsDifferentType = lastComment.next != null &&
+ lastComment.next.type != TokenType.SINGLE_LINE_COMMENT;
+
+ if (hasBlankLine || nextCommentIsDifferentType) {
+ _addRegion(firstComment.end, lastComment.end, FoldingKind.FILE_HEADER);
+ break;
+ }
+ }
+ }
+
+ _addRegion(int startOffset, int endOffset, FoldingKind kind) {
+ final CharacterLocation start = _lineInfo.getLocation(startOffset);
+ final CharacterLocation end = _lineInfo.getLocation(endOffset);
+
+ if (start.lineNumber != end.lineNumber) {
+ _foldingRegions
+ .add(new FoldingRegion(kind, startOffset, endOffset - startOffset));
+ }
+ }
+
+ _addRegionForAnnotations(List<Annotation> annotations) {
+ if (annotations.isNotEmpty) {
+ _addRegion(annotations.first.name.end, annotations.last.end,
+ FoldingKind.ANNOTATIONS);
+ }
+ }
+
+ bool _hasBlankLineBetween(Token first, Token second) {
+ final CharacterLocation firstLoc = _lineInfo.getLocation(first.end);
+ final CharacterLocation secondLoc = _lineInfo.getLocation(second.offset);
+ return secondLoc.lineNumber - firstLoc.lineNumber > 1;
+ }
+
+ _recordDirective(Directive node) {
+ _firstDirective ??= node;
+ _lastDirective = node;
+ }
}
/**
@@ -47,88 +111,79 @@
@override
Object visitBlockFunctionBody(BlockFunctionBody node) {
- final FoldingKind kind = node.parent is ConstructorDeclaration ||
- node.parent is MethodDeclaration
- ? FoldingKind.CLASS_MEMBER
- : FoldingKind.TOP_LEVEL_DECLARATION;
- _addRegion(
- node.block.leftBracket.end, node.block.rightBracket.offset, kind);
+ _computer._addRegion(node.block.leftBracket.end,
+ node.block.rightBracket.offset, FoldingKind.FUNCTION_BODY);
return super.visitBlockFunctionBody(node);
}
@override
Object visitClassDeclaration(ClassDeclaration node) {
- _addRegion(node.leftBracket.end, node.rightBracket.offset,
- FoldingKind.TOP_LEVEL_DECLARATION);
+ _computer._addRegionForAnnotations(node.metadata);
+ _computer._addRegion(
+ node.leftBracket.end, node.rightBracket.offset, FoldingKind.CLASS_BODY);
return super.visitClassDeclaration(node);
}
@override
- Object visitAnnotation(Annotation node) {
- if (node.arguments != null &&
- node.arguments.leftParenthesis != null &&
- node.arguments.rightParenthesis != null) {
- _addRegion(
- node.arguments.leftParenthesis.end,
- node.arguments.rightParenthesis.offset,
- FoldingKind.TOP_LEVEL_DECLARATION);
- }
- return super.visitAnnotation(node);
- }
-
- @override
Object visitComment(Comment node) {
- final FoldingKind kind = node.isDocumentation
- ? FoldingKind.DOCUMENTATION_COMMENT
- : FoldingKind.COMMENT;
- _addRegion(node.offset, node.end, kind);
+ if (node.isDocumentation) {
+ _computer._addRegion(
+ node.offset, node.end, FoldingKind.DOCUMENTATION_COMMENT);
+ }
return super.visitComment(node);
}
@override
+ Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ _computer._addRegionForAnnotations(node.metadata);
+ return super.visitConstructorDeclaration(node);
+ }
+
+ @override
Object visitExportDirective(ExportDirective node) {
- _recordDirective(node);
+ _computer._recordDirective(node);
return super.visitExportDirective(node);
}
@override
+ Object visitFieldDeclaration(FieldDeclaration node) {
+ _computer._addRegionForAnnotations(node.metadata);
+ return super.visitFieldDeclaration(node);
+ }
+
+ @override
+ Object visitFunctionDeclaration(FunctionDeclaration node) {
+ _computer._addRegionForAnnotations(node.metadata);
+ return super.visitFunctionDeclaration(node);
+ }
+
+ @override
visitImportDirective(ImportDirective node) {
- _recordDirective(node);
+ _computer._recordDirective(node);
return super.visitImportDirective(node);
}
@override
Object visitLibraryDirective(LibraryDirective node) {
- _recordDirective(node);
+ _computer._recordDirective(node);
return super.visitLibraryDirective(node);
}
@override
+ Object visitMethodDeclaration(MethodDeclaration node) {
+ _computer._addRegionForAnnotations(node.metadata);
+ return super.visitMethodDeclaration(node);
+ }
+
+ @override
Object visitPartDirective(PartDirective node) {
- _recordDirective(node);
+ _computer._recordDirective(node);
return super.visitPartDirective(node);
}
@override
Object visitPartOfDirective(PartOfDirective node) {
- _recordDirective(node);
+ _computer._recordDirective(node);
return super.visitPartOfDirective(node);
}
-
- _addRegion(int startOffset, int endOffset, FoldingKind kind) {
- // TODO(dantup): This class is marked deprecated; find out what to change it to.
- final LineInfo_Location start =
- _computer._lineInfo.getLocation(startOffset);
- final LineInfo_Location end = _computer._lineInfo.getLocation(endOffset);
-
- if (start.lineNumber != end.lineNumber) {
- _computer._foldingRegions
- .add(new FoldingRegion(kind, startOffset, endOffset - startOffset));
- }
- }
-
- _recordDirective(Directive node) {
- _computer._firstDirective ??= node;
- _computer._lastDirective = node;
- }
}
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 5e9f2a6..97d4ec5 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -16,7 +16,6 @@
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
@@ -176,7 +175,6 @@
int offset = params.offset;
AnalysisResult result = await server.getAnalysisResult(filePath);
- Source source;
if (result == null || !result.exists) {
if (server.onNoAnalysisCompletion != null) {
@@ -185,7 +183,6 @@
request, this, params, performance, completionId);
return;
}
- source = server.resourceProvider.getFile(filePath).createSource();
} else {
if (offset < 0 || offset > result.content.length) {
server.sendResponse(new Response.invalidParameter(
@@ -195,13 +192,11 @@
' but found $offset'));
return;
}
- source =
- server.resourceProvider.getFile(result.path).createSource(result.uri);
- recordRequest(performance, source, result.content, offset);
+ recordRequest(performance, filePath, result.content, offset);
}
- CompletionRequestImpl completionRequest = new CompletionRequestImpl(
- result, server.resourceProvider, source, offset, performance);
+ CompletionRequestImpl completionRequest =
+ new CompletionRequestImpl(result, offset, performance);
String completionId = (_nextCompletionId++).toString();
@@ -233,10 +228,10 @@
* If tracking code completion performance over time, then
* record addition information about the request in the performance record.
*/
- void recordRequest(CompletionPerformance performance, Source source,
+ void recordRequest(CompletionPerformance performance, String path,
String content, int offset) {
- performance.source = source;
- if (performanceListMaxLength == 0 || source == null) {
+ performance.path = path;
+ if (performanceListMaxLength == 0) {
return;
}
performance.setContentsAndOffset(content, offset);
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index ea17e60..16c23fb 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
import 'dart:collection';
import 'dart:core';
@@ -10,6 +9,7 @@
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domains/execution/completion.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -32,13 +32,7 @@
/**
* A table mapping execution context id's to the root of the context.
*/
- Map<String, String> contextMap = new HashMap<String, String>();
-
- /**
- * The subscription to the 'onAnalysisComplete' events,
- * used to send notifications when
- */
- StreamSubscription onFileAnalyzed;
+ final Map<String, String> contextMap = new HashMap<String, String>();
/**
* Initialize a newly created handler to handle requests for the given [server].
@@ -65,6 +59,30 @@
return new ExecutionDeleteContextResult().toResponse(request.id);
}
+ /**
+ * Implement the 'execution.getSuggestions' request.
+ */
+ void getSuggestions(Request request) async {
+ var params = new ExecutionGetSuggestionsParams.fromRequest(request);
+ var computer = new RuntimeCompletionComputer(
+ server.resourceProvider,
+ server.fileContentOverlay,
+ server.getAnalysisDriver(params.contextFile),
+ params.code,
+ params.offset,
+ params.contextFile,
+ params.contextOffset,
+ params.variables,
+ params.expressions);
+ RuntimeCompletionResult completionResult = await computer.compute();
+
+ // Send the response.
+ var result = new ExecutionGetSuggestionsResult(
+ suggestions: completionResult.suggestions,
+ expressions: completionResult.expressions);
+ server.sendResponse(result.toResponse(request.id));
+ }
+
@override
Response handleRequest(Request request) {
try {
@@ -73,6 +91,9 @@
return createContext(request);
} else if (requestName == EXECUTION_REQUEST_DELETE_CONTEXT) {
return deleteContext(request);
+ } else if (requestName == EXECUTION_REQUEST_GET_SUGGESTIONS) {
+ getSuggestions(request);
+ return Response.DELAYED_RESPONSE;
} else if (requestName == EXECUTION_REQUEST_MAP_URI) {
return mapUri(request);
} else if (requestName == EXECUTION_REQUEST_SET_SUBSCRIPTIONS) {
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
new file mode 100644
index 0000000..9a4e0b3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/src/protocol_server.dart'
+ show
+ CompletionSuggestion,
+ RuntimeCompletionExpression,
+ RuntimeCompletionVariable,
+ SourceEdit;
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+
+class RuntimeCompletionComputer {
+ final ResourceProvider resourceProvider;
+ final FileContentOverlay fileContentOverlay;
+ final AnalysisDriver analysisDriver;
+
+ final String code;
+ final int offset;
+
+ final String contextFile;
+ final int contextOffset;
+
+ final List<RuntimeCompletionVariable> variables;
+ final List<RuntimeCompletionExpression> expressions;
+
+ RuntimeCompletionComputer(
+ this.resourceProvider,
+ this.fileContentOverlay,
+ this.analysisDriver,
+ this.code,
+ this.offset,
+ this.contextFile,
+ this.contextOffset,
+ this.variables,
+ this.expressions);
+
+ Future<RuntimeCompletionResult> compute() async {
+ var contextResult = await analysisDriver.getResult(contextFile);
+ var session = contextResult.session;
+
+ const codeMarker = '__code_\_';
+
+ // Insert the code being completed at the context offset.
+ var changeBuilder = new DartChangeBuilder(session);
+ int nextImportPrefixIndex = 0;
+ await changeBuilder.addFileEdit(contextFile, (builder) {
+ builder.addInsertion(contextOffset, (builder) {
+ builder.writeln('{');
+
+ // TODO(scheglov) Use variables.
+
+ builder.write(codeMarker);
+ builder.writeln(';');
+
+ builder.writeln('}');
+ });
+ }, importPrefixGenerator: (uri) => '__prefix${nextImportPrefixIndex++}');
+
+ // Compute the patched context file content.
+ String targetCode = SourceEdit.applySequence(
+ contextResult.content,
+ changeBuilder.sourceChange.edits[0].edits,
+ );
+
+ // Insert the code being completed.
+ int targetOffset = targetCode.indexOf(codeMarker) + offset;
+ targetCode = targetCode.replaceAll(codeMarker, code);
+
+ // Update the context file content to include the code being completed.
+ // Then resolve it, and restore the file to its initial state.
+ AnalysisResult targetResult;
+ String contentFileOverlay = fileContentOverlay[contextFile];
+ try {
+ fileContentOverlay[contextFile] = targetCode;
+ analysisDriver.changeFile(contextFile);
+ targetResult = await analysisDriver.getResult(contextFile);
+ } finally {
+ fileContentOverlay[contextFile] = contentFileOverlay;
+ analysisDriver.changeFile(contextFile);
+ }
+
+ CompletionContributor contributor = new DartCompletionManager();
+ CompletionRequestImpl request = new CompletionRequestImpl(
+ targetResult,
+ targetOffset,
+ new CompletionPerformance(),
+ );
+ var suggestions = await contributor.computeSuggestions(request);
+
+ // Remove completions with synthetic import prefixes.
+ suggestions.removeWhere((s) => s.completion.startsWith('__prefix'));
+
+ // TODO(scheglov) Add support for expressions.
+ var expressions = <RuntimeCompletionExpression>[];
+ return new RuntimeCompletionResult(expressions, suggestions);
+ }
+}
+
+/// The result of performing runtime completion.
+class RuntimeCompletionResult {
+ final List<RuntimeCompletionExpression> expressions;
+ final List<CompletionSuggestion> suggestions;
+
+ RuntimeCompletionResult(this.expressions, this.suggestions);
+}
diff --git a/pkg/analysis_server/lib/src/plugin/notification_manager.dart b/pkg/analysis_server/lib/src/plugin/notification_manager.dart
index 9aad4d5..344697c 100644
--- a/pkg/analysis_server/lib/src/plugin/notification_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/notification_manager.dart
@@ -86,12 +86,12 @@
/**
* The object used to convert results.
*/
- ResultConverter converter = new ResultConverter();
+ final ResultConverter converter = new ResultConverter();
/**
* The object used to merge results.
*/
- ResultMerger merger = new ResultMerger();
+ final ResultMerger merger = new ResultMerger();
/**
* Initialize a newly created notification manager.
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index 4b53584..fc60fb9 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -68,12 +68,15 @@
/**
* Returns a [Future] completing with [Element]s to search references to.
*
- * If a [ClassMemberElement] is given, each corresponding [Element] in the
- * hierarchy is returned.
+ * If a [ClassMemberElement] or a named [ParameterElement] is given, each
+ * corresponding [Element] in the hierarchy is returned.
*
* Otherwise, only references to [element] should be searched.
*/
Future<Iterable<Element>> _getRefElements(Element element) {
+ if (element is ParameterElement && element.isNamed) {
+ return getHierarchyNamedParameters(searchEngine, element);
+ }
if (element is ClassMemberElement) {
return getHierarchyMembers(searchEngine, element);
}
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index 131d00a..bcbf428 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -107,7 +107,7 @@
try {
_serverFuture =
- HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, initialPort ?? 0);
+ HttpServer.bind(InternetAddress.loopbackIPv4, initialPort ?? 0);
HttpServer server = await _serverFuture;
_handleServer(server);
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_core.dart b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
index 9d15c20..7000f0b 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
@@ -16,9 +16,6 @@
final AnalysisResult result;
@override
- final Source source;
-
- @override
final int offset;
/**
@@ -39,9 +36,6 @@
*/
int replacementLength;
- @override
- final ResourceProvider resourceProvider;
-
bool _aborted = false;
final CompletionPerformance performance;
@@ -49,14 +43,18 @@
/**
* Initialize a newly created completion request based on the given arguments.
*/
- CompletionRequestImpl(this.result, this.resourceProvider, Source source,
- int offset, this.performance)
- : this.source = source,
- this.offset = offset,
+ CompletionRequestImpl(this.result, int offset, this.performance)
+ : this.offset = offset,
replacementOffset = offset,
replacementLength = 0;
@override
+ ResourceProvider get resourceProvider => result.session.resourceProvider;
+
+ @override
+ Source get source => result.unit.element.source;
+
+ @override
String get sourceContents => result?.content;
/**
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
index fab1435..24b952f 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/src/generated/source.dart';
-
/**
* Overall performance of a code completion operation.
*/
@@ -13,7 +11,7 @@
final Stopwatch _stopwatch = new Stopwatch();
final List<OperationPerformance> operations = <OperationPerformance>[];
- Source source;
+ String path;
String snippet = '';
int notificationCount = -1;
int suggestionCountFirst = -1;
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 e37be19..1291f78 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
@@ -22,7 +22,7 @@
if (node is ArgumentList) {
if (request.target.entity == node.rightParenthesis) {
// Parser ignores trailing commas
- if (node.rightParenthesis.previous?.lexeme == ',') {
+ if (node.findPrevious(node.rightParenthesis)?.lexeme == ',') {
return node.arguments.length + 1;
}
}
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 351c240..22062cc5 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
@@ -57,7 +57,7 @@
Future<List<CompletionSuggestion>> computeSuggestions(
CompletionRequest request) async {
request.checkAborted();
- if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
+ if (!AnalysisEngine.isDartFileName(request.result.path)) {
return EMPTY_LIST;
}
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
index 8239f37..593de24 100644
--- 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
@@ -68,6 +68,13 @@
}
@override
+ visitConstructorElement(ConstructorElement element) {
+ if (element.context.analysisOptions.previewDart2) {
+ _addSuggestion(element);
+ }
+ }
+
+ @override
visitFieldElement(FieldElement element) {
if (element.isStatic) {
_addSuggestion(element);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
index cfd7cf4..9c5afa7 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -98,7 +98,7 @@
return new protocol.Element(kind, name, flags,
location: location,
parameters: parameters,
- returnType: nameForType(returnType));
+ returnType: nameForType(id, returnType));
}
/**
@@ -141,7 +141,7 @@
0,
isDeprecated,
false,
- returnType: nameForType(returnType),
+ returnType: nameForType(id, returnType),
element: element);
if (classDecl != null) {
SimpleIdentifier classId = classDecl.name;
@@ -204,33 +204,45 @@
}
/**
- * Return the name for the given [type].
+ * Return name of the type of the given [identifier], or, if it unresolved, the
+ * name of its declared [declaredType].
*/
-String nameForType(TypeAnnotation type) {
- if (type == NO_RETURN_TYPE) {
+String nameForType(SimpleIdentifier identifier, TypeAnnotation declaredType) {
+ if (identifier == null) {
return null;
}
+
+ // Get the type from the identifier element.
+ DartType type;
+ Element element = identifier.staticElement;
+ if (element == null) {
+ return DYNAMIC;
+ } else if (element is FunctionTypedElement) {
+ if (element is PropertyAccessorElement && element.isSetter) {
+ return null;
+ }
+ type = element.returnType;
+ } else if (element is VariableElement) {
+ type = identifier.bestType;
+ } else {
+ return null;
+ }
+
+ // If the type is unresolved, use the declared type.
+ if (type != null && type.isUndefined) {
+ if (declaredType is TypeName) {
+ Identifier id = declaredType.name;
+ if (id != null) {
+ return id.name;
+ }
+ }
+ return DYNAMIC;
+ }
+
if (type == null) {
return DYNAMIC;
}
- if (type is TypeName) {
- Identifier id = type.name;
- if (id == null) {
- return DYNAMIC;
- }
- String name = id.name;
- if (name == null || name.length <= 0) {
- return DYNAMIC;
- }
- TypeArgumentList typeArgs = type.typeArguments;
- if (typeArgs != null) {
- //TODO (danrubel) include type arguments
- }
- return name;
- } else if (type is GenericFunctionType) {
- // TODO(brianwilkerson) Implement this.
- }
- return DYNAMIC;
+ return type.toString();
}
//TODO(pq): fix to use getDefaultStringParameterValue()
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 d9ae917..19c6a82 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -1578,71 +1578,41 @@
}
Future<Null> _addProposal_flutterSwapWithChild() async {
- InstanceCreationExpression exprGoingDown =
- flutter.identifyNewExpression(node);
- if (exprGoingDown == null || !flutter.isWidgetCreation(exprGoingDown)) {
+ InstanceCreationExpression parent = flutter.identifyNewExpression(node);
+ if (!flutter.isWidgetCreation(parent)) {
_coverageMarker();
return;
}
- InstanceCreationExpression exprGoingUp =
- flutter.findChildWidget(exprGoingDown);
- if (exprGoingUp == null) {
+
+ NamedExpression childArgument = flutter.findChildArgument(parent);
+ if (childArgument?.expression is! InstanceCreationExpression ||
+ !flutter.isWidgetCreation(childArgument.expression)) {
_coverageMarker();
return;
}
- NamedExpression stableChild = flutter.findChildArgument(exprGoingUp);
- if (stableChild == null || stableChild.expression == null) {
- _coverageMarker();
- return;
- }
- String exprGoingDownSrc = utils.getNodeText(exprGoingDown);
- int dnNewlineIdx = exprGoingDownSrc.lastIndexOf(eol);
- if (dnNewlineIdx < 0 || dnNewlineIdx == exprGoingDownSrc.length - 1) {
- _coverageMarker();
- return; // Outer new-expr needs to be in multi-line format already.
- }
- String exprGoingUpSrc = utils.getNodeText(exprGoingUp);
- int upNewlineIdx = exprGoingUpSrc.lastIndexOf(eol);
- if (upNewlineIdx < 0 || upNewlineIdx == exprGoingUpSrc.length - 1) {
- _coverageMarker();
- return; // Inner new-expr needs to be in multi-line format already.
- }
- await _swapFlutterWidgets(exprGoingDown, exprGoingUp, stableChild,
- DartAssistKind.FLUTTER_SWAP_WITH_CHILD);
+ InstanceCreationExpression child = childArgument.expression;
+
+ await _swapParentAndChild(
+ parent, child, DartAssistKind.FLUTTER_SWAP_WITH_CHILD);
}
Future<Null> _addProposal_flutterSwapWithParent() async {
- InstanceCreationExpression exprGoingUp =
- flutter.identifyNewExpression(node);
- if (exprGoingUp == null || !flutter.isWidgetCreation(exprGoingUp)) {
+ InstanceCreationExpression child = flutter.identifyNewExpression(node);
+ if (!flutter.isWidgetCreation(child)) {
_coverageMarker();
return;
}
- AstNode expr = exprGoingUp.parent?.parent?.parent;
- if (expr == null || expr is! InstanceCreationExpression) {
+
+ // NamedExpression (child:), ArgumentList, InstanceCreationExpression
+ AstNode expr = child.parent?.parent?.parent;
+ if (expr is! InstanceCreationExpression) {
_coverageMarker();
return;
}
- InstanceCreationExpression exprGoingDown = expr;
- NamedExpression stableChild = flutter.findChildArgument(exprGoingUp);
- if (stableChild == null || stableChild.expression == null) {
- _coverageMarker();
- return;
- }
- String exprGoingUpSrc = utils.getNodeText(exprGoingUp);
- int upNewlineIdx = exprGoingUpSrc.lastIndexOf(eol);
- if (upNewlineIdx < 0 || upNewlineIdx == exprGoingUpSrc.length - 1) {
- _coverageMarker();
- return; // Inner new-expr needs to be in multi-line format already.
- }
- String exprGoingDownSrc = utils.getNodeText(exprGoingDown);
- int dnNewlineIdx = exprGoingDownSrc.lastIndexOf(eol);
- if (dnNewlineIdx < 0 || dnNewlineIdx == exprGoingDownSrc.length - 1) {
- _coverageMarker();
- return; // Outer new-expr needs to be in multi-line format already.
- }
- await _swapFlutterWidgets(exprGoingDown, exprGoingUp, stableChild,
- DartAssistKind.FLUTTER_SWAP_WITH_PARENT);
+ InstanceCreationExpression parent = expr;
+
+ await _swapParentAndChild(
+ parent, child, DartAssistKind.FLUTTER_SWAP_WITH_PARENT);
}
Future<Null> _addProposal_flutterWrapWidget() async {
@@ -1694,7 +1664,9 @@
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addReplacement(range.node(widgetExpr), (DartEditBuilder builder) {
- builder.write('new ');
+ if (!driver.analysisOptions.previewDart2) {
+ builder.write('new ');
+ }
if (parentClassElement == null) {
builder.addSimpleLinkedEdit('WIDGET', 'widget');
} else {
@@ -1773,7 +1745,9 @@
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addReplacement(selectedRange, (DartEditBuilder builder) {
- builder.write('new ');
+ if (!driver.analysisOptions.previewDart2) {
+ builder.write('new ');
+ }
builder.writeType(parentClassElement.type);
builder.write('(');
@@ -2085,7 +2059,8 @@
if (node is SimpleIdentifier &&
node.parent is AssignmentExpression &&
(node.parent as AssignmentExpression).leftHandSide == node &&
- node.parent.parent is ExpressionStatement) {} else {
+ node.parent.parent is ExpressionStatement) {
+ } else {
_coverageMarker();
return;
}
@@ -2107,7 +2082,8 @@
declNode.parent is VariableDeclaration &&
(declNode.parent as VariableDeclaration).name == declNode &&
declNode.parent.parent is VariableDeclarationList &&
- declNode.parent.parent.parent is VariableDeclarationStatement) {} else {
+ declNode.parent.parent.parent is VariableDeclarationStatement) {
+ } else {
_coverageMarker();
return;
}
@@ -2129,7 +2105,8 @@
ExpressionStatement assignStatement =
node.parent.parent as ExpressionStatement;
if (assignStatement.parent is Block &&
- assignStatement.parent == declStatement.parent) {} else {
+ assignStatement.parent == declStatement.parent) {
+ } else {
_coverageMarker();
return;
}
@@ -2137,7 +2114,8 @@
// check that "declaration" and "assignment" statements are adjacent
List<Statement> statements = block.statements;
if (statements.indexOf(assignStatement) ==
- statements.indexOf(declStatement) + 1) {} else {
+ statements.indexOf(declStatement) + 1) {
+ } else {
_coverageMarker();
return;
}
@@ -2155,7 +2133,8 @@
// prepare enclosing VariableDeclarationList
VariableDeclarationList declList =
node.getAncestor((node) => node is VariableDeclarationList);
- if (declList != null && declList.variables.length == 1) {} else {
+ if (declList != null && declList.variables.length == 1) {
+ } else {
_coverageMarker();
return;
}
@@ -2167,7 +2146,8 @@
}
// prepare VariableDeclarationStatement in Block
if (declList.parent is VariableDeclarationStatement &&
- declList.parent.parent is Block) {} else {
+ declList.parent.parent is Block) {
+ } else {
_coverageMarker();
return;
}
@@ -2180,20 +2160,23 @@
{
// declaration should not be last Statement
int declIndex = statements.indexOf(declStatement);
- if (declIndex < statements.length - 1) {} else {
+ if (declIndex < statements.length - 1) {
+ } else {
_coverageMarker();
return;
}
// next Statement should be assignment
Statement assignStatement = statements[declIndex + 1];
- if (assignStatement is ExpressionStatement) {} else {
+ if (assignStatement is ExpressionStatement) {
+ } else {
_coverageMarker();
return;
}
ExpressionStatement expressionStatement =
assignStatement as ExpressionStatement;
// expression should be assignment
- if (expressionStatement.expression is AssignmentExpression) {} else {
+ if (expressionStatement.expression is AssignmentExpression) {
+ } else {
_coverageMarker();
return;
}
@@ -2570,7 +2553,8 @@
// prepare DartVariableStatement, should be part of Block
VariableDeclarationStatement statement =
node.getAncestor((node) => node is VariableDeclarationStatement);
- if (statement != null && statement.parent is Block) {} else {
+ if (statement != null && statement.parent is Block) {
+ } else {
_coverageMarker();
return;
}
@@ -3011,87 +2995,84 @@
return utils.getRangeText(range);
}
- Future<Null> _swapFlutterWidgets(
- InstanceCreationExpression exprGoingDown,
- InstanceCreationExpression exprGoingUp,
- NamedExpression stableChild,
- AssistKind assistKind) async {
- String currentSource = unitElement.context.getContents(source).data;
- // TODO(messick) Find a better way to get LineInfo for the source.
- LineInfo lineInfo = new LineInfo.fromContent(currentSource);
- int currLn = lineInfo.getLocation(exprGoingUp.offset).lineNumber;
- int lnOffset = lineInfo.getOffsetOfLine(currLn);
+ Future<void> _swapParentAndChild(InstanceCreationExpression parent,
+ InstanceCreationExpression child, AssistKind kind) async {
+ // The child must have its own child.
+ if (flutter.findChildArgument(child) == null) {
+ _coverageMarker();
+ return;
+ }
- DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(exprGoingDown),
- (DartEditBuilder builder) {
- String argSrc =
- utils.getText(exprGoingUp.offset, lnOffset - exprGoingUp.offset);
- builder.write(argSrc); // Append child new-expr plus rest of line.
+ var changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(file, (builder) {
+ builder.addReplacement(range.node(parent), (builder) {
+ var childArgs = child.argumentList;
+ var parentArgs = parent.argumentList;
+ var childText = _getRangeText(range.startStart(child, childArgs));
+ var parentText = _getRangeText(range.startStart(parent, parentArgs));
- String getSrc(Expression expr) {
- int startLn = lineInfo.getLocation(expr.offset).lineNumber;
- int startOffset = lineInfo.getOffsetOfLine(startLn - 1);
- int endLn =
- lineInfo.getLocation(expr.offset + expr.length).lineNumber + 1;
- int curOffset = lineInfo.getOffsetOfLine(endLn - 1);
- return utils.getText(startOffset, curOffset - startOffset);
+ var parentIndent = utils.getLinePrefix(parent.offset);
+ var childIndent = parentIndent + ' ';
+
+ // Write the beginning of the child.
+ builder.write(childText);
+ builder.writeln('(');
+
+ // Write all the arguments of the parent.
+ // Don't write the "child".
+ Expression stableChild;
+ for (Expression argument in childArgs.arguments) {
+ if (flutter.isChildArgument(argument)) {
+ stableChild = argument;
+ } else {
+ String text = _getNodeText(argument);
+ text = _replaceSourceIndent(text, childIndent, parentIndent);
+ builder.write(parentIndent);
+ builder.write(' ');
+ builder.write(text);
+ builder.writeln(',');
+ }
}
- String outerIndent = utils.getLinePrefix(exprGoingDown.offset);
- String innerIndent = utils.getLinePrefix(exprGoingUp.offset);
- exprGoingUp.argumentList.arguments.forEach((arg) {
- if (arg is NamedExpression && arg.name.label.name == 'child') {
- if (stableChild != arg) {
- _coverageMarker();
- return;
- }
- // Insert exprGoingDown here.
- // Copy from start of line to offset of exprGoingDown.
- currLn = lineInfo.getLocation(stableChild.offset).lineNumber;
- lnOffset = lineInfo.getOffsetOfLine(currLn - 1);
- argSrc = utils.getText(
- lnOffset, stableChild.expression.offset - lnOffset);
- argSrc = _replaceSourceIndent(argSrc, innerIndent, outerIndent);
- builder.write(argSrc);
- int nextLn = lineInfo.getLocation(exprGoingDown.offset).lineNumber;
- lnOffset = lineInfo.getOffsetOfLine(nextLn);
- argSrc = utils.getText(
- exprGoingDown.offset, lnOffset - exprGoingDown.offset);
- builder.write(argSrc);
+ // Write the parent as a new child.
+ builder.write(parentIndent);
+ builder.write(' ');
+ builder.write('child: ');
+ builder.write(parentText);
+ builder.writeln('(');
- exprGoingDown.argumentList.arguments.forEach((val) {
- if (val is NamedExpression && val.name.label.name == 'child') {
- // Insert stableChild here at same indent level.
- builder.write(utils.getNodePrefix(arg.name));
- argSrc = utils.getNodeText(stableChild);
- builder.write(argSrc);
- if (assistKind == DartAssistKind.FLUTTER_SWAP_WITH_PARENT) {
- builder.write(',$eol');
- }
- } else {
- argSrc = getSrc(val);
- argSrc = _replaceSourceIndent(argSrc, outerIndent, innerIndent);
- builder.write(argSrc);
- }
- });
- if (assistKind == DartAssistKind.FLUTTER_SWAP_WITH_CHILD) {
- builder.write(',$eol');
- }
- builder.write(innerIndent);
- builder.write('),$eol');
- } else {
- argSrc = getSrc(arg);
- argSrc = _replaceSourceIndent(argSrc, innerIndent, outerIndent);
- builder.write(argSrc);
+ // Write all arguments of the parent.
+ // Don't write its child.
+ for (Expression argument in parentArgs.arguments) {
+ if (!flutter.isChildArgument(argument)) {
+ String text = _getNodeText(argument);
+ text = _replaceSourceIndent(text, parentIndent, childIndent);
+ builder.write(childIndent);
+ builder.write(' ');
+ builder.write(text);
+ builder.writeln(',');
}
- });
- builder.write(outerIndent);
+ }
+
+ // Write the child of the "child" now, as the child of the "parent".
+ {
+ var text = _getNodeText(stableChild);
+ builder.write(childIndent);
+ builder.write(' ');
+ builder.write(text);
+ builder.writeln(',');
+ }
+
+ // Close the parent expression.
+ builder.write(childIndent);
+ builder.writeln('),');
+
+ // Close the child expression.
+ builder.write(parentIndent);
builder.write(')');
});
});
- _addAssistFromBuilder(changeBuilder, assistKind);
+ _addAssistFromBuilder(changeBuilder, kind);
}
/**
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 a97741f..3df2168 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -403,6 +403,7 @@
if (errorCode == HintCode.UNDEFINED_METHOD ||
errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
await _addFix_importLibrary_withFunction();
+ await _addFix_importLibrary_withType();
await _addFix_undefinedMethod_useSimilar();
await _addFix_undefinedMethod_create();
await _addFix_undefinedFunction_create();
@@ -1954,13 +1955,13 @@
_addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE);
}
- Future<Null> _addFix_importLibrary(FixKind kind, Source library) async {
- String libraryUri = getLibrarySourceUri(unitLibraryElement, library);
+ Future<Null> _addFix_importLibrary(FixKind kind, Uri library) async {
+ String uriText;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.importLibraries([library]);
+ uriText = builder.importLibrary(library);
});
- _addFixFromBuilder(changeBuilder, kind, args: [libraryUri]);
+ _addFixFromBuilder(changeBuilder, kind, args: [uriText]);
}
Future<Null> _addFix_importLibrary_withElement(String name,
@@ -2060,7 +2061,7 @@
fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
}
// Add the fix.
- await _addFix_importLibrary(fixKind, librarySource);
+ await _addFix_importLibrary(fixKind, librarySource.uri);
}
}
}
@@ -2348,9 +2349,11 @@
} else {
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- range.endEnd(emptyStatement.beginToken.previous, emptyStatement),
- ' {}');
+ Token previous = emptyStatement.findPrevious(emptyStatement.beginToken);
+ if (previous != null) {
+ builder.addSimpleReplacement(
+ range.endEnd(previous, emptyStatement), ' {}');
+ }
});
_addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_BRACKETS);
}
@@ -2820,7 +2823,8 @@
Future<Null> _addFix_undefinedFunction_create() async {
// should be the name of the invocation
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {} else {
+ if (node is SimpleIdentifier && node.parent is MethodInvocation) {
+ } else {
return;
}
String name = (node as SimpleIdentifier).name;
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 5878f8c..d5bd83e 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -21,14 +21,14 @@
show SourceChange, SourceEdit;
import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as pathos;
/**
* Adds edits to the given [change] that ensure that all the [libraries] are
* imported into the given [targetLibrary].
*/
-void addLibraryImports(
- SourceChange change, LibraryElement targetLibrary, Set<Source> libraries) {
+void addLibraryImports(pathos.Context pathContext, SourceChange change,
+ LibraryElement targetLibrary, Set<Source> libraries) {
CorrectionUtils libUtils;
try {
CompilationUnitElement unitElement = targetLibrary.definingCompilationUnit;
@@ -52,7 +52,8 @@
// Prepare all URIs to import.
List<String> uriList = libraries
- .map((library) => getLibrarySourceUri(targetLibrary, library))
+ .map((library) =>
+ getLibrarySourceUri(pathContext, targetLibrary, library.uri))
.toList();
uriList.sort((a, b) => a.compareTo(b));
@@ -347,18 +348,14 @@
/**
* Computes the best URI to import [what] into [from].
*/
-String getLibrarySourceUri(LibraryElement from, Source what) {
- String whatPath = what.fullName;
- // check if an absolute URI (such as 'dart:' or 'package:')
- Uri whatUri = what.uri;
- String whatUriScheme = whatUri.scheme;
- if (whatUriScheme != '' && whatUriScheme != 'file') {
- return whatUri.toString();
+String getLibrarySourceUri(
+ pathos.Context pathContext, LibraryElement from, Uri what) {
+ if (what.scheme == 'file') {
+ String fromFolder = pathContext.dirname(from.source.fullName);
+ String relativeFile = pathContext.relative(what.path, from: fromFolder);
+ return pathContext.split(relativeFile).join('/');
}
- // compute a relative URI
- String fromFolder = dirname(from.source.fullName);
- String relativeFile = relative(whatPath, from: fromFolder);
- return split(relativeFile).join('/');
+ return what.toString();
}
/**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index c1ce1cb..4a1d37a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -389,7 +389,8 @@
}
}
// done
- addLibraryImports(change, libraryElement, librariesToImport);
+ addLibraryImports(session.resourceProvider.pathContext, change,
+ libraryElement, librariesToImport);
return change;
}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 4b1c9eb4..eca6220 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -26,7 +26,7 @@
final AstProvider astProvider;
final ResolvedUnitCache unitCache;
- Set<LocalElement> elements = new Set<LocalElement>();
+ List<LocalElement> elements = [];
RenameLocalRefactoringImpl(
SearchEngine searchEngine, this.astProvider, LocalElement element)
@@ -92,25 +92,11 @@
* Fills [elements] with [Element]s to rename.
*/
Future _prepareElements() async {
- Element enclosing = element.enclosingElement;
- if (enclosing is MethodElement &&
- element is ParameterElement &&
- (element as ParameterElement).isNamed) {
- // prepare hierarchy methods
- Set<ClassMemberElement> methods =
- await getHierarchyMembers(searchEngine, enclosing);
- // add named parameter from each method
- for (ClassMemberElement method in methods) {
- if (method is MethodElement) {
- for (ParameterElement parameter in method.parameters) {
- if (parameter.isNamed && parameter.name == element.name) {
- elements.add(parameter);
- }
- }
- }
- }
+ Element element = this.element;
+ if (element is ParameterElement && element.isNamed) {
+ elements = await getHierarchyNamedParameters(searchEngine, element);
} else {
- elements = new Set.from([element]);
+ elements = [element];
}
}
}
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 3f9bb483..6441488 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -100,6 +100,34 @@
}
/**
+ * If the [element] is a named parameter in a [MethodElement], return all
+ * corresponding named parameters in the method hierarchy.
+ */
+Future<List<ParameterElement>> getHierarchyNamedParameters(
+ SearchEngine searchEngine, ParameterElement element) async {
+ if (element.isNamed) {
+ Element method = element.enclosingElement;
+ if (method is MethodElement) {
+ var hierarchyParameters = <ParameterElement>[];
+ var hierarchyMembers = await getHierarchyMembers(searchEngine, method);
+ for (ClassMemberElement hierarchyMethod in hierarchyMembers) {
+ if (hierarchyMethod is MethodElement) {
+ for (var hierarchyParameter in hierarchyMethod.parameters) {
+ if (hierarchyParameter.isNamed &&
+ hierarchyParameter.name == element.name) {
+ hierarchyParameters.add(hierarchyParameter);
+ break;
+ }
+ }
+ }
+ }
+ return hierarchyParameters;
+ }
+ }
+ return [element];
+}
+
+/**
* Returns non-synthetic members of the given [ClassElement] and its super
* classes.
*
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index ac435fd..b579add 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -11,7 +11,6 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/domain_diagnostic.dart';
-import 'package:analysis_server/src/domain_execution.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/server/http_server.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
@@ -351,12 +350,14 @@
buf.writeln('<table>');
buf.writeln(
'<tr><th>Time</th><th>Results</th><th>Source</th><th>Snippet</th></tr>');
+ var pathContext = completionDomain.server.resourceProvider.pathContext;
for (CompletionPerformance completion in completions) {
+ String shortName = pathContext.basename(completion.path);
buf.writeln('<tr>'
'<td class="pre right">${printMilliseconds(
completion.elapsedInMilliseconds)}</td>'
'<td class="right">${completion.suggestionCount}</td>'
- '<td>${escape(completion.source.shortName)}</td>'
+ '<td>${escape(shortName)}</td>'
'<td><code>${escape(completion.snippet)}</code></td>'
'</tr>');
}
@@ -1310,19 +1311,5 @@
buf.write('$item');
});
}
-
- // execution domain
- ExecutionDomainHandler domain = server.handlers.firstWhere(
- (handler) => handler is ExecutionDomainHandler,
- orElse: () => null);
-
- h3('Execution domain');
- ul(ExecutionService.VALUES, (item) {
- if (domain.onFileAnalyzed != null) {
- buf.write('$item (has subscriptions)');
- } else {
- buf.write('$item (no subscriptions)');
- }
- });
}
}
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index bb06c05..ce4d959 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -111,18 +111,16 @@
* [newExpr], or `null` if none.
*/
NamedExpression findChildArgument(InstanceCreationExpression newExpr) =>
- newExpr.argumentList.arguments.firstWhere(
- (arg) => arg is NamedExpression && arg.name.label.name == 'child',
- orElse: () => null);
+ newExpr.argumentList.arguments
+ .firstWhere(isChildArgument, orElse: () => null);
/**
* Return the named expression representing the `children` argument of the
* given [newExpr], or `null` if none.
*/
NamedExpression findChildrenArgument(InstanceCreationExpression newExpr) =>
- newExpr.argumentList.arguments.firstWhere(
- (arg) => arg is NamedExpression && arg.name.label.name == 'children',
- orElse: () => null);
+ newExpr.argumentList.arguments
+ .firstWhere(isChildrenArgument, orElse: () => null);
/**
* Return the Flutter instance creation expression that is the value of the
@@ -244,6 +242,18 @@
}
/**
+ * Return `true` is the given [argument] is the `child` argument.
+ */
+bool isChildArgument(Expression argument) =>
+ argument is NamedExpression && argument.name.label.name == 'child';
+
+/**
+ * Return `true` is the given [argument] is the `child` argument.
+ */
+bool isChildrenArgument(Expression argument) =>
+ argument is NamedExpression && argument.name.label.name == 'children';
+
+/**
* Return `true` if the given [type] is the Flutter class `StatefulWidget`.
*/
bool isExactlyStatefulWidgetType(DartType type) {
@@ -331,7 +341,13 @@
* subtype.
*/
bool isWidgetExpression(AstNode node) {
- if (node?.parent is TypeName || node?.parent?.parent is TypeName) {
+ if (node == null) {
+ return false;
+ }
+ if (node.parent is TypeName || node.parent?.parent is TypeName) {
+ return false;
+ }
+ if (node.parent is ConstructorName) {
return false;
}
if (node is NamedExpression) {
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 3ee2c09..8cf628e 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -53,7 +53,7 @@
UriResolver resourceResolver;
StringBuffer _logBuffer = new StringBuffer();
- FileContentOverlay _fileContentOverlay = new FileContentOverlay();
+ FileContentOverlay fileContentOverlay = new FileContentOverlay();
AnalysisDriver _driver;
AnalysisDriver get driver => _driver;
@@ -101,7 +101,7 @@
Source source = file.createSource(uri);
driver.addFile(file.path);
driver.changeFile(file.path);
- _fileContentOverlay[file.path] = content;
+ fileContentOverlay[file.path] = content;
return source;
}
@@ -136,7 +136,7 @@
log,
resourceProvider,
new MemoryByteStore(),
- _fileContentOverlay,
+ fileContentOverlay,
new ContextRoot(resourceProvider.convertPath('/project'), []),
sourceFactory,
new AnalysisOptionsImpl()..strongMode = true);
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 1e1aec8..9d2093d 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -732,21 +732,17 @@
<String>["1+fooConst", "1-fooNotConst", "1-bar"],
failingTests: '1');
- buildTests(
- 'testCompletion_annotation_type',
- '''
+ buildTests('testCompletion_annotation_type', '''
class AAA {
const AAA({int a, int b});
const AAA.nnn(int c, int d);
}
@AAA!1
main() {
-}''',
- <String>[
- "1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/,
- "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/
- ],
- failingTests: '1');
+}''', <String>[
+ "1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/,
+ "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/
+ ]);
buildTests('testCompletion_annotation_type_inClass_withoutMember', '''
class AAA {
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 078a2bb..07c23fa 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -619,8 +619,11 @@
assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
elementKind: ElementKind.CLASS);
- // No constructors suggested.
- assertNoResult('A.named');
+ // Both constructors - default and named, are suggested.
+ assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
+ elementKind: ElementKind.CONSTRUCTOR);
+ assertHasResult(CompletionSuggestionKind.INVOCATION, 'A.named',
+ elementKind: ElementKind.CONSTRUCTOR);
}
test_local_named_constructor() {
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 02b95c1..296c28b 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -6,6 +6,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_execution.dart';
+import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/sdk.dart';
@@ -177,6 +178,38 @@
super.tearDown();
}
+ test_getSuggestions() async {
+ var code = r'''
+class A {
+ int foo;
+}
+
+void contextFunction() {
+ var a = new A();
+ // context line
+}
+''';
+
+ String path = newFile('/test.dart').path;
+ newFile(path, content: code);
+
+ Request request = new ExecutionGetSuggestionsParams(
+ 'a.',
+ 2,
+ path,
+ code.indexOf('// context line'),
+ <RuntimeCompletionVariable>[]).toRequest('0');
+ Response response = await waitResponse(request);
+
+ var result = new ExecutionGetSuggestionsResult.fromResponse(response);
+ expect(result.suggestions, isNotEmpty);
+
+ expect(
+ result.suggestions,
+ contains(
+ predicate<CompletionSuggestion>((s) => s.completion == 'foo')));
+ }
+
void test_mapUri_file() {
String path = newFile('/a/b.dart').path;
// map the file
diff --git a/pkg/analysis_server/test/integration/coverage.md b/pkg/analysis_server/test/integration/coverage.md
index 4dbeae6..466c66e 100644
--- a/pkg/analysis_server/test/integration/coverage.md
+++ b/pkg/analysis_server/test/integration/coverage.md
@@ -53,6 +53,7 @@
## execution domain
- [x] execution.createContext
- [x] execution.deleteContext
+- [ ] execution.getSuggestions
- [x] execution.mapUri
- [x] execution.setSubscriptions
- [ ] execution.launchData
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index 9b77a47..41880e3 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1830,6 +1830,98 @@
}
/**
+ * Request completion suggestions for the given runtime context.
+ *
+ * It might take one or two requests of this type to get completion
+ * suggestions. The first request should have only "code", "offset", and
+ * "variables", but not "expressions". If there are sub-expressions that can
+ * have different runtime types, and are considered to be safe to evaluate at
+ * runtime (e.g. getters), so using their actual runtime types can improve
+ * completion results, the server will not include the "suggestions" field in
+ * the response, and instead will return the "expressions" field. The client
+ * will use debug API to get current runtime types for these sub-expressions
+ * and send another request, this time with "expressions". If there are no
+ * interesting sub-expressions to get runtime types for, or when the
+ * "expressions" field is provided by the client, the server will return
+ * "suggestions" in the response.
+ *
+ * Parameters
+ *
+ * code: String
+ *
+ * The code to get suggestions in.
+ *
+ * offset: int
+ *
+ * The offset within the code to get suggestions at.
+ *
+ * contextFile: FilePath
+ *
+ * The path of the context file, e.g. the file of the current debugger
+ * frame. The combination of the context file and context offset can be
+ * used to ensure that all variables of the context are available for
+ * completion (with their static types).
+ *
+ * contextOffset: int
+ *
+ * The offset in the context file, e.g. the line offset in the current
+ * debugger frame.
+ *
+ * variables: List<RuntimeCompletionVariable>
+ *
+ * The runtime context variables that are potentially referenced in the
+ * code.
+ *
+ * expressions: List<RuntimeCompletionExpression> (optional)
+ *
+ * The list of sub-expressions in the code for which the client wants to
+ * provide runtime types. It does not have to be the full list of
+ * expressions requested by the server, for missing expressions their
+ * static types will be used.
+ *
+ * When this field is omitted, the server will return completion
+ * suggestions only when there are no interesting sub-expressions in the
+ * given code. The client may provide an empty list, in this case the
+ * server will return completion suggestions.
+ *
+ * Returns
+ *
+ * suggestions: List<CompletionSuggestion> (optional)
+ *
+ * The completion suggestions. In contrast to usual completion request,
+ * suggestions for private elements also will be provided.
+ *
+ * If there are sub-expressions that can have different runtime types, and
+ * are considered to be safe to evaluate at runtime (e.g. getters), so
+ * using their actual runtime types can improve completion results, the
+ * server omits this field in the response, and instead will return the
+ * "expressions" field.
+ *
+ * expressions: List<RuntimeCompletionExpression> (optional)
+ *
+ * The list of sub-expressions in the code for which the server would like
+ * to know runtime types to provide better completion suggestions.
+ *
+ * This field is omitted the field "suggestions" is returned.
+ */
+ Future<ExecutionGetSuggestionsResult> sendExecutionGetSuggestions(
+ String code,
+ int offset,
+ String contextFile,
+ int contextOffset,
+ List<RuntimeCompletionVariable> variables,
+ {List<RuntimeCompletionExpression> expressions}) async {
+ var params = new ExecutionGetSuggestionsParams(
+ code, offset, contextFile, contextOffset, variables,
+ expressions: expressions)
+ .toJson();
+ var result = await server.send("execution.getSuggestions", params);
+ ResponseDecoder decoder = new ResponseDecoder(null);
+ return new ExecutionGetSuggestionsResult.fromJson(
+ decoder, 'result', result);
+ }
+
+ /**
* Map a URI from the execution context to the file that it corresponds to,
* or map a file to the URI that it corresponds to in the execution context.
*
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index dd07221..bdb6726 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -572,19 +572,21 @@
* FoldingKind
*
* enum {
- * COMMENT
- * CLASS_MEMBER
+ * ANNOTATIONS
+ * CLASS_BODY
* DIRECTIVES
* DOCUMENTATION_COMMENT
- * TOP_LEVEL_DECLARATION
+ * FILE_HEADER
+ * FUNCTION_BODY
* }
*/
final Matcher isFoldingKind = new MatchesEnum("FoldingKind", [
- "COMMENT",
- "CLASS_MEMBER",
+ "ANNOTATIONS",
+ "CLASS_BODY",
"DIRECTIVES",
"DOCUMENTATION_COMMENT",
- "TOP_LEVEL_DECLARATION"
+ "FILE_HEADER",
+ "FUNCTION_BODY"
]);
/**
@@ -1277,6 +1279,70 @@
]);
/**
+ * RuntimeCompletionExpression
+ *
+ * {
+ * "offset": int
+ * "length": int
+ * "type": optional RuntimeCompletionExpressionType
+ * }
+ */
+final Matcher isRuntimeCompletionExpression = new LazyMatcher(() =>
+ new MatchesJsonObject(
+ "RuntimeCompletionExpression", {"offset": isInt, "length": isInt},
+ optionalFields: {"type": isRuntimeCompletionExpressionType}));
+
+/**
+ * RuntimeCompletionExpressionType
+ *
+ * {
+ * "libraryPath": optional FilePath
+ * "kind": RuntimeCompletionExpressionTypeKind
+ * "name": optional String
+ * "typeArguments": optional List<RuntimeCompletionExpressionType>
+ * "returnType": optional RuntimeCompletionExpressionType
+ * "parameterTypes": optional List<RuntimeCompletionExpressionType>
+ * "parameterNames": optional List<String>
+ * }
+ */
+final Matcher isRuntimeCompletionExpressionType = new LazyMatcher(
+ () => new MatchesJsonObject("RuntimeCompletionExpressionType", {
+ "kind": isRuntimeCompletionExpressionTypeKind
+ }, optionalFields: {
+ "libraryPath": isFilePath,
+ "name": isString,
+ "typeArguments": isListOf(isRuntimeCompletionExpressionType),
+ "returnType": isRuntimeCompletionExpressionType,
+ "parameterTypes": isListOf(isRuntimeCompletionExpressionType),
+ "parameterNames": isListOf(isString)
+ }));
+
+/**
+ * RuntimeCompletionExpressionTypeKind
+ *
+ * enum {
+ * DYNAMIC
+ * FUNCTION
+ * INTERFACE
+ * }
+ */
+final Matcher isRuntimeCompletionExpressionTypeKind = new MatchesEnum(
+ "RuntimeCompletionExpressionTypeKind",
+ ["DYNAMIC", "FUNCTION", "INTERFACE"]);
+
+/**
+ * RuntimeCompletionVariable
+ *
+ * {
+ * "name": String
+ * "type": RuntimeCompletionExpressionType
+ * }
+ */
+final Matcher isRuntimeCompletionVariable = new LazyMatcher(() =>
+ new MatchesJsonObject("RuntimeCompletionVariable",
+ {"name": isString, "type": isRuntimeCompletionExpressionType}));
+
+/**
* SearchId
*
* String
@@ -2329,6 +2395,44 @@
final Matcher isExecutionDeleteContextResult = isNull;
/**
+ * execution.getSuggestions params
+ *
+ * {
+ * "code": String
+ * "offset": int
+ * "contextFile": FilePath
+ * "contextOffset": int
+ * "variables": List<RuntimeCompletionVariable>
+ * "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ */
+final Matcher isExecutionGetSuggestionsParams = new LazyMatcher(
+ () => new MatchesJsonObject("execution.getSuggestions params", {
+ "code": isString,
+ "offset": isInt,
+ "contextFile": isFilePath,
+ "contextOffset": isInt,
+ "variables": isListOf(isRuntimeCompletionVariable)
+ }, optionalFields: {
+ "expressions": isListOf(isRuntimeCompletionExpression)
+ }));
+
+/**
+ * execution.getSuggestions result
+ *
+ * {
+ * "suggestions": optional List<CompletionSuggestion>
+ * "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ */
+final Matcher isExecutionGetSuggestionsResult = new LazyMatcher(() =>
+ new MatchesJsonObject("execution.getSuggestions result", null,
+ optionalFields: {
+ "suggestions": isListOf(isCompletionSuggestion),
+ "expressions": isListOf(isRuntimeCompletionExpression)
+ }));
+
+/**
* execution.launchData params
*
* {
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index de74dd3..bbe7e01 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -128,6 +128,7 @@
abstract class Iterable<E> {
Iterator<E> get iterator;
bool get isEmpty;
+ void forEach(void f(E element));
Iterable<T> map<T>(T f(E e)) => null;
T fold<T>(T initialValue, T combine(T previousValue, E element));
List<E> toList({bool growable: true});
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 3e411f4..d320dbb 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -305,6 +305,30 @@
assertHasResult(SearchResultKind.INVOCATION, 'mmm(20)');
}
+ test_hierarchy_namedParameter() async {
+ addTestFile('''
+class A {
+ m({p}) {} // in A
+}
+class B extends A {
+ m({p}) {} // in B
+}
+class C extends B {
+ m({p}) {} // in C
+}
+main(A a, B b, C c) {
+ a.m(p: 1);
+ b.m(p: 2);
+ c.m(p: 3);
+}
+''');
+ await findElementReferences('p}) {} // in B', false);
+ expect(searchElement.kind, ElementKind.PARAMETER);
+ assertHasResult(SearchResultKind.REFERENCE, 'p: 1');
+ assertHasResult(SearchResultKind.REFERENCE, 'p: 2');
+ assertHasResult(SearchResultKind.REFERENCE, 'p: 3');
+ }
+
test_label() async {
addTestFile('''
main() {
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 558129a..d6d8191 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
@@ -11,7 +11,6 @@
show DartCompletionRequestImpl;
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/parser.dart' as analyzer;
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
@@ -26,7 +25,6 @@
abstract class DartCompletionContributorTest extends AbstractContextTest {
static const String _UNCHECKED = '__UNCHECKED__';
String testFile;
- Source testSource;
int completionOffset;
int replacementOffset;
int replacementLength;
@@ -47,7 +45,7 @@
* Return `true` if contributors should suggest constructors in contexts where
* there is no `new` or `const` keyword.
*/
- bool get suggestConstructorsWithoutNew => false;
+ bool get suggestConstructorsWithoutNew => true;
bool get usingFastaParser => analyzer.Parser.useFasta;
@@ -59,7 +57,7 @@
expect(nextOffset, equals(-1), reason: 'too many ^');
content = content.substring(0, completionOffset) +
content.substring(completionOffset + 1);
- testSource = addSource(testFile, content);
+ addSource(testFile, content);
}
void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
@@ -473,13 +471,8 @@
Future computeSuggestions({int times = 200}) async {
AnalysisResult analysisResult =
await driver.getResult(convertPath(testFile));
- testSource = analysisResult.unit.element.source;
CompletionRequestImpl baseRequest = new CompletionRequestImpl(
- analysisResult,
- resourceProvider,
- testSource,
- completionOffset,
- new CompletionPerformance());
+ analysisResult, completionOffset, new CompletionPerformance());
// Build the request
Completer<DartCompletionRequest> requestCompleter =
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index d0717e8..51950f4 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -48,8 +48,6 @@
// Build the request
CompletionRequestImpl baseRequest = new CompletionRequestImpl(
await driver.getResult(testFile),
- resourceProvider,
- testSource,
completionOffset,
new CompletionPerformance());
Completer<DartCompletionRequest> requestCompleter =
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 8f6efea..60b262c 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -2449,12 +2449,12 @@
await computeSuggestions();
assertSuggestClass('A');
- assertNotSuggested('A.a1');
- assertNotSuggested('A.a2');
+ assertSuggestConstructor('A.a1');
+ assertSuggestConstructor('A.a2');
assertSuggestClass('B');
- assertNotSuggested('B.b1');
- assertNotSuggested('B.b2');
+ assertSuggestConstructor('B.b1');
+ assertSuggestConstructor('B.b2');
}
test_ImportDirective_dart() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index fb5a912..1aa985c 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -330,7 +330,7 @@
assertSuggestFunction('bar', 'String',
kind: CompletionSuggestionKind.IDENTIFIER,
relevance: DART_RELEVANCE_LOCAL_FUNCTION);
- assertSuggestFunction('boo', 'dynamic',
+ assertSuggestFunction('boo', 'Null',
kind: CompletionSuggestionKind.IDENTIFIER,
relevance: DART_RELEVANCE_LOCAL_FUNCTION);
assertNotSuggested('hasLength');
@@ -365,7 +365,7 @@
kind: CompletionSuggestionKind.IDENTIFIER,
relevance:
DART_RELEVANCE_LOCAL_FUNCTION + DART_RELEVANCE_BOOST_SUBTYPE);
- assertSuggestFunction('boo', 'dynamic',
+ assertSuggestFunction('boo', 'Null',
kind: CompletionSuggestionKind.IDENTIFIER,
relevance:
DART_RELEVANCE_LOCAL_FUNCTION + DART_RELEVANCE_BOOST_SUBTYPE);
@@ -871,7 +871,7 @@
assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
assertSuggestMethod('b', 'X', 'void',
relevance: DART_RELEVANCE_LOCAL_METHOD);
- assertSuggestFunction('localF', null,
+ assertSuggestFunction('localF', 'Null',
relevance: DART_RELEVANCE_LOCAL_FUNCTION);
assertSuggestLocalVariable('f', null);
// Don't suggest locals out of scope
@@ -2352,7 +2352,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestLocalVariable('values', 'List');
+ assertSuggestLocalVariable('values', 'List<int>');
assertNotSuggested('index');
}
@@ -2363,7 +2363,7 @@
expect(replacementOffset, completionOffset - 1);
expect(replacementLength, 1);
- assertSuggestLocalVariable('values', 'List');
+ assertSuggestLocalVariable('values', 'List<int>');
assertNotSuggested('index');
}
@@ -2374,7 +2374,7 @@
expect(replacementOffset, completionOffset - 1);
expect(replacementLength, 1);
- assertSuggestLocalVariable('values', 'List');
+ assertSuggestLocalVariable('values', 'List<int>');
assertNotSuggested('index');
}
@@ -2742,7 +2742,7 @@
}
assertSuggestFunction('bar', 'void',
relevance: DART_RELEVANCE_LOCAL_FUNCTION);
- assertSuggestParameter('args', 'List');
+ assertSuggestParameter('args', 'List<dynamic>');
assertSuggestParameter('b', 'R');
assertNotSuggested('Object');
}
@@ -4202,6 +4202,12 @@
assertSuggestLocalVariable('_ab', null);
}
+ test_inferredType() async {
+ addTestSource('main() { var v = 42; ^ }');
+ await computeSuggestions();
+ assertSuggestLocalVariable('v', 'int');
+ }
+
test_prioritization_public() async {
addTestSource('main() {var ab; var _ab; a^}');
await computeSuggestions();
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
index 8aebb55..2987710 100644
--- 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
@@ -114,8 +114,8 @@
''');
await computeSuggestions();
- assertNotSuggested('foo');
- assertNotSuggested('bar');
+ assertSuggestConstructor('foo', elementName: 'foo');
+ assertSuggestConstructor('bar', elementName: 'bar');
}
test_keyword() async {
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 0cc4f57..752c8af 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -38,7 +38,7 @@
String resultCode;
LinkedEditGroup linkedPositionGroup;
- bool get omitNew => false;
+ bool get omitNew => true;
/**
* Asserts that there is an [Assist] of the given [kind] at [offset] which
@@ -518,7 +518,7 @@
''');
await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
main() {
- Function v = () => 1;
+ int Function() v = () => 1;
}
''');
}
@@ -3405,6 +3405,7 @@
return new Scaffold(
// start
body: new Center(
+ key: null,
child: new /*caret*/GestureDetector(
onTap: () => startResize(),
child: new Container(
@@ -3412,7 +3413,6 @@
height: 300.0,
),
),
- key: null,
),
// end
);
@@ -3421,6 +3421,58 @@
''');
}
+ test_flutterSwapWithChild_OK_notFormatted() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new /*caret*/Expanded(
+ flex: 2,
+ child: new GestureDetector(
+ child: new Text(
+ 'foo',
+ ), onTap: () {
+ print(42);
+ },
+ ),
+ );
+ }
+}''');
+ _setCaretLocation();
+ await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_CHILD, '''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new GestureDetector(
+ onTap: () {
+ print(42);
+ },
+ child: new /*caret*/Expanded(
+ flex: 2,
+ child: new Text(
+ 'foo',
+ ),
+ ),
+ );
+ }
+}''');
+ }
+
test_flutterSwapWithParent_OK() async {
addFlutterPackage();
await resolveTestUnit('''
@@ -3452,11 +3504,11 @@
body: new /*caret*/GestureDetector(
onTap: () => startResize(),
child: new Center(
+ key: null,
child: new Container(
width: 200.0,
height: 300.0,
),
- key: null,
),
),
// end
@@ -3466,6 +3518,58 @@
''');
}
+ test_flutterSwapWithParent_OK_notFormatted() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new GestureDetector(
+ child: new /*caret*/Expanded(
+ child: new Text(
+ 'foo',
+ ),
+ flex: 2,
+ ), onTap: () {
+ print(42);
+ },
+ );
+ }
+}''');
+ _setCaretLocation();
+ await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_PARENT, '''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new /*caret*/Expanded(
+ flex: 2,
+ child: new GestureDetector(
+ onTap: () {
+ print(42);
+ },
+ child: new Text(
+ 'foo',
+ ),
+ ),
+ );
+ }
+}''');
+ }
+
test_flutterSwapWithParent_OK_outerIsInChildren() async {
addFlutterPackage();
await resolveTestUnit('''
@@ -3568,7 +3672,7 @@
import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
- return /*caret*/new Container();
+ return /*caret*/Container();
}
}
''');
@@ -3577,12 +3681,59 @@
import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
- return /*caret*/new Center(child: new Container());
+ return /*caret*/Center(child: Container());
}
}
''');
}
+ test_flutterWrapCenter_OK_namedConstructor() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ MyWidget.named();
+
+ Widget build(BuildContext context) => null;
+}
+
+main() {
+ return MyWidget./*caret*/named();
+}
+''');
+ _setCaretLocation();
+ if (omitNew) {
+ await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ MyWidget.named();
+
+ Widget build(BuildContext context) => null;
+}
+
+main() {
+ return Center(child: MyWidget./*caret*/named());
+}
+''');
+ } else {
+ await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ MyWidget.named();
+
+ Widget build(BuildContext context) => null;
+}
+
+main() {
+ return new Center(child: MyWidget./*caret*/named());
+}
+''');
+ }
+ }
+
test_flutterWrapColumn_OK_coveredByWidget() async {
addFlutterPackage();
await resolveTestUnit('''
@@ -3704,7 +3855,7 @@
main() {
return Container(
- child: /*caret*/new Text('aaa'),
+ child: /*caret*/Text('aaa'),
);
}
''');
@@ -3714,9 +3865,9 @@
main() {
return Container(
- child: /*caret*/new Column(
+ child: /*caret*/Column(
children: <Widget>[
- new Text('aaa'),
+ Text('aaa'),
],
),
);
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index be7a4cc..cde73fd 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -4533,6 +4533,84 @@
''');
}
+ test_importLibrarySdk_withClass_instanceCreation_explicitNew() async {
+ await resolveTestUnit('''
+class C {
+ foo() {
+ new Future();
+ }
+}
+''');
+ await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+ foo() {
+ new Future();
+ }
+}
+''');
+ }
+
+ test_importLibrarySdk_withClass_instanceCreation_explicitNew_namedConstructor() async {
+ await resolveTestUnit('''
+class C {
+ foo() {
+ new Future.value(0);
+ }
+}
+''');
+ await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+ foo() {
+ new Future.value(0);
+ }
+}
+''');
+ }
+
+ test_importLibrarySdk_withClass_instanceCreation_implicitNew() async {
+ configurePreviewDart2();
+ await resolveTestUnit('''
+class C {
+ foo() {
+ Future();
+ }
+}
+''');
+ await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+ foo() {
+ Future();
+ }
+}
+''');
+ }
+
+ test_importLibrarySdk_withClass_instanceCreation_implicitNew_namedConstructor() async {
+ configurePreviewDart2();
+ await resolveTestUnit('''
+class C {
+ foo() {
+ Future.value(0);
+ }
+}
+''');
+ await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+ foo() {
+ Future.value(0);
+ }
+}
+''');
+ }
+
test_importLibrarySdk_withClass_invocationTarget() async {
await resolveTestUnit('''
main() {
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index 05866c9..3e1981c 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -287,7 +287,8 @@
void _assertAddLibraryImport(List<Source> newLibraries, String expectedCode) {
SourceChange change = new SourceChange('');
- addLibraryImports(change, testLibraryElement, newLibraries.toSet());
+ addLibraryImports(resourceProvider.pathContext, change, testLibraryElement,
+ newLibraries.toSet());
SourceFileEdit testEdit = change.getFileEdit(testFile);
expect(testEdit, isNotNull);
String resultCode = SourceEdit.applySequence(testCode, testEdit.edits);
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index d81893d..a6827ee 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -254,6 +254,95 @@
return Future.wait([futureA, futureB, futureD]);
}
+ test_getHierarchyNamedParameters() async {
+ await _indexTestUnit('''
+class A {
+ foo({p}) {}
+}
+class B extends A {
+ foo({p}) {}
+}
+class C extends B {
+ foo({p}) {}
+}
+class D {
+ foo({p}) {}
+}
+class E extends D {
+ foo({p}) {}
+}
+''');
+ ClassElement classA = findElement('A');
+ ClassElement classB = findElement('B');
+ ClassElement classC = findElement('C');
+ ClassElement classD = findElement('D');
+ ClassElement classE = findElement('E');
+ ParameterElement parameterA = classA.methods[0].parameters[0];
+ ParameterElement parameterB = classB.methods[0].parameters[0];
+ ParameterElement parameterC = classC.methods[0].parameters[0];
+ ParameterElement parameterD = classD.methods[0].parameters[0];
+ ParameterElement parameterE = classE.methods[0].parameters[0];
+
+ {
+ var result = await getHierarchyNamedParameters(searchEngine, parameterA);
+ expect(result, unorderedEquals([parameterA, parameterB, parameterC]));
+ }
+
+ {
+ var result = await getHierarchyNamedParameters(searchEngine, parameterB);
+ expect(result, unorderedEquals([parameterA, parameterB, parameterC]));
+ }
+
+ {
+ var result = await getHierarchyNamedParameters(searchEngine, parameterC);
+ expect(result, unorderedEquals([parameterA, parameterB, parameterC]));
+ }
+
+ {
+ var result = await getHierarchyNamedParameters(searchEngine, parameterD);
+ expect(result, unorderedEquals([parameterD, parameterE]));
+ }
+
+ {
+ var result = await getHierarchyNamedParameters(searchEngine, parameterE);
+ expect(result, unorderedEquals([parameterD, parameterE]));
+ }
+ }
+
+ test_getHierarchyNamedParameters_invalid_missing() async {
+ verifyNoTestUnitErrors = false;
+ await _indexTestUnit('''
+class A {
+ foo({p}) {}
+}
+class B extends A {
+ foo() {}
+}
+''');
+ ClassElement classA = findElement('A');
+ ParameterElement parameterA = classA.methods[0].parameters[0];
+
+ var result = await getHierarchyNamedParameters(searchEngine, parameterA);
+ expect(result, unorderedEquals([parameterA]));
+ }
+
+ test_getHierarchyNamedParameters_invalid_notNamed() async {
+ verifyNoTestUnitErrors = false;
+ await _indexTestUnit('''
+class A {
+ foo({p}) {}
+}
+class B extends A {
+ foo(p) {}
+}
+''');
+ ClassElement classA = findElement('A');
+ ParameterElement parameterA = classA.methods[0].parameters[0];
+
+ var result = await getHierarchyNamedParameters(searchEngine, parameterA);
+ expect(result, unorderedEquals([parameterA]));
+ }
+
test_getMembers() async {
await _indexTestUnit('''
class A {
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index 72a26a7..55d864b 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -35,6 +35,7 @@
""";
// Since there are no region comment markers above
+ // just check the length instead of the contents
final regions = await _computeRegions(content);
expect(regions, hasLength(0));
}
@@ -79,7 +80,7 @@
main() {/*1:INC*/
print("Hello, world!");
-/*1:INC:TOP_LEVEL_DECLARATION*/}
+/*1:INC:FUNCTION_BODY*/}
// Content after
""";
@@ -96,7 +97,7 @@
/// that spans lines/*1:INC:DOCUMENTATION_COMMENT*/
main() {/*2:INC*/
print("Hello, world!");
-/*2:INC:TOP_LEVEL_DECLARATION*/}
+/*2:INC:FUNCTION_BODY*/}
// Content after
""";
@@ -112,9 +113,9 @@
main() {/*1:INC*/
doPrint() {/*2:INC*/
print("Hello, world!");
- /*2:INC:TOP_LEVEL_DECLARATION*/}
+ /*2:INC:FUNCTION_BODY*/}
doPrint();
-/*1:INC:TOP_LEVEL_DECLARATION*/}
+/*1:INC:FUNCTION_BODY*/}
// Content after
""";
@@ -130,12 +131,12 @@
class Person {/*1:INC*/
Person() {/*2:INC*/
print("Hello, world!");
- /*2:INC:CLASS_MEMBER*/}
+ /*2:INC:FUNCTION_BODY*/}
void sayHello() {/*3:INC*/
print("Hello, world!");
- /*3:INC:CLASS_MEMBER*/}
-/*1:INC:TOP_LEVEL_DECLARATION*/}
+ /*3:INC:FUNCTION_BODY*/}
+/*1:INC:CLASS_BODY*/}
// Content after
""";
@@ -146,21 +147,137 @@
test_annotations() async {
String content = """
-@myMultilineAnnotation(/*1:INC*/
+@myMultilineAnnotation/*1:INC*/(
"this",
"is a test"
-/*1:INC:TOP_LEVEL_DECLARATION*/)
-@another()
-@andAnother
-main() {/*2:INC*/
- print("Hello, world!");
-/*2:INC:TOP_LEVEL_DECLARATION*/}
+)/*1:EXC:ANNOTATIONS*/
+main() {}
+
+@noFoldNecessary
+main2() {}
+
+@multipleAnnotations1/*2:INC*/(
+ "this",
+ "is a test"
+)
+@multipleAnnotations2()
+@multipleAnnotations3/*2:EXC:ANNOTATIONS*/
+main3() {}
+
+@noFoldsForSingleClassAnnotation
+class MyClass {}
+
+@folded.classAnnotation1/*3:INC*/()
+@foldedClassAnnotation2/*3:EXC:ANNOTATIONS*/
+class MyClass2 {/*4:INC*/
+ @fieldAnnotation1/*5:INC*/
+ @fieldAnnotation2/*5:EXC:ANNOTATIONS*/
+ int myField;
+
+ @getterAnnotation1/*6:INC*/
+ @getterAnnotation2/*6:EXC:ANNOTATIONS*/
+ int get myThing => 1;
+
+ @setterAnnotation1/*7:INC*/
+ @setterAnnotation2/*7:EXC:ANNOTATIONS*/
+ void set myThing(int value) {}
+
+ @methodAnnotation1/*8:INC*/
+ @methodAnnotation2/*8:EXC:ANNOTATIONS*/
+ void myMethod() {}
+
+ @constructorAnnotation1/*9:INC*/
+ @constructorAnnotation1/*9:EXC:ANNOTATIONS*/
+ MyClass2() {}
+/*4:INC:CLASS_BODY*/}
""";
final regions = await _computeRegions(content);
_compareRegions(regions, content);
}
+ test_file_header() async {
+ String content = """
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+
+// This is not the file header
+// It's just a comment
+main() {}
+""";
+
+ final regions = await _computeRegions(content);
+ _compareRegions(regions, content);
+ }
+
+ test_file_header_with_no_function_comment() async {
+ String content = """
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+
+main() {}
+""";
+
+ final regions = await _computeRegions(content);
+ _compareRegions(regions, content);
+ }
+
+ test_file_header_with_non_end_of_line_comment() async {
+ String content = """
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+/* This shouldn't be part of the file header */
+
+main() {}
+""";
+
+ final regions = await _computeRegions(content);
+ _compareRegions(regions, content);
+ }
+
+ test_file_header_does_not_include_block_comments() async {
+ String content = """
+/*
+ * Copyright some year by some people
+ * See LICENCE etc.
+ */
+/* This shouldn't be part of the file header */
+
+main() {}
+""";
+
+ final regions = await _computeRegions(content);
+ expect(regions, hasLength(0));
+ }
+
+ test_file_header_with_script_prefix() async {
+ String content = """
+#! /usr/bin/dart
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+
+// This is not the file header
+// It's just a comment
+main() {}
+""";
+
+ final regions = await _computeRegions(content);
+ _compareRegions(regions, content);
+ }
+
+ test_comment_is_not_considered_file_header() async {
+ String content = """
+// This is not the file header
+// It's just a comment
+main() {}
+""";
+
+ // Since there are no region comment markers above
+ // just check the length instead of the contents
+ final regions = await _computeRegions(content);
+ expect(regions, hasLength(0));
+ }
+
/// Compares provided folding regions with expected
/// regions extracted from the comments in the provided content.
void _compareRegions(List<FoldingRegion> regions, String content) {
diff --git a/pkg/analysis_server/test/src/domains/execution/completion_test.dart b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
new file mode 100644
index 0000000..4ba0ecd
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
@@ -0,0 +1,379 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/src/domains/execution/completion.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../abstract_context.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RuntimeCompletionComputerTest);
+ });
+}
+
+@reflectiveTest
+class RuntimeCompletionComputerTest extends AbstractContextTest {
+ String contextFile;
+ int contextOffset;
+
+ RuntimeCompletionResult result;
+
+ void addContextFile(String content) {
+ contextFile = convertPath('/test/lib/context.dart');
+ addSource(contextFile, content);
+
+ contextOffset = content.indexOf('// context line');
+ expect(contextOffset, isNonNegative,
+ reason: "Not found '// context line'.");
+ }
+
+ void assertNotSuggested(String completion) {
+ CompletionSuggestion suggestion = getSuggest(completion);
+ if (suggestion != null) {
+ failedCompletion('unexpected $completion');
+ }
+ }
+
+ void assertSuggested(String completion, {String returnType}) {
+ CompletionSuggestion suggestion = getSuggest(completion);
+ if (suggestion == null) {
+ failedCompletion('expected $completion');
+ }
+ if (returnType != null) {
+ expect(suggestion.returnType, returnType);
+ }
+ }
+
+ Future<void> computeCompletion(
+ String code, {
+ List<RuntimeCompletionVariable> variables,
+ List<RuntimeCompletionExpression> expressions,
+ }) async {
+ int codeOffset = code.indexOf('^');
+ expect(codeOffset, isNonNegative);
+ code = code.replaceAll('^', '');
+
+ var computer = new RuntimeCompletionComputer(
+ resourceProvider,
+ fileContentOverlay,
+ driver,
+ code,
+ codeOffset,
+ contextFile,
+ contextOffset,
+ variables,
+ expressions);
+ result = await computer.compute();
+ }
+
+ void failedCompletion(String message) {
+ var sb = new StringBuffer(message);
+ if (result.suggestions != null) {
+ sb.write('\n found');
+ result.suggestions.toList()
+ ..sort((a, b) => a.completion.compareTo(b.completion))
+ ..forEach((suggestion) {
+ sb.write('\n ${suggestion.completion} -> $suggestion');
+ });
+ }
+ fail(sb.toString());
+ }
+
+ CompletionSuggestion getSuggest(String completion) {
+ expect(result.suggestions, isNotNull);
+ for (var suggestion in result.suggestions) {
+ if (suggestion.completion == completion) {
+ return suggestion;
+ }
+ }
+ return null;
+ }
+
+ test_class_fields() async {
+ addContextFile(r'''
+class A {
+ int a;
+}
+class B extends A {
+ double b, c;
+ void foo() {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ assertSuggested('c', returnType: 'double');
+ }
+
+ test_class_methods() async {
+ addContextFile(r'''
+class A {
+ int a() => null;
+}
+class B extends A {
+ double b() => null;
+ void foo() {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_inPart() async {
+ addSource('/test/lib/a.dart', r'''
+part 'b.dart';
+part 'context.dart';
+
+int a;
+''');
+ addSource('/test/lib/b.dart', r'''
+part of 'a.dart';
+
+double b;
+''');
+ addContextFile(r'''
+part of 'a.dart';
+
+String c;
+
+void main() {
+ // context line
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ assertSuggested('c', returnType: 'String');
+ }
+
+ test_locals_block() async {
+ addContextFile(r'''
+class A {
+ int foo;
+}
+
+void contextFunction() {
+ var a = new A();
+ // context line
+}
+''');
+ await computeCompletion('a.^');
+ assertSuggested('foo');
+
+ // There was an issue with cleaning up
+ // Check that the second time it works too.
+ await computeCompletion('a.^');
+ assertSuggested('foo');
+ }
+
+ test_locals_block_codeWithClosure() async {
+ addContextFile(r'''
+main() {
+ var items = <String>[];
+ // context line
+}
+''');
+ await computeCompletion('items.forEach((e) => e.^)');
+ assertSuggested('toUpperCase');
+ }
+
+ test_locals_block_nested() async {
+ addContextFile(r'''
+void main() {
+ var a = 0;
+ var b = 0.0;
+ {
+ var a = '';
+ // context line
+ }
+ var c = 0;
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'String');
+ assertSuggested('b', returnType: 'double');
+
+ // "c" is defined after the context offset, so is not visible.
+ assertNotSuggested('c');
+ }
+
+ test_locals_for() async {
+ addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+ for (var a = 0, b = 0.0; a < 5; a++) {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_locals_forEach() async {
+ addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+ for (var a in intItems) {
+ for (var b in doubleItems) {
+ // context line
+ }
+ }
+}sosol
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_parameters_constructor() async {
+ addContextFile(r'''
+class C {
+ C(int a, double b) {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_parameters_function() async {
+ addContextFile(r'''
+void main(int a, double b) {
+ // context line
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_parameters_function_locals() async {
+ addContextFile(r'''
+void main(int a, int b) {
+ String a;
+ double c;
+ // context line
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'String');
+ assertSuggested('b', returnType: 'int');
+ assertSuggested('c', returnType: 'double');
+ }
+
+ test_parameters_function_nested() async {
+ addContextFile(r'''
+void foo(int a, double b) {
+ void bar(String a, bool c) {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'String');
+ assertSuggested('b', returnType: 'double');
+ assertSuggested('c', returnType: 'bool');
+ }
+
+ test_parameters_functionExpression() async {
+ addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+ intItems.forEach((a) {
+ doubleItems.forEach((b) {
+ // context line
+ });
+ });
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_parameters_method() async {
+ addContextFile(r'''
+class C {
+ void main(int a, double b) {
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_parameters_method_locals() async {
+ addContextFile(r'''
+class C {
+ void main(int a, int b) {
+ String a;
+ double c;
+ // context line
+ }
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'String');
+ assertSuggested('b', returnType: 'int');
+ assertSuggested('c', returnType: 'double');
+ }
+
+ test_syntheticImportPrefix() async {
+ newFile('/test/lib/a.dart', content: 'class A {}');
+ newFile('/test/lib/b.dart', content: 'class B {}');
+ addContextFile(r'''
+import 'a.dart';
+impoty 'b.dart';
+main() {
+ var a = new A();
+ var b = new B();
+ // context line
+}
+''');
+ await computeCompletion('^');
+ for (var suggestion in result.suggestions) {
+ expect(suggestion.completion, isNot(startsWith('__prefix')));
+ }
+ }
+
+ test_topLevelFunctions() async {
+ addContextFile(r'''
+int a() => null;
+double b() => null;
+void main() {
+ // context line
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+
+ test_topLevelVariables() async {
+ addContextFile(r'''
+int a;
+double b;
+
+void main() {
+ // context line
+}
+''');
+ await computeCompletion('^');
+ assertSuggested('a', returnType: 'int');
+ assertSuggested('b', returnType: 'double');
+ }
+}
diff --git a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
index 91ff506..6bfaf1d 100644
--- a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
+++ b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
@@ -91,7 +91,7 @@
String fileName(int stringIndex) => '${strings[stringIndex]}.dart';
FoldingRegion foldingRegion(int offset, int length) =>
- new FoldingRegion(FoldingKind.COMMENT, offset, length);
+ new FoldingRegion(FoldingKind.FILE_HEADER, offset, length);
HighlightRegion highlightRegion(int offset, int length) =>
new HighlightRegion(HighlightRegionType.FIELD, offset, length);
diff --git a/pkg/analysis_server/test/src/plugin/result_merger_test.dart b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
index dc409fc..75f11fa 100644
--- a/pkg/analysis_server/test/src/plugin/result_merger_test.dart
+++ b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
@@ -129,7 +129,7 @@
}
void test_mergeFoldingRegion() {
- FoldingKind kind = FoldingKind.COMMENT;
+ FoldingKind kind = FoldingKind.FILE_HEADER;
FoldingRegion region1 = new FoldingRegion(kind, 30, 5);
FoldingRegion region2 = new FoldingRegion(kind, 0, 4);
FoldingRegion region3 = new FoldingRegion(kind, 20, 6);
diff --git a/pkg/analysis_server/test/src/utilities/flutter_test.dart b/pkg/analysis_server/test/src/utilities/flutter_test.dart
index fb85da9..7ec839b 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_test.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_test.dart
@@ -272,6 +272,7 @@
import 'package:flutter/widgets.dart';
main() {
+ MyWidget.named(); // use
var text = new Text('abc');
text;
createEmptyText();
@@ -280,9 +281,20 @@
intVariable;
}
+class MyWidget extends StatelessWidget {
+ MyWidget.named();
+}
+
Text createEmptyText() => new Text('');
''');
{
+ Expression expression = findNodeAtString('named(); // use');
+ expect(isWidgetExpression(expression), isFalse);
+ var creation = expression.parent.parent as InstanceCreationExpression;
+ expect(isWidgetExpression(creation), isTrue);
+ }
+
+ {
Expression expression = findNodeAtString("new Text('abc')");
expect(isWidgetExpression(expression), isTrue);
}
diff --git a/pkg/analysis_server/test/src/utilities/flutter_util.dart b/pkg/analysis_server/test/src/utilities/flutter_util.dart
index 83b5b82..e7012a1 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_util.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_util.dart
@@ -229,6 +229,14 @@
Widget child,
});
}
+
+class Expanded extends StatelessWidget {
+ const Expanded({
+ Key key,
+ int flex: 1,
+ @required Widget child,
+ });
+}
''');
newFile('$flutterPkgLibPath/src/widgets/container.dart', r'''
diff --git a/pkg/analysis_server/tool/instrumentation/server.dart b/pkg/analysis_server/tool/instrumentation/server.dart
index 768c8b8..64f77bb 100644
--- a/pkg/analysis_server/tool/instrumentation/server.dart
+++ b/pkg/analysis_server/tool/instrumentation/server.dart
@@ -101,7 +101,7 @@
* Begin serving HTTP requests over the given [port].
*/
void serveHttp(int port) {
- _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port);
+ _server = HttpServer.bind(InternetAddress.loopbackIPv4, port);
_server.then(_handleServer).catchError((_) {/* Ignore errors. */});
}
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 6272649..f8991b5 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -576,6 +576,38 @@
public void execution_deleteContext(String id);
/**
+ * {@code execution.getSuggestions}
+ *
+ * Request completion suggestions for the given runtime context.
+ *
+ * It might take one or two requests of this type to get completion suggestions. The first request
+ * should have only "code", "offset", and "variables", but not "expressions". If there are
+ * sub-expressions that can have different runtime types, and are considered to be safe to evaluate
+ * at runtime (e.g. getters), so using their actual runtime types can improve completion results,
+ * the server will not include the "suggestions" field in the response, and instead will return the
+ * "expressions" field. The client will use debug API to get current runtime types for these
+ * sub-expressions and send another request, this time with "expressions". If there are no
+ * interesting sub-expressions to get runtime types for, or when the "expressions" field is
+ * provided by the client, the server will return "suggestions" in the response.
+ *
+ * @param code The code to get suggestions in.
+ * @param offset The offset within the code to get suggestions at.
+ * @param contextFile The path of the context file, e.g. the file of the current debugger frame.
+ * The combination of the context file and context offset can be used to ensure that all
+ * variables of the context are available for completion (with their static types).
+ * @param contextOffset The offset in the context file, e.g. the line offset in the current
+ * debugger frame.
+ * @param variables The runtime context variables that are potentially referenced in the code.
+ * @param expressions The list of sub-expressions in the code for which the client wants to provide
+ * runtime types. It does not have to be the full list of expressions requested by the
+ * server, for missing expressions their static types will be used. When this field is
+ * omitted, the server will return completion suggestions only when there are no
+ * interesting sub-expressions in the given code. The client may provide an empty list, in
+ * this case the server will return completion suggestions.
+ */
+ public void execution_getSuggestions(String code, int offset, String contextFile, int contextOffset, List<RuntimeCompletionVariable> variables, List<RuntimeCompletionExpression> expressions, GetSuggestionsConsumer consumer);
+
+ /**
* {@code execution.mapUri}
*
* Map a URI from the execution context to the file that it corresponds to, or map a file to the
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
index f1d947b..e4fdb2e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
@@ -15,14 +15,16 @@
*/
public class FoldingKind {
- public static final String COMMENT = "COMMENT";
+ public static final String ANNOTATIONS = "ANNOTATIONS";
- public static final String CLASS_MEMBER = "CLASS_MEMBER";
+ public static final String CLASS_BODY = "CLASS_BODY";
public static final String DIRECTIVES = "DIRECTIVES";
public static final String DOCUMENTATION_COMMENT = "DOCUMENTATION_COMMENT";
- public static final String TOP_LEVEL_DECLARATION = "TOP_LEVEL_DECLARATION";
+ public static final String FILE_HEADER = "FILE_HEADER";
+
+ public static final String FUNCTION_BODY = "FUNCTION_BODY";
}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
new file mode 100644
index 0000000..c0cc239
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for 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 has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * An expression for which we want to know its runtime type. In expressions like `a.b.c.where((e)
+ * => e.^)` we want to know the runtime type of `a.b.c` to enforce it statically at the time
+ * when we compute completion suggestions, and get better type for `e`.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class RuntimeCompletionExpression {
+
+ public static final RuntimeCompletionExpression[] EMPTY_ARRAY = new RuntimeCompletionExpression[0];
+
+ public static final List<RuntimeCompletionExpression> EMPTY_LIST = Lists.newArrayList();
+
+ /**
+ * The offset of the expression in the code for completion.
+ */
+ private final int offset;
+
+ /**
+ * The length of the expression in the code for completion.
+ */
+ private final int length;
+
+ /**
+ * When the expression is sent from the server to the client, the type is omitted. The client
+ * should fill the type when it sends the request to the server again.
+ */
+ private final RuntimeCompletionExpressionType type;
+
+ /**
+ * Constructor for {@link RuntimeCompletionExpression}.
+ */
+ public RuntimeCompletionExpression(int offset, int length, RuntimeCompletionExpressionType type) {
+ this.offset = offset;
+ this.length = length;
+ this.type = type;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof RuntimeCompletionExpression) {
+ RuntimeCompletionExpression other = (RuntimeCompletionExpression) obj;
+ return
+ other.offset == offset &&
+ other.length == length &&
+ ObjectUtilities.equals(other.type, type);
+ }
+ return false;
+ }
+
+ public static RuntimeCompletionExpression fromJson(JsonObject jsonObject) {
+ int offset = jsonObject.get("offset").getAsInt();
+ int length = jsonObject.get("length").getAsInt();
+ RuntimeCompletionExpressionType type = jsonObject.get("type") == null ? null : RuntimeCompletionExpressionType.fromJson(jsonObject.get("type").getAsJsonObject());
+ return new RuntimeCompletionExpression(offset, length, type);
+ }
+
+ public static List<RuntimeCompletionExpression> fromJsonArray(JsonArray jsonArray) {
+ if (jsonArray == null) {
+ return EMPTY_LIST;
+ }
+ ArrayList<RuntimeCompletionExpression> list = new ArrayList<RuntimeCompletionExpression>(jsonArray.size());
+ Iterator<JsonElement> iterator = jsonArray.iterator();
+ while (iterator.hasNext()) {
+ list.add(fromJson(iterator.next().getAsJsonObject()));
+ }
+ return list;
+ }
+
+ /**
+ * The length of the expression in the code for completion.
+ */
+ public int getLength() {
+ return length;
+ }
+
+ /**
+ * The offset of the expression in the code for completion.
+ */
+ public int getOffset() {
+ return offset;
+ }
+
+ /**
+ * When the expression is sent from the server to the client, the type is omitted. The client
+ * should fill the type when it sends the request to the server again.
+ */
+ public RuntimeCompletionExpressionType getType() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+ builder.append(offset);
+ builder.append(length);
+ builder.append(type);
+ return builder.toHashCode();
+ }
+
+ public JsonObject toJson() {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("offset", offset);
+ jsonObject.addProperty("length", length);
+ if (type != null) {
+ jsonObject.add("type", type.toJson());
+ }
+ return jsonObject;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ builder.append("offset=");
+ builder.append(offset + ", ");
+ builder.append("length=");
+ builder.append(length + ", ");
+ builder.append("type=");
+ builder.append(type);
+ builder.append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java
new file mode 100644
index 0000000..c31710a
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for 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 has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A type at runtime.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class RuntimeCompletionExpressionType {
+
+ public static final RuntimeCompletionExpressionType[] EMPTY_ARRAY = new RuntimeCompletionExpressionType[0];
+
+ public static final List<RuntimeCompletionExpressionType> EMPTY_LIST = Lists.newArrayList();
+
+ /**
+ * The path of the library that has this type. Omitted if the type is not declared in any library,
+ * e.g. "dynamic", or "void".
+ */
+ private final String libraryPath;
+
+ /**
+ * The kind of the type.
+ */
+ private final String kind;
+
+ /**
+ * The name of the type. Omitted if the type does not have a name, e.g. an inline function type.
+ */
+ private final String name;
+
+ /**
+ * The type arguments of the type. Omitted if the type does not have type parameters.
+ */
+ private final List<RuntimeCompletionExpressionType> typeArguments;
+
+ /**
+ * If the type is a function type, the return type of the function. Omitted if the type is not a
+ * function type.
+ */
+ private final RuntimeCompletionExpressionType returnType;
+
+ /**
+ * If the type is a function type, the types of the function parameters of all kinds - required,
+ * optional positional, and optional named. Omitted if the type is not a function type.
+ */
+ private final List<RuntimeCompletionExpressionType> parameterTypes;
+
+ /**
+ * If the type is a function type, the names of the function parameters of all kinds - required,
+ * optional positional, and optional named. The names of positional parameters are empty strings.
+ * Omitted if the type is not a function type.
+ */
+ private final List<String> parameterNames;
+
+ /**
+ * Constructor for {@link RuntimeCompletionExpressionType}.
+ */
+ public RuntimeCompletionExpressionType(String libraryPath, String kind, String name, List<RuntimeCompletionExpressionType> typeArguments, RuntimeCompletionExpressionType returnType, List<RuntimeCompletionExpressionType> parameterTypes, List<String> parameterNames) {
+ this.libraryPath = libraryPath;
+ this.kind = kind;
+ this.name = name;
+ this.typeArguments = typeArguments;
+ this.returnType = returnType;
+ this.parameterTypes = parameterTypes;
+ this.parameterNames = parameterNames;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof RuntimeCompletionExpressionType) {
+ RuntimeCompletionExpressionType other = (RuntimeCompletionExpressionType) obj;
+ return
+ ObjectUtilities.equals(other.libraryPath, libraryPath) &&
+ ObjectUtilities.equals(other.kind, kind) &&
+ ObjectUtilities.equals(other.name, name) &&
+ ObjectUtilities.equals(other.typeArguments, typeArguments) &&
+ ObjectUtilities.equals(other.returnType, returnType) &&
+ ObjectUtilities.equals(other.parameterTypes, parameterTypes) &&
+ ObjectUtilities.equals(other.parameterNames, parameterNames);
+ }
+ return false;
+ }
+
+ public static RuntimeCompletionExpressionType fromJson(JsonObject jsonObject) {
+ String libraryPath = jsonObject.get("libraryPath") == null ? null : jsonObject.get("libraryPath").getAsString();
+ String kind = jsonObject.get("kind").getAsString();
+ String name = jsonObject.get("name") == null ? null : jsonObject.get("name").getAsString();
+ List<RuntimeCompletionExpressionType> typeArguments = jsonObject.get("typeArguments") == null ? null : RuntimeCompletionExpressionType.fromJsonArray(jsonObject.get("typeArguments").getAsJsonArray());
+ RuntimeCompletionExpressionType returnType = jsonObject.get("returnType") == null ? null : RuntimeCompletionExpressionType.fromJson(jsonObject.get("returnType").getAsJsonObject());
+ List<RuntimeCompletionExpressionType> parameterTypes = jsonObject.get("parameterTypes") == null ? null : RuntimeCompletionExpressionType.fromJsonArray(jsonObject.get("parameterTypes").getAsJsonArray());
+ List<String> parameterNames = jsonObject.get("parameterNames") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("parameterNames").getAsJsonArray());
+ return new RuntimeCompletionExpressionType(libraryPath, kind, name, typeArguments, returnType, parameterTypes, parameterNames);
+ }
+
+ public static List<RuntimeCompletionExpressionType> fromJsonArray(JsonArray jsonArray) {
+ if (jsonArray == null) {
+ return EMPTY_LIST;
+ }
+ ArrayList<RuntimeCompletionExpressionType> list = new ArrayList<RuntimeCompletionExpressionType>(jsonArray.size());
+ Iterator<JsonElement> iterator = jsonArray.iterator();
+ while (iterator.hasNext()) {
+ list.add(fromJson(iterator.next().getAsJsonObject()));
+ }
+ return list;
+ }
+
+ /**
+ * The kind of the type.
+ */
+ public String getKind() {
+ return kind;
+ }
+
+ /**
+ * The path of the library that has this type. Omitted if the type is not declared in any library,
+ * e.g. "dynamic", or "void".
+ */
+ public String getLibraryPath() {
+ return libraryPath;
+ }
+
+ /**
+ * The name of the type. Omitted if the type does not have a name, e.g. an inline function type.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * If the type is a function type, the names of the function parameters of all kinds - required,
+ * optional positional, and optional named. The names of positional parameters are empty strings.
+ * Omitted if the type is not a function type.
+ */
+ public List<String> getParameterNames() {
+ return parameterNames;
+ }
+
+ /**
+ * If the type is a function type, the types of the function parameters of all kinds - required,
+ * optional positional, and optional named. Omitted if the type is not a function type.
+ */
+ public List<RuntimeCompletionExpressionType> getParameterTypes() {
+ return parameterTypes;
+ }
+
+ /**
+ * If the type is a function type, the return type of the function. Omitted if the type is not a
+ * function type.
+ */
+ public RuntimeCompletionExpressionType getReturnType() {
+ return returnType;
+ }
+
+ /**
+ * The type arguments of the type. Omitted if the type does not have type parameters.
+ */
+ public List<RuntimeCompletionExpressionType> getTypeArguments() {
+ return typeArguments;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+ builder.append(libraryPath);
+ builder.append(kind);
+ builder.append(name);
+ builder.append(typeArguments);
+ builder.append(returnType);
+ builder.append(parameterTypes);
+ builder.append(parameterNames);
+ return builder.toHashCode();
+ }
+
+ public JsonObject toJson() {
+ JsonObject jsonObject = new JsonObject();
+ if (libraryPath != null) {
+ jsonObject.addProperty("libraryPath", libraryPath);
+ }
+ jsonObject.addProperty("kind", kind);
+ if (name != null) {
+ jsonObject.addProperty("name", name);
+ }
+ if (typeArguments != null) {
+ JsonArray jsonArrayTypeArguments = new JsonArray();
+ for (RuntimeCompletionExpressionType elt : typeArguments) {
+ jsonArrayTypeArguments.add(elt.toJson());
+ }
+ jsonObject.add("typeArguments", jsonArrayTypeArguments);
+ }
+ if (returnType != null) {
+ jsonObject.add("returnType", returnType.toJson());
+ }
+ if (parameterTypes != null) {
+ JsonArray jsonArrayParameterTypes = new JsonArray();
+ for (RuntimeCompletionExpressionType elt : parameterTypes) {
+ jsonArrayParameterTypes.add(elt.toJson());
+ }
+ jsonObject.add("parameterTypes", jsonArrayParameterTypes);
+ }
+ if (parameterNames != null) {
+ JsonArray jsonArrayParameterNames = new JsonArray();
+ for (String elt : parameterNames) {
+ jsonArrayParameterNames.add(new JsonPrimitive(elt));
+ }
+ jsonObject.add("parameterNames", jsonArrayParameterNames);
+ }
+ return jsonObject;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ builder.append("libraryPath=");
+ builder.append(libraryPath + ", ");
+ builder.append("kind=");
+ builder.append(kind + ", ");
+ builder.append("name=");
+ builder.append(name + ", ");
+ builder.append("typeArguments=");
+ builder.append(StringUtils.join(typeArguments, ", ") + ", ");
+ builder.append("returnType=");
+ builder.append(returnType + ", ");
+ builder.append("parameterTypes=");
+ builder.append(StringUtils.join(parameterTypes, ", ") + ", ");
+ builder.append("parameterNames=");
+ builder.append(StringUtils.join(parameterNames, ", "));
+ builder.append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java
new file mode 100644
index 0000000..c544c9f
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for 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 has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+/**
+ * An enumeration of the kinds of runtime expression types.
+ *
+ * @coverage dart.server.generated.types
+ */
+public class RuntimeCompletionExpressionTypeKind {
+
+ public static final String DYNAMIC = "DYNAMIC";
+
+ public static final String FUNCTION = "FUNCTION";
+
+ public static final String INTERFACE = "INTERFACE";
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java
new file mode 100644
index 0000000..05e9040
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for 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 has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A variable in a runtime context.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class RuntimeCompletionVariable {
+
+ public static final RuntimeCompletionVariable[] EMPTY_ARRAY = new RuntimeCompletionVariable[0];
+
+ public static final List<RuntimeCompletionVariable> EMPTY_LIST = Lists.newArrayList();
+
+ /**
+ * The name of the variable. The name "this" has a special meaning and is used as an implicit
+ * target for runtime completion, and in explicit "this" references.
+ */
+ private final String name;
+
+ /**
+ * The type of the variable.
+ */
+ private final RuntimeCompletionExpressionType type;
+
+ /**
+ * Constructor for {@link RuntimeCompletionVariable}.
+ */
+ public RuntimeCompletionVariable(String name, RuntimeCompletionExpressionType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof RuntimeCompletionVariable) {
+ RuntimeCompletionVariable other = (RuntimeCompletionVariable) obj;
+ return
+ ObjectUtilities.equals(other.name, name) &&
+ ObjectUtilities.equals(other.type, type);
+ }
+ return false;
+ }
+
+ public static RuntimeCompletionVariable fromJson(JsonObject jsonObject) {
+ String name = jsonObject.get("name").getAsString();
+ RuntimeCompletionExpressionType type = RuntimeCompletionExpressionType.fromJson(jsonObject.get("type").getAsJsonObject());
+ return new RuntimeCompletionVariable(name, type);
+ }
+
+ public static List<RuntimeCompletionVariable> fromJsonArray(JsonArray jsonArray) {
+ if (jsonArray == null) {
+ return EMPTY_LIST;
+ }
+ ArrayList<RuntimeCompletionVariable> list = new ArrayList<RuntimeCompletionVariable>(jsonArray.size());
+ Iterator<JsonElement> iterator = jsonArray.iterator();
+ while (iterator.hasNext()) {
+ list.add(fromJson(iterator.next().getAsJsonObject()));
+ }
+ return list;
+ }
+
+ /**
+ * The name of the variable. The name "this" has a special meaning and is used as an implicit
+ * target for runtime completion, and in explicit "this" references.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The type of the variable.
+ */
+ public RuntimeCompletionExpressionType getType() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder builder = new HashCodeBuilder();
+ builder.append(name);
+ builder.append(type);
+ return builder.toHashCode();
+ }
+
+ public JsonObject toJson() {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("name", name);
+ jsonObject.add("type", type.toJson());
+ return jsonObject;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ builder.append("name=");
+ builder.append(name + ", ");
+ builder.append("type=");
+ builder.append(type);
+ builder.append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 0d1c534..7e8bc43 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- <version>1.20.2</version>
+ <version>1.20.3</version>
</h1>
<p>
This document contains a specification of the API provided by the
@@ -2307,6 +2307,111 @@
</field>
</params>
</request>
+ <request method="getSuggestions">
+ <p>
+ Request completion suggestions for the given runtime context.
+ </p>
+ <p>
+ It might take one or two requests of this type to get completion
+ suggestions. The first request should have only "code", "offset",
+ and "variables", but not "expressions". If there are sub-expressions that
+ can have different runtime types, and are considered to be safe to
+ evaluate at runtime (e.g. getters), so using their actual runtime types
+ can improve completion results, the server will not include the
+ "suggestions" field in the response, and instead will return the
+ "expressions" field. The client will use debug API to get current runtime
+ types for these sub-expressions and send another request, this time with
+ "expressions". If there are no interesting sub-expressions to get
+ runtime types for, or when the "expressions" field is provided by the
+ client, the server will return "suggestions" in the response.
+ </p>
+ <params>
+ <field name="code">
+ <ref>String</ref>
+ <p>
+ The code to get suggestions in.
+ </p>
+ </field>
+ <field name="offset">
+ <ref>int</ref>
+ <p>
+ The offset within the code to get suggestions at.
+ </p>
+ </field>
+ <field name="contextFile">
+ <ref>FilePath</ref>
+ <p>
+ The path of the context file, e.g. the file of the current debugger
+ frame. The combination of the context file and context offset can
+ be used to ensure that all variables of the context are available
+ for completion (with their static types).
+ </p>
+ </field>
+ <field name="contextOffset">
+ <ref>int</ref>
+ <p>
+ The offset in the context file, e.g. the line offset in the current
+ debugger frame.
+ </p>
+ </field>
+ <field name="variables">
+ <list>
+ <ref>RuntimeCompletionVariable</ref>
+ </list>
+ <p>
+ The runtime context variables that are potentially referenced in the
+ code.
+ </p>
+ </field>
+ <field name="expressions" optional="true">
+ <list>
+ <ref>RuntimeCompletionExpression</ref>
+ </list>
+ <p>
+ The list of sub-expressions in the code for which the client wants
+ to provide runtime types. It does not have to be the full list of
+ expressions requested by the server, for missing expressions their
+ static types will be used.
+ </p>
+ <p>
+ When this field is omitted, the server will return completion
+ suggestions only when there are no interesting sub-expressions in the
+ given code. The client may provide an empty list, in this case the
+ server will return completion suggestions.
+ </p>
+ </field>
+ </params>
+ <result>
+ <field name="suggestions" optional="true">
+ <list>
+ <ref>CompletionSuggestion</ref>
+ </list>
+ <p>
+ The completion suggestions. In contrast to usual completion request,
+ suggestions for private elements also will be provided.
+ </p>
+ <p>
+ If there are sub-expressions that can have different runtime types,
+ and are considered to be safe to evaluate at runtime (e.g. getters),
+ so using their actual runtime types can improve completion results,
+ the server omits this field in the response, and instead will return
+ the "expressions" field.
+ </p>
+ </field>
+ <field name="expressions" optional="true">
+ <list>
+ <ref>RuntimeCompletionExpression</ref>
+ </list>
+ <p>
+ The list of sub-expressions in the code for which the server would
+ like to know runtime types to provide better completion suggestions.
+ </p>
+ <p>
+ This field is omitted the field "suggestions" is returned.
+ </p>
+ </field>
+ </result>
+ </request>
<request method="mapUri">
<p>
Map a URI from the execution context to the file that it corresponds
@@ -3075,6 +3180,132 @@
The identifier for a execution context.
</p>
</type>
+ <type name="RuntimeCompletionExpression">
+ <p>
+ An expression for which we want to know its runtime type.
+ In expressions like `a.b.c.where((e) => e.^)` we want to know the
+ runtime type of `a.b.c` to enforce it statically at the time when we
+ compute completion suggestions, and get better type for `e`.
+ </p>
+ <object>
+ <field name="offset">
+ <ref>int</ref>
+ <p>
+ The offset of the expression in the code for completion.
+ </p>
+ </field>
+ <field name="length">
+ <ref>int</ref>
+ <p>
+ The length of the expression in the code for completion.
+ </p>
+ </field>
+ <field name="type" optional="true">
+ <ref>RuntimeCompletionExpressionType</ref>
+ <p>
+ When the expression is sent from the server to the client, the
+ type is omitted. The client should fill the type when it sends the
+ request to the server again.
+ </p>
+ </field>
+ </object>
+ </type>
+ <type name="RuntimeCompletionVariable">
+ <p>
+ A variable in a runtime context.
+ </p>
+ <object>
+ <field name="name">
+ <ref>String</ref>
+ <p>
+ The name of the variable.
+ The name "this" has a special meaning and is used as an implicit
+ target for runtime completion, and in explicit "this" references.
+ </p>
+ </field>
+ <field name="type">
+ <ref>RuntimeCompletionExpressionType</ref>
+ <p>
+ The type of the variable.
+ </p>
+ </field>
+ </object>
+ </type>
+ <type name="RuntimeCompletionExpressionType">
+ <p>
+ A type at runtime.
+ </p>
+ <object>
+ <field name="libraryPath" optional="true">
+ <ref>FilePath</ref>
+ <p>
+ The path of the library that has this type.
+ Omitted if the type is not declared in any library, e.g. "dynamic",
+ or "void".
+ </p>
+ </field>
+ <field name="kind">
+ <ref>RuntimeCompletionExpressionTypeKind</ref>
+ <p>
+ The kind of the type.
+ </p>
+ </field>
+ <field name="name" optional="true">
+ <ref>String</ref>
+ <p>
+ The name of the type. Omitted if the type does not have a name, e.g.
+ an inline function type.
+ </p>
+ </field>
+ <field name="typeArguments" optional="true">
+ <list>
+ <ref>RuntimeCompletionExpressionType</ref>
+ </list>
+ <p>
+ The type arguments of the type.
+ Omitted if the type does not have type parameters.
+ </p>
+ </field>
+ <field name="returnType" optional="true">
+ <ref>RuntimeCompletionExpressionType</ref>
+ <p>
+ If the type is a function type, the return type of the function.
+ Omitted if the type is not a function type.
+ </p>
+ </field>
+ <field name="parameterTypes" optional="true">
+ <list>
+ <ref>RuntimeCompletionExpressionType</ref>
+ </list>
+ <p>
+ If the type is a function type, the types of the function parameters
+ of all kinds - required, optional positional, and optional named.
+ Omitted if the type is not a function type.
+ </p>
+ </field>
+ <field name="parameterNames" optional="true">
+ <list>
+ <ref>String</ref>
+ </list>
+ <p>
+ If the type is a function type, the names of the function parameters
+ of all kinds - required, optional positional, and optional named.
+ The names of positional parameters are empty strings.
+ Omitted if the type is not a function type.
+ </p>
+ </field>
+ </object>
+ </type>
+ <type name="RuntimeCompletionExpressionTypeKind">
+ <p>
+ An enumeration of the kinds of runtime expression types.
+ </p>
+ <enum>
+ <value><code>DYNAMIC</code></value>
+ <value><code>FUNCTION</code></value>
+ <value><code>INTERFACE</code></value>
+ </enum>
+ </type>
<type name="ExecutionService">
<p>
An enumeration of the services provided by the execution
diff --git a/pkg/analysis_server_client/test/analysis_server_client_test.dart b/pkg/analysis_server_client/test/analysis_server_client_test.dart
index 6ceabe2..baaf679 100644
--- a/pkg/analysis_server_client/test/analysis_server_client_test.dart
+++ b/pkg/analysis_server_client/test/analysis_server_client_test.dart
@@ -105,7 +105,7 @@
int get pid => null;
@override
- bool kill([ProcessSignal signal = ProcessSignal.SIGTERM]) => null;
+ bool kill([ProcessSignal signal = ProcessSignal.sigterm]) => null;
}
class MockStdin implements IOSink {
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index d25a9bb..8d9ed60 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,27 @@
+## 0.32.0
+
+* Allow annotations on enum constants.
+* Analyzer fully supports being run on the VM with --preview-dart-2.
+* Fix heap usage regression by not storing bytes in the file cache.
+* Add AnalysisSessionHelper.getTopLevelPropertyAccessor().
+* Don't infer types when there's an irreconcilable type mismatch (#32305)
+* Many fasta parser improvements.
+* Use @isTest and @isTestGroup to understand executable element as a
+ test/group. To use, add `@isTest` annotations (from package:meta)
+ to the methods in their package which define a test.
+```dart
+@isTest
+void myMagicTest(String name, FutureOr Function() body) {
+ test(name, body);
+}
+```
+ When subscribed to [notifications for outlines of a test file](https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blob/master/pkg/analysis_server/doc/api.html#notification_analysis.outline),
+ they will include elements for UNIT_TEST_GROUP and UNIT_TEST_TEST.
+* Improve guess for type name identifier. (#32765)
+* Fix LineInfo.getOffsetOfLineAfter().
+* Remove some flutter specific analysis code.
+* Fix resolution tests when run locally.
+
## 0.31.2-alpha.2
* Refactoring to make element model logic sharable with
diff --git a/pkg/analyzer/lib/dart/analysis/session.dart b/pkg/analyzer/lib/dart/analysis/session.dart
index a39a2f7..dd8c595 100644
--- a/pkg/analyzer/lib/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/dart/analysis/session.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -22,6 +23,11 @@
*/
abstract class AnalysisSession {
/**
+ * Return the [ResourceProvider] that is used to access the file system.
+ */
+ ResourceProvider get resourceProvider;
+
+ /**
* Return the source factory used to resolve URIs.
*/
SourceFactory get sourceFactory;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index b2743a7..5679752 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -320,7 +320,6 @@
ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION,
ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE,
ParserErrorCode.ABSTRACT_TYPEDEF,
- ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
ParserErrorCode.BREAK_OUTSIDE_OF_LOOP,
ParserErrorCode.CATCH_SYNTAX,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index f8b1648..bf98050 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -431,6 +431,11 @@
}
/**
+ * Return the [ResourceProvider] that is used to access the file system.
+ */
+ ResourceProvider get resourceProvider => _resourceProvider;
+
+ /**
* Return the [Stream] that produces [AnalysisResult]s for added files.
*
* Note that the stream supports only one single subscriber.
diff --git a/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart b/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
index f96c5c6..6962a80 100644
--- a/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
@@ -79,14 +79,16 @@
<kernel.TreeNode, AnalyzerMetadata>{};
@override
- AnalyzerMetadata readFromBinary(kernel.BinarySource source) {
+ AnalyzerMetadata readFromBinary(
+ kernel.Node node, kernel.BinarySource source) {
return new AnalyzerMetadata()
..constructorNameOffset = _readOffset(source)
..documentationComment = _readOptionalString(source);
}
@override
- void writeToBinary(AnalyzerMetadata metadata, kernel.BinarySink sink) {
+ void writeToBinary(
+ AnalyzerMetadata metadata, kernel.Node node, kernel.BinarySink sink) {
_writeOffset(sink, metadata.constructorNameOffset);
_writeOptionalString(sink, metadata.documentationComment);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 37ad32e..f627fa8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' as driver;
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -42,6 +43,9 @@
AnalysisSessionImpl(this._driver);
@override
+ ResourceProvider get resourceProvider => _driver.resourceProvider;
+
+ @override
SourceFactory get sourceFactory => _driver.sourceFactory;
@override
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 1ba6e80..b9ac011e 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -699,6 +699,15 @@
return null;
}
+ /**
+ * If this constant represents a library function or static method, returns
+ * it, otherwise returns `null`.
+ */
+ ExecutableElement toFunctionValue() {
+ InstanceState state = _state;
+ return state is FunctionState ? state._element : null;
+ }
+
@override
int toIntValue() {
InstanceState state = _state;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index f794006..ac0dd3e 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -46,11 +46,6 @@
'ABSTRACT_TYPEDEF', "Typedefs can't be declared to be 'abstract'.",
correction: "Try removing the keyword 'abstract'.");
- static const ParserErrorCode ANNOTATION_ON_ENUM_CONSTANT =
- const ParserErrorCode('ANNOTATION_ON_ENUM_CONSTANT',
- "Enum constants can't have annotations.",
- correction: "Try removing the annotation.");
-
/**
* 16.32 Identifier Reference: It is a compile-time error if any of the
* identifiers async, await, or yield is used as an identifier in a function
diff --git a/pkg/analyzer/lib/src/fasta/ast_body_builder.dart b/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
index c24180f1..e5e7442 100644
--- a/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
@@ -35,6 +35,11 @@
coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
@override
+ void enterThenForTypePromotion(Expression condition) {
+ // Do nothing.
+ }
+
+ @override
void printEvent(String name) {
// TODO(scheglov): Call of super is commented out to prevent spamming.
// super.printEvent(name);
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index b654900..052b7ba 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -45,6 +45,7 @@
messageMissingAssignableSelector,
messageNativeClauseShouldBeAnnotation,
messageStaticConstructor,
+ messageTypedefNotFunction,
templateDuplicateLabelInSwitchStatement,
templateExpectedType;
import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
@@ -173,6 +174,12 @@
}
@override
+ void handleParenthesizedCondition(Token leftParenthesis) {
+ // TODO(danrubel): Implement rather than forwarding.
+ handleParenthesizedExpression(leftParenthesis);
+ }
+
+ @override
void handleParenthesizedExpression(Token leftParenthesis) {
assert(optional('(', leftParenthesis));
debugEvent("ParenthesizedExpression");
@@ -2410,8 +2417,8 @@
List<Annotation> metadata = pop();
Comment comment = _findComment(metadata, typedefKeyword);
if (type is! GenericFunctionType) {
- // TODO(paulberry) Generate an error and recover (better than
- // this).
+ // This error is also reported in the OutlineBuilder.
+ handleRecoverableError(messageTypedefNotFunction, equals, equals);
type = null;
}
declarations.add(ast.genericTypeAlias(
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index 4382c12..52839a7 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -2,10 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart' hide Identifier;
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/ast_factory.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:front_end/src/fasta/kernel/body_builder.dart'
+ show Identifier, Operator;
import 'package:front_end/src/fasta/kernel/forest.dart';
import 'package:kernel/ast.dart' as kernel;
@@ -61,9 +63,12 @@
Expression asLiteralString(Expression value) => value;
@override
- Expression awaitExpression(Expression operand, Token awaitKeyword) {
- return astFactory.awaitExpression(awaitKeyword, operand);
- }
+ Expression awaitExpression(Expression operand, Token awaitKeyword) =>
+ astFactory.awaitExpression(awaitKeyword, operand);
+
+ @override
+ Block block(Token openBrace, List<Statement> statements, Token closeBrace) =>
+ astFactory.block(openBrace, statements, closeBrace);
@override
kernel.Arguments castArguments(_Arguments arguments) {
@@ -84,6 +89,25 @@
condition, question, thenExpression, colon, elseExpression);
@override
+ Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
+ ParenthesizedExpression condition, Token semicolon) =>
+ astFactory.doStatement(
+ doKeyword,
+ body,
+ whileKeyword,
+ condition.leftParenthesis,
+ condition.expression,
+ condition.rightParenthesis,
+ semicolon);
+
+ @override
+ Statement emptyStatement(Token semicolon) =>
+ astFactory.emptyStatement(semicolon);
+
+ Statement expressionStatement(Expression expression, Token semicolon) =>
+ astFactory.expressionStatement(expression, semicolon);
+
+ @override
kernel.DartType getTypeAt(TypeArgumentList typeArguments, int index) {
return null; // typeArguments.arguments[index].type.kernelType;
}
@@ -93,7 +117,26 @@
typeArguments.arguments.length;
@override
- bool isErroneousNode(covariant node) => false; // ???
+ Statement ifStatement(
+ Token ifKeyword,
+ ParenthesizedExpression condition,
+ Statement thenStatement,
+ Token elseKeyword,
+ Statement elseStatement) =>
+ astFactory.ifStatement(
+ ifKeyword,
+ condition.leftParenthesis,
+ condition.expression,
+ condition.rightParenthesis,
+ thenStatement,
+ elseKeyword,
+ elseStatement);
+
+ @override
+ bool isBlock(Object node) => node is Block;
+
+ @override
+ bool isErroneousNode(Object node) => false /* ??? */;
@override
Expression isExpression(Expression expression, Token isOperator,
@@ -101,6 +144,13 @@
astFactory.isExpression(expression, isOperator, notOperator, type);
@override
+ bool isThisExpression(Object node) => node is ThisExpression;
+
+ @override
+ bool isVariablesDeclaration(Object node) =>
+ node is VariableDeclarationStatement && node.variables != 1;
+
+ @override
Expression literalBool(bool value, Token location) =>
astFactory.booleanLiteral(location, value)
..staticType = _typeProvider?.boolType;
@@ -150,9 +200,24 @@
..staticType = _typeProvider?.stringType;
@override
- Expression literalSymbol(String value, Token location) {
- // TODO(brianwilkerson) Get the missing information.
- return astFactory.symbolLiteral(location, null /* components */)
+ Expression literalSymbolMultiple(
+ String value, Token hash, List<Identifier> components) =>
+ astFactory.symbolLiteral(
+ hash, components.map((identifier) => identifier.token).toList())
+ ..staticType = _typeProvider?.symbolType;
+
+ @override
+ Expression literalSymbolSingluar(String value, Token hash, Object component) {
+ Token token;
+ if (component is Identifier) {
+ token = component.token;
+ } else if (component is Operator) {
+ token = component.token;
+ } else {
+ throw new ArgumentError(
+ 'Unexpected class of component: ${component.runtimeType}');
+ }
+ return astFactory.symbolLiteral(hash, <Token>[token])
..staticType = _typeProvider?.symbolType;
}
@@ -182,16 +247,90 @@
..staticType = _typeProvider?.boolType;
@override
+ Object parenthesizedCondition(Token leftParenthesis, Expression expression,
+ Token rightParenthesis) =>
+ astFactory.parenthesizedExpression(
+ leftParenthesis, expression, rightParenthesis);
+
+ @override
int readOffset(AstNode node) => node.offset;
@override
+ void resolveBreak(Statement target, BreakStatement user) {
+ user.target = target;
+ }
+
+ @override
+ void resolveContinue(Statement target, ContinueStatement user) {
+ user.target = target;
+ }
+
+ @override
+ void resolveContinueInSwitch(SwitchStatement target, ContinueStatement user) {
+ user.target = target;
+ }
+
+ @override
+ Statement rethrowStatement(Token rethrowKeyword, Token semicolon) =>
+ astFactory.expressionStatement(
+ astFactory.rethrowExpression(rethrowKeyword), semicolon);
+
+ @override
+ Statement returnStatement(
+ Token returnKeyword, Expression expression, Token semicolon) =>
+ astFactory.returnStatement(returnKeyword, expression, semicolon);
+
+ @override
Expression stringConcatenationExpression(
List<Expression> strings, Token location) =>
- astFactory.adjacentStrings(strings);
+ astFactory.adjacentStrings(strings.cast<StringLiteral>());
+
+ @override
+ Statement syntheticLabeledStatement(Statement statement) => statement;
@override
Expression thisExpression(Token thisKeyword) =>
astFactory.thisExpression(thisKeyword);
+
+ @override
+ Expression throwExpression(Token throwKeyword, Expression expression) =>
+ astFactory.throwExpression(throwKeyword, expression);
+
+ @override
+ Statement tryStatement(
+ Token tryKeyword,
+ Statement body,
+ List<CatchClause> catchClauses,
+ Token finallyKeyword,
+ Statement finallyBlock) =>
+ astFactory.tryStatement(
+ tryKeyword, body, catchClauses, finallyKeyword, finallyBlock);
+
+ @override
+ VariableDeclarationStatement variablesDeclaration(
+ List<VariableDeclaration> declarations, Uri uri) {
+ // TODO(brianwilkerson) Implement this.
+ throw new UnimplementedError();
+ }
+
+ @override
+ NodeList<VariableDeclaration> variablesDeclarationExtractDeclarations(
+ VariableDeclarationStatement variablesDeclaration) =>
+ variablesDeclaration.variables.variables;
+
+ @override
+ Statement whileStatement(Token whileKeyword,
+ ParenthesizedExpression condition, Statement body) =>
+ astFactory.whileStatement(whileKeyword, condition.leftParenthesis,
+ condition.expression, condition.rightParenthesis, body);
+
+ @override
+ Statement wrapVariables(Statement statement) => statement;
+
+ @override
+ Statement yieldStatement(Token yieldKeyword, Token star,
+ Expression expression, Token semicolon) =>
+ astFactory.yieldStatement(yieldKeyword, star, expression, semicolon);
}
/// A data holder used to conform to the [Forest] API.
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 660a6b6..7207018 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -29,10 +29,6 @@
errorReporter?.reportErrorForOffset(
ParserErrorCode.ABSTRACT_CLASS_MEMBER, offset, length);
return;
- case "ANNOTATION_ON_ENUM_CONSTANT":
- errorReporter?.reportErrorForOffset(
- ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, offset, length);
- return;
case "ASYNC_FOR_IN_WRONG_CONTEXT":
errorReporter?.reportErrorForOffset(
CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT, offset, length);
@@ -353,6 +349,10 @@
errorReporter?.reportErrorForOffset(
StrongModeCode.INVALID_CAST_NEW_EXPR, offset, length);
return;
+ case "INVALID_GENERIC_FUNCTION_TYPE":
+ errorReporter?.reportErrorForOffset(
+ ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, offset, length);
+ return;
case "INVALID_METHOD_OVERRIDE":
errorReporter?.reportErrorForOffset(
StrongModeCode.INVALID_METHOD_OVERRIDE, offset, length);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index f13507a..86a305f 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -209,6 +209,24 @@
*/
ClassElementImpl _enclosingClass;
+ ClassElement get enclosingClass => _enclosingClass;
+
+ /**
+ * For consumers of error verification as a library, (currently just the
+ * angular plugin), expose a setter that can make the errors reported more
+ * accurate when dangling code snippets are being resolved from a class
+ * context. Note that this setter is very defensive for potential misuse; it
+ * should not be modified in the middle of visiting a tree and requires an
+ * analyzer-provided Impl instance to work.
+ */
+ set enclosingClass(ClassElement classElement) {
+ assert(classElement is ClassElementImpl);
+ assert(_enclosingClass == null);
+ assert(_enclosingEnum == null);
+ assert(_enclosingFunction == null);
+ _enclosingClass = classElement;
+ }
+
/**
* The enum containing the AST nodes being visited, or `null` if we are not
* in the scope of an enum.
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 8d228f3..a60c8ab 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -6824,10 +6824,6 @@
} else {
name = createSyntheticIdentifier();
}
- if (commentAndMetadata.hasMetadata) {
- _reportErrorForNode(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
- commentAndMetadata.metadata[0]);
- }
return astFactory.enumConstantDeclaration(
commentAndMetadata.comment, commentAndMetadata.metadata, name);
}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 503d7b1..185d6d3 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1304,7 +1304,7 @@
rhsType != null &&
!lhsType.isDynamic &&
!rhsType.isDynamic &&
- lhsType.isMoreSpecificThan(rhsType)) {
+ _typeSystem.isMoreSpecificThan(lhsType, rhsType)) {
_errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node);
return true;
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 9e72153..03cdb82 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,20 +1,20 @@
name: analyzer
-version: 0.31.2-alpha.2
+version: 0.32.0
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
environment:
- sdk: '>=2.0.0-dev <2.0.0'
+ sdk: '>=2.0.0-dev.48.0 <2.0.0'
dependencies:
args: '>=0.12.1 <2.0.0'
charcode: ^1.1.0
collection: ^1.10.1
convert: ^2.0.0
crypto: '>=1.1.1 <3.0.0'
- front_end: 0.1.0-alpha.12
+ front_end: 0.1.0
glob: ^1.0.3
html: '>=0.12.0 <1.14.0'
- kernel: 0.3.0-alpha.12
+ kernel: 0.3.0
meta: ^1.0.2
package_config: '>=0.1.5 <2.0.0'
path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index 6ba10ce..d418538 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -1094,6 +1094,35 @@
verify([source]);
}
+ test_unnecessaryCast_function() async {
+ Source source = addSource(r'''
+void main() {
+ Function(Null) f = (String x) => x;
+ (f as Function(int))(3);
+}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ test_unnecessaryCast_function2() async {
+ Source source = addSource(r'''
+class A {}
+
+class B<T extends A> {
+ void foo() {
+ T Function(T) f;
+ A Function(A) g;
+ g = f as A Function(A);
+ }
+}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_unnecessaryCast_generics() async {
// dartbug.com/18953
Source source = addSource(r'''
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 5103eca..e634c00 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -488,70 +488,6 @@
// Expected 1 errors of type ParserErrorCode.MISSING_FUNCTION_PARAMETERS, found 0
super.test_missingFunctionParameters_topLevel_void_expression();
}
-
- @override
- @failingTest
- void test_unexpectedToken_endOfFieldDeclarationStatement() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.UNEXPECTED_TOKEN, found 0
- super.test_unexpectedToken_endOfFieldDeclarationStatement();
- }
-
- @override
-// @failingTest
- void test_voidVariable_parseClassMember_initializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_parseClassMember_initializer();
- }
-
- @override
-// @failingTest
- void test_voidVariable_parseClassMember_noInitializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_parseClassMember_noInitializer();
- }
-
- @override
-// @failingTest
- void test_voidVariable_parseCompilationUnit_initializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_parseCompilationUnit_initializer();
- }
-
- @override
-// @failingTest
- void test_voidVariable_parseCompilationUnit_noInitializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_parseCompilationUnit_noInitializer();
- }
-
- @override
-// @failingTest
- void test_voidVariable_parseCompilationUnitMember_initializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_parseCompilationUnitMember_initializer();
- }
-
- @override
-// @failingTest
- void test_voidVariable_parseCompilationUnitMember_noInitializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_parseCompilationUnitMember_noInitializer();
- }
-
- @override
-// @failingTest
- void test_voidVariable_statement_initializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_statement_initializer();
- }
-
- @override
-// @failingTest
- void test_voidVariable_statement_noInitializer() {
- // TODO(brianwilkerson) Passes, but ought to fail.
- super.test_voidVariable_statement_noInitializer();
- }
}
/**
@@ -636,11 +572,8 @@
}
@override
- @failingTest
void test_parseInstanceCreationExpression_type_named_typeArgumentComments() {
- // TODO(brianwilkerson) Does not inject generic type arguments.
- super
- .test_parseInstanceCreationExpression_type_named_typeArgumentComments();
+ // Ignored: Fasta does not support the generic comment syntax.
}
@override
diff --git a/pkg/analyzer/test/generated/parser_forest_test.dart b/pkg/analyzer/test/generated/parser_forest_test.dart
index 5c22fec..425b0a0 100644
--- a/pkg/analyzer/test/generated/parser_forest_test.dart
+++ b/pkg/analyzer/test/generated/parser_forest_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../src/fasta/body_builder_test_helper.dart';
@@ -9,23 +10,2523 @@
main() async {
defineReflectiveSuite(() {
- // TODO(brianwilkerson) Implement the remaining parser tests.
-// defineReflectiveTests(ClassMemberParserTest_Forest);
-// defineReflectiveTests(ComplexParserTest_Forest);
-// defineReflectiveTests(ErrorParserTest_Forest);
+ defineReflectiveTests(ClassMemberParserTest_Forest);
+ defineReflectiveTests(ComplexParserTest_Forest);
+ defineReflectiveTests(ErrorParserTest_Forest);
defineReflectiveTests(ExpressionParserTest_Forest);
-// defineReflectiveTests(FormalParameterParserTest_Forest);
-// defineReflectiveTests(NonErrorParserTest_Forest);
-// defineReflectiveTests(RecoveryParserTest_Forest);
-// defineReflectiveTests(SimpleParserTest_Forest);
+ defineReflectiveTests(FormalParameterParserTest_Forest);
+ defineReflectiveTests(RecoveryParserTest_Forest);
+ defineReflectiveTests(SimpleParserTest_Forest);
defineReflectiveTests(StatementParserTest_Forest);
defineReflectiveTests(TopLevelParserTest_Forest);
});
}
-/**
- * Tests of the fasta parser based on [ExpressionParserTestMixin].
- */
+@reflectiveTest
+class ClassMemberParserTest_Forest extends FastaBodyBuilderTestCase
+ with ClassMemberParserTestMixin {
+ ClassMemberParserTest_Forest() : super(false);
+
+ @failingTest
+ void test_parseAwaitExpression_asStatement_inAsync() {
+ super.test_parseAwaitExpression_asStatement_inAsync();
+ }
+
+ @failingTest
+ void test_parseAwaitExpression_asStatement_inSync() {
+ super.test_parseAwaitExpression_asStatement_inSync();
+ }
+
+ @failingTest
+ void test_parseAwaitExpression_inSync() {
+ super.test_parseAwaitExpression_inSync();
+ }
+
+ @failingTest
+ void test_parseClassMember_constructor_withDocComment() {
+ super.test_parseClassMember_constructor_withDocComment();
+ }
+
+ @failingTest
+ void test_parseClassMember_constructor_withInitializers() {
+ super.test_parseClassMember_constructor_withInitializers();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_covariant() {
+ super.test_parseClassMember_field_covariant();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_generic() {
+ super.test_parseClassMember_field_generic();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_gftType_gftReturnType() {
+ super.test_parseClassMember_field_gftType_gftReturnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_gftType_noReturnType() {
+ super.test_parseClassMember_field_gftType_noReturnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_instance_prefixedType() {
+ super.test_parseClassMember_field_instance_prefixedType();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_namedGet() {
+ super.test_parseClassMember_field_namedGet();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_namedOperator() {
+ super.test_parseClassMember_field_namedOperator();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_namedOperator_withAssignment() {
+ super.test_parseClassMember_field_namedOperator_withAssignment();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_namedSet() {
+ super.test_parseClassMember_field_namedSet();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_nameKeyword() {
+ super.test_parseClassMember_field_nameKeyword();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_nameMissing() {
+ super.test_parseClassMember_field_nameMissing();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_nameMissing2() {
+ super.test_parseClassMember_field_nameMissing2();
+ }
+
+ @failingTest
+ void test_parseClassMember_field_static() {
+ super.test_parseClassMember_field_static();
+ }
+
+ @failingTest
+ void test_parseClassMember_getter_functionType() {
+ super.test_parseClassMember_getter_functionType();
+ }
+
+ @failingTest
+ void test_parseClassMember_getter_void() {
+ super.test_parseClassMember_getter_void();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_external() {
+ super.test_parseClassMember_method_external();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_external_withTypeAndArgs() {
+ super.test_parseClassMember_method_external_withTypeAndArgs();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_comment_noReturnType() {
+ super.test_parseClassMember_method_generic_comment_noReturnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_comment_parameterType() {
+ super.test_parseClassMember_method_generic_comment_parameterType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_comment_returnType() {
+ super.test_parseClassMember_method_generic_comment_returnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_comment_returnType_bound() {
+ super.test_parseClassMember_method_generic_comment_returnType_bound();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_comment_returnType_complex() {
+ super.test_parseClassMember_method_generic_comment_returnType_complex();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_comment_void() {
+ super.test_parseClassMember_method_generic_comment_void();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_noReturnType() {
+ super.test_parseClassMember_method_generic_noReturnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_parameterType() {
+ super.test_parseClassMember_method_generic_parameterType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_returnType() {
+ super.test_parseClassMember_method_generic_returnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_returnType_bound() {
+ super.test_parseClassMember_method_generic_returnType_bound();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_returnType_complex() {
+ super.test_parseClassMember_method_generic_returnType_complex();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_returnType_static() {
+ super.test_parseClassMember_method_generic_returnType_static();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_generic_void() {
+ super.test_parseClassMember_method_generic_void();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_get_noType() {
+ super.test_parseClassMember_method_get_noType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_get_type() {
+ super.test_parseClassMember_method_get_type();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_get_void() {
+ super.test_parseClassMember_method_get_void();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_gftReturnType_noReturnType() {
+ super.test_parseClassMember_method_gftReturnType_noReturnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_gftReturnType_voidReturnType() {
+ super.test_parseClassMember_method_gftReturnType_voidReturnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_native_allowed() {
+ super.test_parseClassMember_method_native_allowed();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_native_missing_literal_allowed() {
+ super.test_parseClassMember_method_native_missing_literal_allowed();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_native_missing_literal_not_allowed() {
+ super.test_parseClassMember_method_native_missing_literal_not_allowed();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_native_not_allowed() {
+ super.test_parseClassMember_method_native_not_allowed();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_native_with_body_allowed() {
+ super.test_parseClassMember_method_native_with_body_allowed();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_native_with_body_not_allowed() {
+ super.test_parseClassMember_method_native_with_body_not_allowed();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_operator_noType() {
+ super.test_parseClassMember_method_operator_noType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_operator_type() {
+ super.test_parseClassMember_method_operator_type();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_operator_void() {
+ super.test_parseClassMember_method_operator_void();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_returnType_functionType() {
+ super.test_parseClassMember_method_returnType_functionType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_returnType_parameterized() {
+ super.test_parseClassMember_method_returnType_parameterized();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_set_noType() {
+ super.test_parseClassMember_method_set_noType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_set_type() {
+ super.test_parseClassMember_method_set_type();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_set_void() {
+ super.test_parseClassMember_method_set_void();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_static_generic_comment_returnType() {
+ super.test_parseClassMember_method_static_generic_comment_returnType();
+ }
+
+ @failingTest
+ void test_parseClassMember_method_trailing_commas() {
+ super.test_parseClassMember_method_trailing_commas();
+ }
+
+ @failingTest
+ void test_parseClassMember_operator_functionType() {
+ super.test_parseClassMember_operator_functionType();
+ }
+
+ @failingTest
+ void test_parseClassMember_operator_index() {
+ super.test_parseClassMember_operator_index();
+ }
+
+ @failingTest
+ void test_parseClassMember_operator_indexAssign() {
+ super.test_parseClassMember_operator_indexAssign();
+ }
+
+ @failingTest
+ void test_parseClassMember_operator_lessThan() {
+ super.test_parseClassMember_operator_lessThan();
+ }
+
+ @failingTest
+ void test_parseClassMember_redirectingFactory_const() {
+ super.test_parseClassMember_redirectingFactory_const();
+ }
+
+ @failingTest
+ void test_parseClassMember_redirectingFactory_expressionBody() {
+ super.test_parseClassMember_redirectingFactory_expressionBody();
+ }
+
+ @failingTest
+ void test_parseClassMember_redirectingFactory_nonConst() {
+ super.test_parseClassMember_redirectingFactory_nonConst();
+ }
+
+ @failingTest
+ void test_parseConstructor_assert() {
+ super.test_parseConstructor_assert();
+ }
+
+ @failingTest
+ void test_parseConstructor_factory_const_external() {
+ super.test_parseConstructor_factory_const_external();
+ }
+
+ @failingTest
+ void test_parseConstructor_factory_named() {
+ super.test_parseConstructor_factory_named();
+ }
+
+ @failingTest
+ void test_parseConstructor_initializers_field() {
+ super.test_parseConstructor_initializers_field();
+ }
+
+ @failingTest
+ void test_parseConstructor_named() {
+ super.test_parseConstructor_named();
+ }
+
+ @failingTest
+ void test_parseConstructor_unnamed() {
+ super.test_parseConstructor_unnamed();
+ }
+
+ @failingTest
+ void test_parseConstructor_with_pseudo_function_literal() {
+ super.test_parseConstructor_with_pseudo_function_literal();
+ }
+
+ @failingTest
+ void test_parseConstructorFieldInitializer_qualified() {
+ super.test_parseConstructorFieldInitializer_qualified();
+ }
+
+ @failingTest
+ void test_parseConstructorFieldInitializer_unqualified() {
+ super.test_parseConstructorFieldInitializer_unqualified();
+ }
+
+ @failingTest
+ void test_parseGetter_nonStatic() {
+ super.test_parseGetter_nonStatic();
+ }
+
+ @failingTest
+ void test_parseGetter_static() {
+ super.test_parseGetter_static();
+ }
+
+ @failingTest
+ void test_parseInitializedIdentifierList_type() {
+ super.test_parseInitializedIdentifierList_type();
+ }
+
+ @failingTest
+ void test_parseInitializedIdentifierList_var() {
+ super.test_parseInitializedIdentifierList_var();
+ }
+
+ @failingTest
+ void test_parseOperator() {
+ super.test_parseOperator();
+ }
+
+ @failingTest
+ void test_parseSetter_nonStatic() {
+ super.test_parseSetter_nonStatic();
+ }
+
+ @failingTest
+ void test_parseSetter_static() {
+ super.test_parseSetter_static();
+ }
+
+ @failingTest
+ void test_simpleFormalParameter_withDocComment() {
+ super.test_simpleFormalParameter_withDocComment();
+ }
+}
+
+@reflectiveTest
+class ComplexParserTest_Forest extends FastaBodyBuilderTestCase
+ with ComplexParserTestMixin {
+ ComplexParserTest_Forest() : super(false);
+
+ @failingTest
+ void test_additiveExpression_normal() {
+ super.test_additiveExpression_normal();
+ }
+
+ @failingTest
+ void test_additiveExpression_noSpaces() {
+ super.test_additiveExpression_noSpaces();
+ }
+
+ @failingTest
+ void test_additiveExpression_precedence_multiplicative_left() {
+ super.test_additiveExpression_precedence_multiplicative_left();
+ }
+
+ @failingTest
+ void test_additiveExpression_precedence_multiplicative_left_withSuper() {
+ super.test_additiveExpression_precedence_multiplicative_left_withSuper();
+ }
+
+ @failingTest
+ void test_additiveExpression_precedence_multiplicative_right() {
+ super.test_additiveExpression_precedence_multiplicative_right();
+ }
+
+ @failingTest
+ void test_additiveExpression_super() {
+ super.test_additiveExpression_super();
+ }
+
+ @failingTest
+ void test_assignableExpression_arguments_normal_chain() {
+ super.test_assignableExpression_arguments_normal_chain();
+ }
+
+ @failingTest
+ void test_assignableExpression_arguments_normal_chain_typeArgumentComments() {
+ super
+ .test_assignableExpression_arguments_normal_chain_typeArgumentComments();
+ }
+
+ @failingTest
+ void test_assignableExpression_arguments_normal_chain_typeArguments() {
+ super.test_assignableExpression_arguments_normal_chain_typeArguments();
+ }
+
+ @failingTest
+ void test_assignmentExpression_compound() {
+ super.test_assignmentExpression_compound();
+ }
+
+ @failingTest
+ void test_assignmentExpression_indexExpression() {
+ super.test_assignmentExpression_indexExpression();
+ }
+
+ @failingTest
+ void test_assignmentExpression_prefixedIdentifier() {
+ super.test_assignmentExpression_prefixedIdentifier();
+ }
+
+ @failingTest
+ void test_assignmentExpression_propertyAccess() {
+ super.test_assignmentExpression_propertyAccess();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_normal() {
+ super.test_bitwiseAndExpression_normal();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_precedence_equality_left() {
+ super.test_bitwiseAndExpression_precedence_equality_left();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_precedence_equality_right() {
+ super.test_bitwiseAndExpression_precedence_equality_right();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_super() {
+ super.test_bitwiseAndExpression_super();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_normal() {
+ super.test_bitwiseOrExpression_normal();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_precedence_xor_left() {
+ super.test_bitwiseOrExpression_precedence_xor_left();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_precedence_xor_right() {
+ super.test_bitwiseOrExpression_precedence_xor_right();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_super() {
+ super.test_bitwiseOrExpression_super();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_normal() {
+ super.test_bitwiseXorExpression_normal();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_precedence_and_left() {
+ super.test_bitwiseXorExpression_precedence_and_left();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_precedence_and_right() {
+ super.test_bitwiseXorExpression_precedence_and_right();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_super() {
+ super.test_bitwiseXorExpression_super();
+ }
+
+ @failingTest
+ void test_cascade_withAssignment() {
+ super.test_cascade_withAssignment();
+ }
+
+ @failingTest
+ void test_conditionalExpression_precedence_ifNullExpression() {
+ super.test_conditionalExpression_precedence_ifNullExpression();
+ }
+
+ @failingTest
+ void test_conditionalExpression_precedence_logicalOrExpression() {
+ super.test_conditionalExpression_precedence_logicalOrExpression();
+ }
+
+ @failingTest
+ void test_conditionalExpression_precedence_nullableType_as() {
+ super.test_conditionalExpression_precedence_nullableType_as();
+ }
+
+ @failingTest
+ void test_conditionalExpression_precedence_nullableType_is() {
+ super.test_conditionalExpression_precedence_nullableType_is();
+ }
+
+ @failingTest
+ void test_constructor_initializer_withParenthesizedExpression() {
+ super.test_constructor_initializer_withParenthesizedExpression();
+ }
+
+ @failingTest
+ void test_equalityExpression_normal() {
+ super.test_equalityExpression_normal();
+ }
+
+ @failingTest
+ void test_equalityExpression_precedence_relational_left() {
+ super.test_equalityExpression_precedence_relational_left();
+ }
+
+ @failingTest
+ void test_equalityExpression_precedence_relational_right() {
+ super.test_equalityExpression_precedence_relational_right();
+ }
+
+ @failingTest
+ void test_equalityExpression_super() {
+ super.test_equalityExpression_super();
+ }
+
+ @failingTest
+ void test_ifNullExpression() {
+ super.test_ifNullExpression();
+ }
+
+ @failingTest
+ void test_ifNullExpression_precedence_logicalOr_left() {
+ super.test_ifNullExpression_precedence_logicalOr_left();
+ }
+
+ @failingTest
+ void test_ifNullExpression_precedence_logicalOr_right() {
+ super.test_ifNullExpression_precedence_logicalOr_right();
+ }
+
+ @failingTest
+ void test_logicalAndExpression() {
+ super.test_logicalAndExpression();
+ }
+
+ @failingTest
+ void test_logicalAndExpression_precedence_bitwiseOr_left() {
+ super.test_logicalAndExpression_precedence_bitwiseOr_left();
+ }
+
+ @failingTest
+ void test_logicalAndExpression_precedence_bitwiseOr_right() {
+ super.test_logicalAndExpression_precedence_bitwiseOr_right();
+ }
+
+ @failingTest
+ void test_logicalAndExpressionStatement() {
+ super.test_logicalAndExpressionStatement();
+ }
+
+ @failingTest
+ void test_logicalOrExpression() {
+ super.test_logicalOrExpression();
+ }
+
+ @failingTest
+ void test_logicalOrExpression_precedence_logicalAnd_left() {
+ super.test_logicalOrExpression_precedence_logicalAnd_left();
+ }
+
+ @failingTest
+ void test_logicalOrExpression_precedence_logicalAnd_right() {
+ super.test_logicalOrExpression_precedence_logicalAnd_right();
+ }
+
+ @failingTest
+ void test_methodInvocation1() {
+ super.test_methodInvocation1();
+ }
+
+ @failingTest
+ void test_methodInvocation2() {
+ super.test_methodInvocation2();
+ }
+
+ @failingTest
+ void test_methodInvocation3() {
+ super.test_methodInvocation3();
+ }
+
+ @failingTest
+ void test_multipleLabels_statement() {
+ super.test_multipleLabels_statement();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_normal() {
+ super.test_multiplicativeExpression_normal();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_precedence_unary_left() {
+ super.test_multiplicativeExpression_precedence_unary_left();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_precedence_unary_right() {
+ super.test_multiplicativeExpression_precedence_unary_right();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_super() {
+ super.test_multiplicativeExpression_super();
+ }
+
+ @failingTest
+ void test_relationalExpression_precedence_shift_right() {
+ super.test_relationalExpression_precedence_shift_right();
+ }
+
+ @failingTest
+ void test_shiftExpression_normal() {
+ super.test_shiftExpression_normal();
+ }
+
+ @failingTest
+ void test_shiftExpression_precedence_additive_left() {
+ super.test_shiftExpression_precedence_additive_left();
+ }
+
+ @failingTest
+ void test_shiftExpression_precedence_additive_right() {
+ super.test_shiftExpression_precedence_additive_right();
+ }
+
+ @failingTest
+ void test_shiftExpression_super() {
+ super.test_shiftExpression_super();
+ }
+
+ @failingTest
+ void test_topLevelFunction_nestedGenericFunction() {
+ super.test_topLevelFunction_nestedGenericFunction();
+ }
+}
+
+@reflectiveTest
+class ErrorParserTest_Forest extends FastaBodyBuilderTestCase
+ with ErrorParserTestMixin {
+ ErrorParserTest_Forest() : super(false);
+
+ @failingTest
+ void test_abstractClassMember_constructor() {
+ super.test_abstractClassMember_constructor();
+ }
+
+ @failingTest
+ void test_abstractClassMember_field() {
+ super.test_abstractClassMember_field();
+ }
+
+ @failingTest
+ void test_abstractClassMember_getter() {
+ super.test_abstractClassMember_getter();
+ }
+
+ @failingTest
+ void test_abstractClassMember_method() {
+ super.test_abstractClassMember_method();
+ }
+
+ @failingTest
+ void test_abstractClassMember_setter() {
+ super.test_abstractClassMember_setter();
+ }
+
+ @failingTest
+ void test_abstractEnum() {
+ super.test_abstractEnum();
+ }
+
+ @failingTest
+ void test_abstractTopLevelFunction_function() {
+ super.test_abstractTopLevelFunction_function();
+ }
+
+ @failingTest
+ void test_abstractTopLevelFunction_getter() {
+ super.test_abstractTopLevelFunction_getter();
+ }
+
+ @failingTest
+ void test_abstractTopLevelFunction_setter() {
+ super.test_abstractTopLevelFunction_setter();
+ }
+
+ @failingTest
+ void test_abstractTopLevelVariable() {
+ super.test_abstractTopLevelVariable();
+ }
+
+ @failingTest
+ void test_abstractTypeDef() {
+ super.test_abstractTypeDef();
+ }
+
+ @failingTest
+ void test_breakOutsideOfLoop_breakInDoStatement() {
+ super.test_breakOutsideOfLoop_breakInDoStatement();
+ }
+
+ @failingTest
+ void test_breakOutsideOfLoop_breakInForStatement() {
+ super.test_breakOutsideOfLoop_breakInForStatement();
+ }
+
+ @failingTest
+ void test_breakOutsideOfLoop_breakInIfStatement() {
+ super.test_breakOutsideOfLoop_breakInIfStatement();
+ }
+
+ @failingTest
+ void test_breakOutsideOfLoop_breakInSwitchStatement() {
+ super.test_breakOutsideOfLoop_breakInSwitchStatement();
+ }
+
+ @failingTest
+ void test_breakOutsideOfLoop_breakInWhileStatement() {
+ super.test_breakOutsideOfLoop_breakInWhileStatement();
+ }
+
+ @failingTest
+ void test_breakOutsideOfLoop_functionExpression_inALoop() {
+ super.test_breakOutsideOfLoop_functionExpression_inALoop();
+ }
+
+ @failingTest
+ void test_breakOutsideOfLoop_functionExpression_withALoop() {
+ super.test_breakOutsideOfLoop_functionExpression_withALoop();
+ }
+
+ @failingTest
+ void test_classInClass_abstract() {
+ super.test_classInClass_abstract();
+ }
+
+ @failingTest
+ void test_classInClass_nonAbstract() {
+ super.test_classInClass_nonAbstract();
+ }
+
+ @failingTest
+ void test_classTypeAlias_abstractAfterEq() {
+ super.test_classTypeAlias_abstractAfterEq();
+ }
+
+ @failingTest
+ void test_colonInPlaceOfIn() {
+ super.test_colonInPlaceOfIn();
+ }
+
+ @failingTest
+ void test_constAndCovariant() {
+ super.test_constAndCovariant();
+ }
+
+ @failingTest
+ void test_constAndFinal() {
+ super.test_constAndFinal();
+ }
+
+ @failingTest
+ void test_constAndVar() {
+ super.test_constAndVar();
+ }
+
+ @failingTest
+ void test_constClass() {
+ super.test_constClass();
+ }
+
+ @failingTest
+ void test_constConstructorWithBody() {
+ super.test_constConstructorWithBody();
+ }
+
+ @failingTest
+ void test_constEnum() {
+ super.test_constEnum();
+ }
+
+ @failingTest
+ void test_constFactory() {
+ super.test_constFactory();
+ }
+
+ @failingTest
+ void test_constMethod() {
+ super.test_constMethod();
+ }
+
+ @failingTest
+ void test_constructorPartial() {
+ super.test_constructorPartial();
+ }
+
+ @failingTest
+ void test_constructorWithReturnType() {
+ super.test_constructorWithReturnType();
+ }
+
+ @failingTest
+ void test_constructorWithReturnType_var() {
+ super.test_constructorWithReturnType_var();
+ }
+
+ @failingTest
+ void test_constTypedef() {
+ super.test_constTypedef();
+ }
+
+ @failingTest
+ void test_continueOutsideOfLoop_continueInDoStatement() {
+ super.test_continueOutsideOfLoop_continueInDoStatement();
+ }
+
+ @failingTest
+ void test_continueOutsideOfLoop_continueInForStatement() {
+ super.test_continueOutsideOfLoop_continueInForStatement();
+ }
+
+ @failingTest
+ void test_continueOutsideOfLoop_continueInIfStatement() {
+ super.test_continueOutsideOfLoop_continueInIfStatement();
+ }
+
+ @failingTest
+ void test_continueOutsideOfLoop_continueInSwitchStatement() {
+ super.test_continueOutsideOfLoop_continueInSwitchStatement();
+ }
+
+ @failingTest
+ void test_continueOutsideOfLoop_continueInWhileStatement() {
+ super.test_continueOutsideOfLoop_continueInWhileStatement();
+ }
+
+ @failingTest
+ void test_continueOutsideOfLoop_functionExpression_inALoop() {
+ super.test_continueOutsideOfLoop_functionExpression_inALoop();
+ }
+
+ @failingTest
+ void test_continueOutsideOfLoop_functionExpression_withALoop() {
+ super.test_continueOutsideOfLoop_functionExpression_withALoop();
+ }
+
+ @failingTest
+ void test_continueWithoutLabelInCase_error() {
+ super.test_continueWithoutLabelInCase_error();
+ }
+
+ @failingTest
+ void test_continueWithoutLabelInCase_noError() {
+ super.test_continueWithoutLabelInCase_noError();
+ }
+
+ @failingTest
+ void test_continueWithoutLabelInCase_noError_switchInLoop() {
+ super.test_continueWithoutLabelInCase_noError_switchInLoop();
+ }
+
+ @failingTest
+ void test_covariantAfterVar() {
+ super.test_covariantAfterVar();
+ }
+
+ @failingTest
+ void test_covariantAndFinal() {
+ super.test_covariantAndFinal();
+ }
+
+ @failingTest
+ void test_covariantAndStatic() {
+ super.test_covariantAndStatic();
+ }
+
+ @failingTest
+ void test_covariantAndType_local() {
+ super.test_covariantAndType_local();
+ }
+
+ @failingTest
+ void test_covariantConstructor() {
+ super.test_covariantConstructor();
+ }
+
+ @failingTest
+ void test_covariantMember_getter_noReturnType() {
+ super.test_covariantMember_getter_noReturnType();
+ }
+
+ @failingTest
+ void test_covariantMember_getter_returnType() {
+ super.test_covariantMember_getter_returnType();
+ }
+
+ @failingTest
+ void test_covariantMember_method() {
+ super.test_covariantMember_method();
+ }
+
+ @failingTest
+ void test_covariantTopLevelDeclaration_class() {
+ super.test_covariantTopLevelDeclaration_class();
+ }
+
+ @failingTest
+ void test_covariantTopLevelDeclaration_enum() {
+ super.test_covariantTopLevelDeclaration_enum();
+ }
+
+ @failingTest
+ void test_covariantTopLevelDeclaration_typedef() {
+ super.test_covariantTopLevelDeclaration_typedef();
+ }
+
+ @failingTest
+ void test_defaultValueInFunctionType_named_colon() {
+ super.test_defaultValueInFunctionType_named_colon();
+ }
+
+ @failingTest
+ void test_defaultValueInFunctionType_named_equal() {
+ super.test_defaultValueInFunctionType_named_equal();
+ }
+
+ @failingTest
+ void test_defaultValueInFunctionType_positional() {
+ super.test_defaultValueInFunctionType_positional();
+ }
+
+ @failingTest
+ void test_directiveAfterDeclaration_classBeforeDirective() {
+ super.test_directiveAfterDeclaration_classBeforeDirective();
+ }
+
+ @failingTest
+ void test_directiveAfterDeclaration_classBetweenDirectives() {
+ super.test_directiveAfterDeclaration_classBetweenDirectives();
+ }
+
+ @failingTest
+ void test_duplicatedModifier_const() {
+ super.test_duplicatedModifier_const();
+ }
+
+ @failingTest
+ void test_duplicatedModifier_external() {
+ super.test_duplicatedModifier_external();
+ }
+
+ @failingTest
+ void test_duplicatedModifier_factory() {
+ super.test_duplicatedModifier_factory();
+ }
+
+ @failingTest
+ void test_duplicatedModifier_final() {
+ super.test_duplicatedModifier_final();
+ }
+
+ @failingTest
+ void test_duplicatedModifier_static() {
+ super.test_duplicatedModifier_static();
+ }
+
+ @failingTest
+ void test_duplicatedModifier_var() {
+ super.test_duplicatedModifier_var();
+ }
+
+ @failingTest
+ void test_duplicateLabelInSwitchStatement() {
+ super.test_duplicateLabelInSwitchStatement();
+ }
+
+ @failingTest
+ void test_emptyEnumBody() {
+ super.test_emptyEnumBody();
+ }
+
+ @failingTest
+ void test_enumInClass() {
+ super.test_enumInClass();
+ }
+
+ @failingTest
+ void test_equalityCannotBeEqualityOperand_eq_eq() {
+ super.test_equalityCannotBeEqualityOperand_eq_eq();
+ }
+
+ @failingTest
+ void test_equalityCannotBeEqualityOperand_eq_neq() {
+ super.test_equalityCannotBeEqualityOperand_eq_neq();
+ }
+
+ @failingTest
+ void test_equalityCannotBeEqualityOperand_neq_eq() {
+ super.test_equalityCannotBeEqualityOperand_neq_eq();
+ }
+
+ @failingTest
+ void test_expectedCaseOrDefault() {
+ super.test_expectedCaseOrDefault();
+ }
+
+ @failingTest
+ void test_expectedClassMember_inClass_afterType() {
+ super.test_expectedClassMember_inClass_afterType();
+ }
+
+ @failingTest
+ void test_expectedClassMember_inClass_beforeType() {
+ super.test_expectedClassMember_inClass_beforeType();
+ }
+
+ @failingTest
+ void test_expectedExecutable_afterAnnotation_atEOF() {
+ super.test_expectedExecutable_afterAnnotation_atEOF();
+ }
+
+ @failingTest
+ void test_expectedExecutable_inClass_afterVoid() {
+ super.test_expectedExecutable_inClass_afterVoid();
+ }
+
+ @failingTest
+ void test_expectedExecutable_topLevel_afterType() {
+ super.test_expectedExecutable_topLevel_afterType();
+ }
+
+ @failingTest
+ void test_expectedExecutable_topLevel_afterVoid() {
+ super.test_expectedExecutable_topLevel_afterVoid();
+ }
+
+ @failingTest
+ void test_expectedExecutable_topLevel_beforeType() {
+ super.test_expectedExecutable_topLevel_beforeType();
+ }
+
+ @failingTest
+ void test_expectedExecutable_topLevel_eof() {
+ super.test_expectedExecutable_topLevel_eof();
+ }
+
+ @failingTest
+ void test_expectedInterpolationIdentifier() {
+ super.test_expectedInterpolationIdentifier();
+ }
+
+ @failingTest
+ void test_expectedInterpolationIdentifier_emptyString() {
+ super.test_expectedInterpolationIdentifier_emptyString();
+ }
+
+ @failingTest
+ void test_expectedListOrMapLiteral() {
+ super.test_expectedListOrMapLiteral();
+ }
+
+ @failingTest
+ void test_expectedStringLiteral() {
+ super.test_expectedStringLiteral();
+ }
+
+ @failingTest
+ void test_expectedToken_commaMissingInArgumentList() {
+ super.test_expectedToken_commaMissingInArgumentList();
+ }
+
+ @failingTest
+ void test_expectedToken_parseStatement_afterVoid() {
+ super.test_expectedToken_parseStatement_afterVoid();
+ }
+
+ @failingTest
+ void test_expectedToken_semicolonMissingAfterExport() {
+ super.test_expectedToken_semicolonMissingAfterExport();
+ }
+
+ @failingTest
+ void test_expectedToken_semicolonMissingAfterExpression() {
+ super.test_expectedToken_semicolonMissingAfterExpression();
+ }
+
+ @failingTest
+ void test_expectedToken_semicolonMissingAfterImport() {
+ super.test_expectedToken_semicolonMissingAfterImport();
+ }
+
+ @failingTest
+ void test_expectedToken_uriAndSemicolonMissingAfterExport() {
+ super.test_expectedToken_uriAndSemicolonMissingAfterExport();
+ }
+
+ @failingTest
+ void test_expectedToken_whileMissingInDoStatement() {
+ super.test_expectedToken_whileMissingInDoStatement();
+ }
+
+ @failingTest
+ void test_expectedTypeName_as() {
+ super.test_expectedTypeName_as();
+ }
+
+ @failingTest
+ void test_expectedTypeName_as_void() {
+ super.test_expectedTypeName_as_void();
+ }
+
+ @failingTest
+ void test_expectedTypeName_is() {
+ super.test_expectedTypeName_is();
+ }
+
+ @failingTest
+ void test_expectedTypeName_is_void() {
+ super.test_expectedTypeName_is_void();
+ }
+
+ @failingTest
+ void test_exportAsType() {
+ super.test_exportAsType();
+ }
+
+ @failingTest
+ void test_exportAsType_inClass() {
+ super.test_exportAsType_inClass();
+ }
+
+ @failingTest
+ void test_exportDirectiveAfterPartDirective() {
+ super.test_exportDirectiveAfterPartDirective();
+ }
+
+ @failingTest
+ void test_externalAfterConst() {
+ super.test_externalAfterConst();
+ }
+
+ @failingTest
+ void test_externalAfterFactory() {
+ super.test_externalAfterFactory();
+ }
+
+ @failingTest
+ void test_externalAfterStatic() {
+ super.test_externalAfterStatic();
+ }
+
+ @failingTest
+ void test_externalClass() {
+ super.test_externalClass();
+ }
+
+ @failingTest
+ void test_externalConstructorWithBody_factory() {
+ super.test_externalConstructorWithBody_factory();
+ }
+
+ @failingTest
+ void test_externalConstructorWithBody_named() {
+ super.test_externalConstructorWithBody_named();
+ }
+
+ @failingTest
+ void test_externalEnum() {
+ super.test_externalEnum();
+ }
+
+ @failingTest
+ void test_externalField_const() {
+ super.test_externalField_const();
+ }
+
+ @failingTest
+ void test_externalField_final() {
+ super.test_externalField_final();
+ }
+
+ @failingTest
+ void test_externalField_static() {
+ super.test_externalField_static();
+ }
+
+ @failingTest
+ void test_externalField_typed() {
+ super.test_externalField_typed();
+ }
+
+ @failingTest
+ void test_externalField_untyped() {
+ super.test_externalField_untyped();
+ }
+
+ @failingTest
+ void test_externalGetterWithBody() {
+ super.test_externalGetterWithBody();
+ }
+
+ @failingTest
+ void test_externalMethodWithBody() {
+ super.test_externalMethodWithBody();
+ }
+
+ @failingTest
+ void test_externalOperatorWithBody() {
+ super.test_externalOperatorWithBody();
+ }
+
+ @failingTest
+ void test_externalSetterWithBody() {
+ super.test_externalSetterWithBody();
+ }
+
+ @failingTest
+ void test_externalTypedef() {
+ super.test_externalTypedef();
+ }
+
+ @failingTest
+ void test_extraCommaInParameterList() {
+ super.test_extraCommaInParameterList();
+ }
+
+ @failingTest
+ void test_extraCommaTrailingNamedParameterGroup() {
+ super.test_extraCommaTrailingNamedParameterGroup();
+ }
+
+ @failingTest
+ void test_extraCommaTrailingPositionalParameterGroup() {
+ super.test_extraCommaTrailingPositionalParameterGroup();
+ }
+
+ @failingTest
+ void test_extraTrailingCommaInParameterList() {
+ super.test_extraTrailingCommaInParameterList();
+ }
+
+ @failingTest
+ void test_factoryTopLevelDeclaration_class() {
+ super.test_factoryTopLevelDeclaration_class();
+ }
+
+ @failingTest
+ void test_factoryTopLevelDeclaration_enum() {
+ super.test_factoryTopLevelDeclaration_enum();
+ }
+
+ @failingTest
+ void test_factoryTopLevelDeclaration_typedef() {
+ super.test_factoryTopLevelDeclaration_typedef();
+ }
+
+ @failingTest
+ void test_factoryWithInitializers() {
+ super.test_factoryWithInitializers();
+ }
+
+ @failingTest
+ void test_factoryWithoutBody() {
+ super.test_factoryWithoutBody();
+ }
+
+ @failingTest
+ void test_fieldInitializerOutsideConstructor() {
+ super.test_fieldInitializerOutsideConstructor();
+ }
+
+ @failingTest
+ void test_finalAndCovariant() {
+ super.test_finalAndCovariant();
+ }
+
+ @failingTest
+ void test_finalAndVar() {
+ super.test_finalAndVar();
+ }
+
+ @failingTest
+ void test_finalClass() {
+ super.test_finalClass();
+ }
+
+ @failingTest
+ void test_finalClassMember_modifierOnly() {
+ super.test_finalClassMember_modifierOnly();
+ }
+
+ @failingTest
+ void test_finalConstructor() {
+ super.test_finalConstructor();
+ }
+
+ @failingTest
+ void test_finalEnum() {
+ super.test_finalEnum();
+ }
+
+ @failingTest
+ void test_finalMethod() {
+ super.test_finalMethod();
+ }
+
+ @failingTest
+ void test_finalTypedef() {
+ super.test_finalTypedef();
+ }
+
+ @failingTest
+ void test_functionTypedField_invalidType_abstract() {
+ super.test_functionTypedField_invalidType_abstract();
+ }
+
+ @failingTest
+ void test_functionTypedField_invalidType_class() {
+ super.test_functionTypedField_invalidType_class();
+ }
+
+ @failingTest
+ void test_functionTypedParameter_const() {
+ super.test_functionTypedParameter_const();
+ }
+
+ @failingTest
+ void test_functionTypedParameter_final() {
+ super.test_functionTypedParameter_final();
+ }
+
+ @failingTest
+ void test_functionTypedParameter_incomplete1() {
+ super.test_functionTypedParameter_incomplete1();
+ }
+
+ @failingTest
+ void test_functionTypedParameter_var() {
+ super.test_functionTypedParameter_var();
+ }
+
+ @failingTest
+ void test_genericFunctionType_asIdentifier() {
+ super.test_genericFunctionType_asIdentifier();
+ }
+
+ @failingTest
+ void test_genericFunctionType_asIdentifier2() {
+ super.test_genericFunctionType_asIdentifier2();
+ }
+
+ @failingTest
+ void test_genericFunctionType_asIdentifier3() {
+ super.test_genericFunctionType_asIdentifier3();
+ }
+
+ @failingTest
+ void test_genericFunctionType_extraLessThan() {
+ super.test_genericFunctionType_extraLessThan();
+ }
+
+ @failingTest
+ void test_getterInFunction_block_noReturnType() {
+ super.test_getterInFunction_block_noReturnType();
+ }
+
+ @failingTest
+ void test_getterInFunction_block_returnType() {
+ super.test_getterInFunction_block_returnType();
+ }
+
+ @failingTest
+ void test_getterInFunction_expression_noReturnType() {
+ super.test_getterInFunction_expression_noReturnType();
+ }
+
+ @failingTest
+ void test_getterInFunction_expression_returnType() {
+ super.test_getterInFunction_expression_returnType();
+ }
+
+ @failingTest
+ void test_getterWithParameters() {
+ super.test_getterWithParameters();
+ }
+
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_assign_int() {
+ super.test_illegalAssignmentToNonAssignable_assign_int();
+ }
+
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_assign_this() {
+ super.test_illegalAssignmentToNonAssignable_assign_this();
+ }
+
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal() {
+ super.test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal();
+ }
+
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal() {
+ super.test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal();
+ }
+
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_postfix_plusPlus_parenthesized() {
+ super
+ .test_illegalAssignmentToNonAssignable_postfix_plusPlus_parenthesized();
+ }
+
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_primarySelectorPostfix() {
+ super.test_illegalAssignmentToNonAssignable_primarySelectorPostfix();
+ }
+
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_superAssigned() {
+ super.test_illegalAssignmentToNonAssignable_superAssigned();
+ }
+
+ @failingTest
+ void test_implementsBeforeExtends() {
+ super.test_implementsBeforeExtends();
+ }
+
+ @failingTest
+ void test_implementsBeforeWith() {
+ super.test_implementsBeforeWith();
+ }
+
+ @failingTest
+ void test_importDirectiveAfterPartDirective() {
+ super.test_importDirectiveAfterPartDirective();
+ }
+
+ @failingTest
+ void test_initializedVariableInForEach() {
+ super.test_initializedVariableInForEach();
+ }
+
+ @failingTest
+ void test_initializedVariableInForEach_annotation() {
+ super.test_initializedVariableInForEach_annotation();
+ }
+
+ @failingTest
+ void test_initializedVariableInForEach_localFunction() {
+ super.test_initializedVariableInForEach_localFunction();
+ }
+
+ @failingTest
+ void test_initializedVariableInForEach_localFunction2() {
+ super.test_initializedVariableInForEach_localFunction2();
+ }
+
+ @failingTest
+ void test_initializedVariableInForEach_var() {
+ super.test_initializedVariableInForEach_var();
+ }
+
+ @failingTest
+ void test_invalidAwaitInFor() {
+ super.test_invalidAwaitInFor();
+ }
+
+ @failingTest
+ void test_invalidCodePoint() {
+ super.test_invalidCodePoint();
+ }
+
+ @failingTest
+ void test_invalidCommentReference__new_nonIdentifier() {
+ super.test_invalidCommentReference__new_nonIdentifier();
+ }
+
+ @failingTest
+ void test_invalidCommentReference__new_tooMuch() {
+ super.test_invalidCommentReference__new_tooMuch();
+ }
+
+ @failingTest
+ void test_invalidCommentReference__nonNew_nonIdentifier() {
+ super.test_invalidCommentReference__nonNew_nonIdentifier();
+ }
+
+ @failingTest
+ void test_invalidCommentReference__nonNew_tooMuch() {
+ super.test_invalidCommentReference__nonNew_tooMuch();
+ }
+
+ @failingTest
+ void test_invalidConstructorName_star() {
+ super.test_invalidConstructorName_star();
+ }
+
+ @failingTest
+ void test_invalidConstructorName_with() {
+ super.test_invalidConstructorName_with();
+ }
+
+ @failingTest
+ void test_invalidHexEscape_invalidDigit() {
+ super.test_invalidHexEscape_invalidDigit();
+ }
+
+ @failingTest
+ void test_invalidHexEscape_tooFewDigits() {
+ super.test_invalidHexEscape_tooFewDigits();
+ }
+
+ @failingTest
+ void test_invalidInterpolationIdentifier_startWithDigit() {
+ super.test_invalidInterpolationIdentifier_startWithDigit();
+ }
+
+ @failingTest
+ void test_invalidLiteralInConfiguration() {
+ super.test_invalidLiteralInConfiguration();
+ }
+
+ @failingTest
+ void test_invalidOperator() {
+ super.test_invalidOperator();
+ }
+
+ @failingTest
+ void test_invalidOperator_unary() {
+ super.test_invalidOperator_unary();
+ }
+
+ @failingTest
+ void test_invalidOperatorAfterSuper_assignableExpression() {
+ super.test_invalidOperatorAfterSuper_assignableExpression();
+ }
+
+ @failingTest
+ void test_invalidOperatorAfterSuper_primaryExpression() {
+ super.test_invalidOperatorAfterSuper_primaryExpression();
+ }
+
+ @failingTest
+ void test_invalidOperatorForSuper() {
+ super.test_invalidOperatorForSuper();
+ }
+
+ @failingTest
+ void test_invalidStarAfterAsync() {
+ super.test_invalidStarAfterAsync();
+ }
+
+ @failingTest
+ void test_invalidSync() {
+ super.test_invalidSync();
+ }
+
+ @failingTest
+ void test_invalidTopLevelSetter() {
+ super.test_invalidTopLevelSetter();
+ }
+
+ @failingTest
+ void test_invalidTopLevelVar() {
+ super.test_invalidTopLevelVar();
+ }
+
+ @failingTest
+ void test_invalidTypedef() {
+ super.test_invalidTypedef();
+ }
+
+ @failingTest
+ void test_invalidTypedef2() {
+ super.test_invalidTypedef2();
+ }
+
+ @failingTest
+ void test_invalidUnicodeEscape_incomplete_noDigits() {
+ super.test_invalidUnicodeEscape_incomplete_noDigits();
+ }
+
+ @failingTest
+ void test_invalidUnicodeEscape_incomplete_someDigits() {
+ super.test_invalidUnicodeEscape_incomplete_someDigits();
+ }
+
+ @failingTest
+ void test_invalidUnicodeEscape_invalidDigit() {
+ super.test_invalidUnicodeEscape_invalidDigit();
+ }
+
+ @failingTest
+ void test_invalidUnicodeEscape_tooFewDigits_fixed() {
+ super.test_invalidUnicodeEscape_tooFewDigits_fixed();
+ }
+
+ @failingTest
+ void test_invalidUnicodeEscape_tooFewDigits_variable() {
+ super.test_invalidUnicodeEscape_tooFewDigits_variable();
+ }
+
+ @failingTest
+ void test_invalidUnicodeEscape_tooManyDigits_variable() {
+ super.test_invalidUnicodeEscape_tooManyDigits_variable();
+ }
+
+ @failingTest
+ void test_libraryDirectiveNotFirst() {
+ super.test_libraryDirectiveNotFirst();
+ }
+
+ @failingTest
+ void test_libraryDirectiveNotFirst_afterPart() {
+ super.test_libraryDirectiveNotFirst_afterPart();
+ }
+
+ @failingTest
+ void test_localFunction_annotation() {
+ super.test_localFunction_annotation();
+ }
+
+ @failingTest
+ void test_localFunctionDeclarationModifier_abstract() {
+ super.test_localFunctionDeclarationModifier_abstract();
+ }
+
+ @failingTest
+ void test_localFunctionDeclarationModifier_external() {
+ super.test_localFunctionDeclarationModifier_external();
+ }
+
+ @failingTest
+ void test_localFunctionDeclarationModifier_factory() {
+ super.test_localFunctionDeclarationModifier_factory();
+ }
+
+ @failingTest
+ void test_localFunctionDeclarationModifier_static() {
+ super.test_localFunctionDeclarationModifier_static();
+ }
+
+ @failingTest
+ void test_method_invalidTypeParameterComments() {
+ super.test_method_invalidTypeParameterComments();
+ }
+
+ @failingTest
+ void test_method_invalidTypeParameterExtends() {
+ super.test_method_invalidTypeParameterExtends();
+ }
+
+ @failingTest
+ void test_method_invalidTypeParameterExtendsComment() {
+ super.test_method_invalidTypeParameterExtendsComment();
+ }
+
+ @failingTest
+ void test_method_invalidTypeParameters() {
+ super.test_method_invalidTypeParameters();
+ }
+
+ @failingTest
+ void test_missingAssignableSelector_identifiersAssigned() {
+ super.test_missingAssignableSelector_identifiersAssigned();
+ }
+
+ @failingTest
+ void test_missingAssignableSelector_prefix_minusMinus_literal() {
+ super.test_missingAssignableSelector_prefix_minusMinus_literal();
+ }
+
+ @failingTest
+ void test_missingAssignableSelector_prefix_plusPlus_literal() {
+ super.test_missingAssignableSelector_prefix_plusPlus_literal();
+ }
+
+ @failingTest
+ void test_missingAssignableSelector_selector() {
+ super.test_missingAssignableSelector_selector();
+ }
+
+ @failingTest
+ void test_missingAssignableSelector_superPrimaryExpression() {
+ super.test_missingAssignableSelector_superPrimaryExpression();
+ }
+
+ @failingTest
+ void test_missingAssignableSelector_superPropertyAccessAssigned() {
+ super.test_missingAssignableSelector_superPropertyAccessAssigned();
+ }
+
+ @failingTest
+ void test_missingCatchOrFinally() {
+ super.test_missingCatchOrFinally();
+ }
+
+ @failingTest
+ void test_missingClassBody() {
+ super.test_missingClassBody();
+ }
+
+ @failingTest
+ void test_missingClosingParenthesis() {
+ super.test_missingClosingParenthesis();
+ }
+
+ @failingTest
+ void test_missingConstFinalVarOrType_static() {
+ super.test_missingConstFinalVarOrType_static();
+ }
+
+ @failingTest
+ void test_missingConstFinalVarOrType_topLevel() {
+ super.test_missingConstFinalVarOrType_topLevel();
+ }
+
+ @failingTest
+ void test_missingEnumBody() {
+ super.test_missingEnumBody();
+ }
+
+ @failingTest
+ void test_missingEnumComma() {
+ super.test_missingEnumComma();
+ }
+
+ @failingTest
+ void test_missingExpressionInThrow() {
+ super.test_missingExpressionInThrow();
+ }
+
+ @failingTest
+ void test_missingFunctionBody_emptyNotAllowed() {
+ super.test_missingFunctionBody_emptyNotAllowed();
+ }
+
+ @failingTest
+ void test_missingFunctionBody_invalid() {
+ super.test_missingFunctionBody_invalid();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_local_nonVoid_block() {
+ super.test_missingFunctionParameters_local_nonVoid_block();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_local_nonVoid_expression() {
+ super.test_missingFunctionParameters_local_nonVoid_expression();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_local_void_block() {
+ super.test_missingFunctionParameters_local_void_block();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_local_void_expression() {
+ super.test_missingFunctionParameters_local_void_expression();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_topLevel_nonVoid_block() {
+ super.test_missingFunctionParameters_topLevel_nonVoid_block();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_topLevel_nonVoid_expression() {
+ super.test_missingFunctionParameters_topLevel_nonVoid_expression();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_topLevel_void_block() {
+ super.test_missingFunctionParameters_topLevel_void_block();
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_topLevel_void_expression() {
+ super.test_missingFunctionParameters_topLevel_void_expression();
+ }
+
+ @failingTest
+ void test_missingIdentifier_afterOperator() {
+ super.test_missingIdentifier_afterOperator();
+ }
+
+ @failingTest
+ void test_missingIdentifier_beforeClosingCurly() {
+ super.test_missingIdentifier_beforeClosingCurly();
+ }
+
+ @failingTest
+ void test_missingIdentifier_inEnum() {
+ super.test_missingIdentifier_inEnum();
+ }
+
+ @failingTest
+ void test_missingIdentifier_inParameterGroupNamed() {
+ super.test_missingIdentifier_inParameterGroupNamed();
+ }
+
+ @failingTest
+ void test_missingIdentifier_inParameterGroupOptional() {
+ super.test_missingIdentifier_inParameterGroupOptional();
+ }
+
+ @failingTest
+ void test_missingIdentifier_inSymbol_afterPeriod() {
+ super.test_missingIdentifier_inSymbol_afterPeriod();
+ }
+
+ @failingTest
+ void test_missingIdentifier_inSymbol_first() {
+ super.test_missingIdentifier_inSymbol_first();
+ }
+
+ @failingTest
+ void test_missingIdentifierForParameterGroup() {
+ super.test_missingIdentifierForParameterGroup();
+ }
+
+ @failingTest
+ void test_missingKeywordOperator() {
+ super.test_missingKeywordOperator();
+ }
+
+ @failingTest
+ void test_missingKeywordOperator_parseClassMember() {
+ super.test_missingKeywordOperator_parseClassMember();
+ }
+
+ @failingTest
+ void test_missingKeywordOperator_parseClassMember_afterTypeName() {
+ super.test_missingKeywordOperator_parseClassMember_afterTypeName();
+ }
+
+ @failingTest
+ void test_missingKeywordOperator_parseClassMember_afterVoid() {
+ super.test_missingKeywordOperator_parseClassMember_afterVoid();
+ }
+
+ @failingTest
+ void test_missingMethodParameters_void_block() {
+ super.test_missingMethodParameters_void_block();
+ }
+
+ @failingTest
+ void test_missingMethodParameters_void_expression() {
+ super.test_missingMethodParameters_void_expression();
+ }
+
+ @failingTest
+ void test_missingNameForNamedParameter_colon() {
+ super.test_missingNameForNamedParameter_colon();
+ }
+
+ @failingTest
+ void test_missingNameForNamedParameter_equals() {
+ super.test_missingNameForNamedParameter_equals();
+ }
+
+ @failingTest
+ void test_missingNameForNamedParameter_noDefault() {
+ super.test_missingNameForNamedParameter_noDefault();
+ }
+
+ @failingTest
+ void test_missingNameInLibraryDirective() {
+ super.test_missingNameInLibraryDirective();
+ }
+
+ @failingTest
+ void test_missingNameInPartOfDirective() {
+ super.test_missingNameInPartOfDirective();
+ }
+
+ @failingTest
+ void test_missingPrefixInDeferredImport() {
+ super.test_missingPrefixInDeferredImport();
+ }
+
+ @failingTest
+ void test_missingStartAfterSync() {
+ super.test_missingStartAfterSync();
+ }
+
+ @failingTest
+ void test_missingStatement() {
+ super.test_missingStatement();
+ }
+
+ @failingTest
+ void test_missingStatement_afterVoid() {
+ super.test_missingStatement_afterVoid();
+ }
+
+ @failingTest
+ void test_missingTerminatorForParameterGroup_named() {
+ super.test_missingTerminatorForParameterGroup_named();
+ }
+
+ @failingTest
+ void test_missingTerminatorForParameterGroup_optional() {
+ super.test_missingTerminatorForParameterGroup_optional();
+ }
+
+ @failingTest
+ void test_missingTypedefParameters_nonVoid() {
+ super.test_missingTypedefParameters_nonVoid();
+ }
+
+ @failingTest
+ void test_missingTypedefParameters_typeParameters() {
+ super.test_missingTypedefParameters_typeParameters();
+ }
+
+ @failingTest
+ void test_missingTypedefParameters_void() {
+ super.test_missingTypedefParameters_void();
+ }
+
+ @failingTest
+ void test_missingVariableInForEach() {
+ super.test_missingVariableInForEach();
+ }
+
+ @failingTest
+ void test_mixedParameterGroups_namedPositional() {
+ super.test_mixedParameterGroups_namedPositional();
+ }
+
+ @failingTest
+ void test_mixedParameterGroups_positionalNamed() {
+ super.test_mixedParameterGroups_positionalNamed();
+ }
+
+ @failingTest
+ void test_mixin_application_lacks_with_clause() {
+ super.test_mixin_application_lacks_with_clause();
+ }
+
+ @failingTest
+ void test_multipleExtendsClauses() {
+ super.test_multipleExtendsClauses();
+ }
+
+ @failingTest
+ void test_multipleImplementsClauses() {
+ super.test_multipleImplementsClauses();
+ }
+
+ @failingTest
+ void test_multipleLibraryDirectives() {
+ super.test_multipleLibraryDirectives();
+ }
+
+ @failingTest
+ void test_multipleNamedParameterGroups() {
+ super.test_multipleNamedParameterGroups();
+ }
+
+ @failingTest
+ void test_multiplePartOfDirectives() {
+ super.test_multiplePartOfDirectives();
+ }
+
+ @failingTest
+ void test_multiplePositionalParameterGroups() {
+ super.test_multiplePositionalParameterGroups();
+ }
+
+ @failingTest
+ void test_multipleVariablesInForEach() {
+ super.test_multipleVariablesInForEach();
+ }
+
+ @failingTest
+ void test_multipleWithClauses() {
+ super.test_multipleWithClauses();
+ }
+
+ @failingTest
+ void test_namedFunctionExpression() {
+ super.test_namedFunctionExpression();
+ }
+
+ @failingTest
+ void test_namedParameterOutsideGroup() {
+ super.test_namedParameterOutsideGroup();
+ }
+
+ @failingTest
+ void test_nonConstructorFactory_field() {
+ super.test_nonConstructorFactory_field();
+ }
+
+ @failingTest
+ void test_nonConstructorFactory_method() {
+ super.test_nonConstructorFactory_method();
+ }
+
+ @failingTest
+ void test_nonIdentifierLibraryName_library() {
+ super.test_nonIdentifierLibraryName_library();
+ }
+
+ @failingTest
+ void test_nonIdentifierLibraryName_partOf() {
+ super.test_nonIdentifierLibraryName_partOf();
+ }
+
+ @failingTest
+ void test_nonPartOfDirectiveInPart_after() {
+ super.test_nonPartOfDirectiveInPart_after();
+ }
+
+ @failingTest
+ void test_nonPartOfDirectiveInPart_before() {
+ super.test_nonPartOfDirectiveInPart_before();
+ }
+
+ @failingTest
+ void test_nonUserDefinableOperator() {
+ super.test_nonUserDefinableOperator();
+ }
+
+ @failingTest
+ void test_optionalAfterNormalParameters_named() {
+ super.test_optionalAfterNormalParameters_named();
+ }
+
+ @failingTest
+ void test_optionalAfterNormalParameters_positional() {
+ super.test_optionalAfterNormalParameters_positional();
+ }
+
+ @failingTest
+ void test_parseCascadeSection_missingIdentifier() {
+ super.test_parseCascadeSection_missingIdentifier();
+ }
+
+ @failingTest
+ void test_parseCascadeSection_missingIdentifier_typeArguments() {
+ super.test_parseCascadeSection_missingIdentifier_typeArguments();
+ }
+
+ @failingTest
+ void test_positionalAfterNamedArgument() {
+ super.test_positionalAfterNamedArgument();
+ }
+
+ @failingTest
+ void test_positionalParameterOutsideGroup() {
+ super.test_positionalParameterOutsideGroup();
+ }
+
+ @failingTest
+ void test_redirectingConstructorWithBody_named() {
+ super.test_redirectingConstructorWithBody_named();
+ }
+
+ @failingTest
+ void test_redirectingConstructorWithBody_unnamed() {
+ super.test_redirectingConstructorWithBody_unnamed();
+ }
+
+ @failingTest
+ void test_redirectionInNonFactoryConstructor() {
+ super.test_redirectionInNonFactoryConstructor();
+ }
+
+ @failingTest
+ void test_setterInFunction_block() {
+ super.test_setterInFunction_block();
+ }
+
+ @failingTest
+ void test_setterInFunction_expression() {
+ super.test_setterInFunction_expression();
+ }
+
+ @failingTest
+ void test_staticAfterConst() {
+ super.test_staticAfterConst();
+ }
+
+ @failingTest
+ void test_staticAfterFinal() {
+ super.test_staticAfterFinal();
+ }
+
+ @failingTest
+ void test_staticAfterVar() {
+ super.test_staticAfterVar();
+ }
+
+ @failingTest
+ void test_staticConstructor() {
+ super.test_staticConstructor();
+ }
+
+ @failingTest
+ void test_staticGetterWithoutBody() {
+ super.test_staticGetterWithoutBody();
+ }
+
+ @failingTest
+ void test_staticOperator_noReturnType() {
+ super.test_staticOperator_noReturnType();
+ }
+
+ @failingTest
+ void test_staticOperator_returnType() {
+ super.test_staticOperator_returnType();
+ }
+
+ @failingTest
+ void test_staticSetterWithoutBody() {
+ super.test_staticSetterWithoutBody();
+ }
+
+ @failingTest
+ void test_staticTopLevelDeclaration_class() {
+ super.test_staticTopLevelDeclaration_class();
+ }
+
+ @failingTest
+ void test_staticTopLevelDeclaration_enum() {
+ super.test_staticTopLevelDeclaration_enum();
+ }
+
+ @failingTest
+ void test_staticTopLevelDeclaration_function() {
+ super.test_staticTopLevelDeclaration_function();
+ }
+
+ @failingTest
+ void test_staticTopLevelDeclaration_typedef() {
+ super.test_staticTopLevelDeclaration_typedef();
+ }
+
+ @failingTest
+ void test_staticTopLevelDeclaration_variable() {
+ super.test_staticTopLevelDeclaration_variable();
+ }
+
+ @failingTest
+ void test_string_unterminated_interpolation_block() {
+ super.test_string_unterminated_interpolation_block();
+ }
+
+ @failingTest
+ void test_switchCase_missingColon() {
+ super.test_switchCase_missingColon();
+ }
+
+ @failingTest
+ void test_switchDefault_missingColon() {
+ super.test_switchDefault_missingColon();
+ }
+
+ @failingTest
+ void test_switchHasCaseAfterDefaultCase() {
+ super.test_switchHasCaseAfterDefaultCase();
+ }
+
+ @failingTest
+ void test_switchHasCaseAfterDefaultCase_repeated() {
+ super.test_switchHasCaseAfterDefaultCase_repeated();
+ }
+
+ @failingTest
+ void test_switchHasMultipleDefaultCases() {
+ super.test_switchHasMultipleDefaultCases();
+ }
+
+ @failingTest
+ void test_switchHasMultipleDefaultCases_repeated() {
+ super.test_switchHasMultipleDefaultCases_repeated();
+ }
+
+ @failingTest
+ void test_switchMissingBlock() {
+ super.test_switchMissingBlock();
+ }
+
+ @failingTest
+ void test_topLevel_getter() {
+ super.test_topLevel_getter();
+ }
+
+ @failingTest
+ void test_topLevelFactory_withFunction() {
+ super.test_topLevelFactory_withFunction();
+ }
+
+ @failingTest
+ void test_topLevelOperator_withFunction() {
+ super.test_topLevelOperator_withFunction();
+ }
+
+ @failingTest
+ void test_topLevelOperator_withoutOperator() {
+ super.test_topLevelOperator_withoutOperator();
+ }
+
+ @failingTest
+ void test_topLevelOperator_withoutType() {
+ super.test_topLevelOperator_withoutType();
+ }
+
+ @failingTest
+ void test_topLevelOperator_withType() {
+ super.test_topLevelOperator_withType();
+ }
+
+ @failingTest
+ void test_topLevelOperator_withVoid() {
+ super.test_topLevelOperator_withVoid();
+ }
+
+ @failingTest
+ void test_topLevelVariable_withMetadata() {
+ super.test_topLevelVariable_withMetadata();
+ }
+
+ @failingTest
+ void test_typedef_incomplete() {
+ super.test_typedef_incomplete();
+ }
+
+ @failingTest
+ void test_typedef_namedFunction() {
+ super.test_typedef_namedFunction();
+ }
+
+ @failingTest
+ void test_typedefInClass_withoutReturnType() {
+ super.test_typedefInClass_withoutReturnType();
+ }
+
+ @failingTest
+ void test_typedefInClass_withReturnType() {
+ super.test_typedefInClass_withReturnType();
+ }
+
+ @failingTest
+ void test_unexpectedTerminatorForParameterGroup_named() {
+ super.test_unexpectedTerminatorForParameterGroup_named();
+ }
+
+ @failingTest
+ void test_unexpectedTerminatorForParameterGroup_optional() {
+ super.test_unexpectedTerminatorForParameterGroup_optional();
+ }
+
+ @failingTest
+ void test_unexpectedToken_endOfFieldDeclarationStatement() {
+ super.test_unexpectedToken_endOfFieldDeclarationStatement();
+ }
+
+ @failingTest
+ void test_unexpectedToken_invalidPostfixExpression() {
+ super.test_unexpectedToken_invalidPostfixExpression();
+ }
+
+ @failingTest
+ void test_unexpectedToken_invalidPrefixExpression() {
+ super.test_unexpectedToken_invalidPrefixExpression();
+ }
+
+ @failingTest
+ void test_unexpectedToken_returnInExpressionFunctionBody() {
+ super.test_unexpectedToken_returnInExpressionFunctionBody();
+ }
+
+ @failingTest
+ void test_unexpectedToken_semicolonBetweenClassMembers() {
+ super.test_unexpectedToken_semicolonBetweenClassMembers();
+ }
+
+ @failingTest
+ void test_unexpectedToken_semicolonBetweenCompilationUnitMembers() {
+ super.test_unexpectedToken_semicolonBetweenCompilationUnitMembers();
+ }
+
+ @failingTest
+ void test_unterminatedString_at_eof() {
+ super.test_unterminatedString_at_eof();
+ }
+
+ @failingTest
+ void test_unterminatedString_at_eol() {
+ super.test_unterminatedString_at_eol();
+ }
+
+ @failingTest
+ void test_unterminatedString_multiline_at_eof_3_quotes() {
+ super.test_unterminatedString_multiline_at_eof_3_quotes();
+ }
+
+ @failingTest
+ void test_unterminatedString_multiline_at_eof_4_quotes() {
+ super.test_unterminatedString_multiline_at_eof_4_quotes();
+ }
+
+ @failingTest
+ void test_unterminatedString_multiline_at_eof_5_quotes() {
+ super.test_unterminatedString_multiline_at_eof_5_quotes();
+ }
+
+ @failingTest
+ void test_useOfUnaryPlusOperator() {
+ super.test_useOfUnaryPlusOperator();
+ }
+
+ @failingTest
+ void test_varAndType_field() {
+ super.test_varAndType_field();
+ }
+
+ @failingTest
+ void test_varAndType_local() {
+ super.test_varAndType_local();
+ }
+
+ @failingTest
+ void test_varAndType_parameter() {
+ super.test_varAndType_parameter();
+ }
+
+ @failingTest
+ void test_varAndType_topLevelVariable() {
+ super.test_varAndType_topLevelVariable();
+ }
+
+ @failingTest
+ void test_varAsTypeName_as() {
+ super.test_varAsTypeName_as();
+ }
+
+ @failingTest
+ void test_varClass() {
+ super.test_varClass();
+ }
+
+ @failingTest
+ void test_varEnum() {
+ super.test_varEnum();
+ }
+
+ @failingTest
+ void test_varReturnType() {
+ super.test_varReturnType();
+ }
+
+ @failingTest
+ void test_varTypedef() {
+ super.test_varTypedef();
+ }
+
+ @failingTest
+ void test_voidParameter() {
+ super.test_voidParameter();
+ }
+
+ @failingTest
+ void test_voidVariable_parseClassMember_initializer() {
+ super.test_voidVariable_parseClassMember_initializer();
+ }
+
+ @failingTest
+ void test_voidVariable_parseClassMember_noInitializer() {
+ super.test_voidVariable_parseClassMember_noInitializer();
+ }
+
+ @failingTest
+ void test_voidVariable_parseCompilationUnit_initializer() {
+ super.test_voidVariable_parseCompilationUnit_initializer();
+ }
+
+ @failingTest
+ void test_voidVariable_parseCompilationUnit_noInitializer() {
+ super.test_voidVariable_parseCompilationUnit_noInitializer();
+ }
+
+ @failingTest
+ void test_voidVariable_parseCompilationUnitMember_initializer() {
+ super.test_voidVariable_parseCompilationUnitMember_initializer();
+ }
+
+ @failingTest
+ void test_voidVariable_parseCompilationUnitMember_noInitializer() {
+ super.test_voidVariable_parseCompilationUnitMember_noInitializer();
+ }
+
+ @failingTest
+ void test_voidVariable_statement_initializer() {
+ super.test_voidVariable_statement_initializer();
+ }
+
+ @failingTest
+ void test_voidVariable_statement_noInitializer() {
+ super.test_voidVariable_statement_noInitializer();
+ }
+
+ @failingTest
+ void test_withBeforeExtends() {
+ super.test_withBeforeExtends();
+ }
+
+ @failingTest
+ void test_withWithoutExtends() {
+ super.test_withWithoutExtends();
+ }
+
+ @failingTest
+ void test_wrongSeparatorForPositionalParameter() {
+ super.test_wrongSeparatorForPositionalParameter();
+ }
+
+ @failingTest
+ void test_wrongTerminatorForParameterGroup_named() {
+ super.test_wrongTerminatorForParameterGroup_named();
+ }
+
+ @failingTest
+ void test_wrongTerminatorForParameterGroup_optional() {
+ super.test_wrongTerminatorForParameterGroup_optional();
+ }
+}
+
@reflectiveTest
class ExpressionParserTest_Forest extends FastaBodyBuilderTestCase
with ExpressionParserTestMixin {
@@ -532,21 +3033,11 @@
}
@failingTest
- void test_parseListLiteral_empty_oneToken() {
- super.test_parseListLiteral_empty_oneToken();
- }
-
- @failingTest
void test_parseListLiteral_empty_oneToken_withComment() {
super.test_parseListLiteral_empty_oneToken_withComment();
}
@failingTest
- void test_parseListLiteral_empty_twoTokens() {
- super.test_parseListLiteral_empty_twoTokens();
- }
-
- @failingTest
void test_parseListLiteral_single_withTypeArgument() {
super.test_parseListLiteral_single_withTypeArgument();
}
@@ -808,11 +3299,6 @@
}
@failingTest
- void test_parseRethrowExpression() {
- super.test_parseRethrowExpression();
- }
-
- @failingTest
void test_parseShiftExpression_normal() {
super.test_parseShiftExpression_normal();
}
@@ -833,11 +3319,6 @@
}
@failingTest
- void test_parseStringLiteral_adjacent() {
- super.test_parseStringLiteral_adjacent();
- }
-
- @failingTest
void test_parseStringLiteral_endsWithInterpolation() {
super.test_parseStringLiteral_endsWithInterpolation();
}
@@ -883,31 +3364,6 @@
}
@failingTest
- void test_parseSymbolLiteral_builtInIdentifier() {
- super.test_parseSymbolLiteral_builtInIdentifier();
- }
-
- @failingTest
- void test_parseSymbolLiteral_multiple() {
- super.test_parseSymbolLiteral_multiple();
- }
-
- @failingTest
- void test_parseSymbolLiteral_operator() {
- super.test_parseSymbolLiteral_operator();
- }
-
- @failingTest
- void test_parseSymbolLiteral_single() {
- super.test_parseSymbolLiteral_single();
- }
-
- @failingTest
- void test_parseSymbolLiteral_void() {
- super.test_parseSymbolLiteral_void();
- }
-
- @failingTest
void test_parseThrowExpression() {
super.test_parseThrowExpression();
}
@@ -983,9 +3439,1559 @@
}
}
-/**
- * Tests of the fasta parser based on [StatementParserTestMixin].
- */
+@reflectiveTest
+class FormalParameterParserTest_Forest extends FastaBodyBuilderTestCase
+ with FormalParameterParserTestMixin {
+ FormalParameterParserTest_Forest() : super(false);
+
+ @failingTest
+ void test_parseFormalParameter_covariant_final_named() {
+ super.test_parseFormalParameter_covariant_final_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_final_normal() {
+ super.test_parseFormalParameter_covariant_final_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_final_positional() {
+ super.test_parseFormalParameter_covariant_final_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_final_type_named() {
+ super.test_parseFormalParameter_covariant_final_type_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_final_type_normal() {
+ super.test_parseFormalParameter_covariant_final_type_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_final_type_positional() {
+ super.test_parseFormalParameter_covariant_final_type_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_type_function() {
+ super.test_parseFormalParameter_covariant_type_function();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_type_named() {
+ super.test_parseFormalParameter_covariant_type_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_type_normal() {
+ super.test_parseFormalParameter_covariant_type_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_type_positional() {
+ super.test_parseFormalParameter_covariant_type_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_var_named() {
+ super.test_parseFormalParameter_covariant_var_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_var_normal() {
+ super.test_parseFormalParameter_covariant_var_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_covariant_var_positional() {
+ super.test_parseFormalParameter_covariant_var_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_final_named() {
+ super.test_parseFormalParameter_final_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_final_normal() {
+ super.test_parseFormalParameter_final_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_final_positional() {
+ super.test_parseFormalParameter_final_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_final_type_named() {
+ super.test_parseFormalParameter_final_type_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_final_type_normal() {
+ super.test_parseFormalParameter_final_type_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_final_type_positional() {
+ super.test_parseFormalParameter_final_type_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_type_function() {
+ super.test_parseFormalParameter_type_function();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_type_named() {
+ super.test_parseFormalParameter_type_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_type_named_noDefault() {
+ super.test_parseFormalParameter_type_named_noDefault();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_type_normal() {
+ super.test_parseFormalParameter_type_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_type_positional() {
+ super.test_parseFormalParameter_type_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_type_positional_noDefault() {
+ super.test_parseFormalParameter_type_positional_noDefault();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_var_named() {
+ super.test_parseFormalParameter_var_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_var_normal() {
+ super.test_parseFormalParameter_var_normal();
+ }
+
+ @failingTest
+ void test_parseFormalParameter_var_positional() {
+ super.test_parseFormalParameter_var_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_empty() {
+ super.test_parseFormalParameterList_empty();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_named_multiple() {
+ super.test_parseFormalParameterList_named_multiple();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_named_single() {
+ super.test_parseFormalParameterList_named_single();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_named_trailing_comma() {
+ super.test_parseFormalParameterList_named_trailing_comma();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_normal_multiple() {
+ super.test_parseFormalParameterList_normal_multiple();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_normal_named() {
+ super.test_parseFormalParameterList_normal_named();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_normal_named_inFunctionType() {
+ super.test_parseFormalParameterList_normal_named_inFunctionType();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_normal_positional() {
+ super.test_parseFormalParameterList_normal_positional();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_normal_single() {
+ super.test_parseFormalParameterList_normal_single();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_normal_single_Function() {
+ super.test_parseFormalParameterList_normal_single_Function();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_normal_single_trailing_comma() {
+ super.test_parseFormalParameterList_normal_single_trailing_comma();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_positional_multiple() {
+ super.test_parseFormalParameterList_positional_multiple();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_positional_single() {
+ super.test_parseFormalParameterList_positional_single();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_positional_trailing_comma() {
+ super.test_parseFormalParameterList_positional_trailing_comma();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_prefixedType() {
+ super.test_parseFormalParameterList_prefixedType();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_prefixedType_missingName() {
+ super.test_parseFormalParameterList_prefixedType_missingName();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_prefixedType_partial() {
+ super.test_parseFormalParameterList_prefixedType_partial();
+ }
+
+ @failingTest
+ void test_parseFormalParameterList_prefixedType_partial2() {
+ super.test_parseFormalParameterList_prefixedType_partial2();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_const_noType() {
+ super.test_parseNormalFormalParameter_field_const_noType();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_const_type() {
+ super.test_parseNormalFormalParameter_field_const_type();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_final_noType() {
+ super.test_parseNormalFormalParameter_field_final_noType();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_final_type() {
+ super.test_parseNormalFormalParameter_field_final_type();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_function_nested() {
+ super.test_parseNormalFormalParameter_field_function_nested();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_function_noNested() {
+ super.test_parseNormalFormalParameter_field_function_noNested();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_function_withDocComment() {
+ super.test_parseNormalFormalParameter_field_function_withDocComment();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_noType() {
+ super.test_parseNormalFormalParameter_field_noType();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_type() {
+ super.test_parseNormalFormalParameter_field_type();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_var() {
+ super.test_parseNormalFormalParameter_field_var();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_field_withDocComment() {
+ super.test_parseNormalFormalParameter_field_withDocComment();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_named() {
+ super.test_parseNormalFormalParameter_function_named();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_noType() {
+ super.test_parseNormalFormalParameter_function_noType();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_noType_covariant() {
+ super.test_parseNormalFormalParameter_function_noType_covariant();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_noType_typeParameterComments() {
+ super
+ .test_parseNormalFormalParameter_function_noType_typeParameterComments();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_noType_typeParameters() {
+ super.test_parseNormalFormalParameter_function_noType_typeParameters();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_type() {
+ super.test_parseNormalFormalParameter_function_type();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_type_typeParameterComments() {
+ super.test_parseNormalFormalParameter_function_type_typeParameterComments();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_type_typeParameters() {
+ super.test_parseNormalFormalParameter_function_type_typeParameters();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_typeVoid_covariant() {
+ super.test_parseNormalFormalParameter_function_typeVoid_covariant();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_void() {
+ super.test_parseNormalFormalParameter_function_void();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_void_typeParameterComments() {
+ super.test_parseNormalFormalParameter_function_void_typeParameterComments();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_void_typeParameters() {
+ super.test_parseNormalFormalParameter_function_void_typeParameters();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_function_withDocComment() {
+ super.test_parseNormalFormalParameter_function_withDocComment();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_const_noType() {
+ super.test_parseNormalFormalParameter_simple_const_noType();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_const_type() {
+ super.test_parseNormalFormalParameter_simple_const_type();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_final_noType() {
+ super.test_parseNormalFormalParameter_simple_final_noType();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_final_type() {
+ super.test_parseNormalFormalParameter_simple_final_type();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_noName() {
+ super.test_parseNormalFormalParameter_simple_noName();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_noType() {
+ super.test_parseNormalFormalParameter_simple_noType();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_noType_namedCovariant() {
+ super.test_parseNormalFormalParameter_simple_noType_namedCovariant();
+ }
+
+ @failingTest
+ void test_parseNormalFormalParameter_simple_type() {
+ super.test_parseNormalFormalParameter_simple_type();
+ }
+}
+
+@reflectiveTest
+class RecoveryParserTest_Forest extends FastaBodyBuilderTestCase
+ with RecoveryParserTestMixin {
+ RecoveryParserTest_Forest() : super(false);
+
+ @failingTest
+ void test_additiveExpression_missing_LHS() {
+ super.test_additiveExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_additiveExpression_missing_LHS_RHS() {
+ super.test_additiveExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_additiveExpression_missing_RHS() {
+ super.test_additiveExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_additiveExpression_missing_RHS_super() {
+ super.test_additiveExpression_missing_RHS_super();
+ }
+
+ @failingTest
+ void test_additiveExpression_precedence_multiplicative_left() {
+ super.test_additiveExpression_precedence_multiplicative_left();
+ }
+
+ @failingTest
+ void test_additiveExpression_precedence_multiplicative_right() {
+ super.test_additiveExpression_precedence_multiplicative_right();
+ }
+
+ @failingTest
+ void test_additiveExpression_super() {
+ super.test_additiveExpression_super();
+ }
+
+ @failingTest
+ void test_assignableSelector() {
+ super.test_assignableSelector();
+ }
+
+ @failingTest
+ void test_assignmentExpression_missing_compound1() {
+ super.test_assignmentExpression_missing_compound1();
+ }
+
+ @failingTest
+ void test_assignmentExpression_missing_compound2() {
+ super.test_assignmentExpression_missing_compound2();
+ }
+
+ @failingTest
+ void test_assignmentExpression_missing_compound3() {
+ super.test_assignmentExpression_missing_compound3();
+ }
+
+ @failingTest
+ void test_assignmentExpression_missing_LHS() {
+ super.test_assignmentExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_assignmentExpression_missing_RHS() {
+ super.test_assignmentExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_missing_LHS() {
+ super.test_bitwiseAndExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_missing_LHS_RHS() {
+ super.test_bitwiseAndExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_missing_RHS() {
+ super.test_bitwiseAndExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_missing_RHS_super() {
+ super.test_bitwiseAndExpression_missing_RHS_super();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_precedence_equality_left() {
+ super.test_bitwiseAndExpression_precedence_equality_left();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_precedence_equality_right() {
+ super.test_bitwiseAndExpression_precedence_equality_right();
+ }
+
+ @failingTest
+ void test_bitwiseAndExpression_super() {
+ super.test_bitwiseAndExpression_super();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_missing_LHS() {
+ super.test_bitwiseOrExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_missing_LHS_RHS() {
+ super.test_bitwiseOrExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_missing_RHS() {
+ super.test_bitwiseOrExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_missing_RHS_super() {
+ super.test_bitwiseOrExpression_missing_RHS_super();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_precedence_xor_left() {
+ super.test_bitwiseOrExpression_precedence_xor_left();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_precedence_xor_right() {
+ super.test_bitwiseOrExpression_precedence_xor_right();
+ }
+
+ @failingTest
+ void test_bitwiseOrExpression_super() {
+ super.test_bitwiseOrExpression_super();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_missing_LHS() {
+ super.test_bitwiseXorExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_missing_LHS_RHS() {
+ super.test_bitwiseXorExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_missing_RHS() {
+ super.test_bitwiseXorExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_missing_RHS_super() {
+ super.test_bitwiseXorExpression_missing_RHS_super();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_precedence_and_left() {
+ super.test_bitwiseXorExpression_precedence_and_left();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_precedence_and_right() {
+ super.test_bitwiseXorExpression_precedence_and_right();
+ }
+
+ @failingTest
+ void test_bitwiseXorExpression_super() {
+ super.test_bitwiseXorExpression_super();
+ }
+
+ @failingTest
+ void test_classTypeAlias_withBody() {
+ super.test_classTypeAlias_withBody();
+ }
+
+ @failingTest
+ void test_combinator_missingIdentifier() {
+ super.test_combinator_missingIdentifier();
+ }
+
+ @failingTest
+ void test_conditionalExpression_missingElse() {
+ super.test_conditionalExpression_missingElse();
+ }
+
+ @failingTest
+ void test_conditionalExpression_missingThen() {
+ super.test_conditionalExpression_missingThen();
+ }
+
+ @failingTest
+ void test_declarationBeforeDirective() {
+ super.test_declarationBeforeDirective();
+ }
+
+ @failingTest
+ void test_equalityExpression_missing_LHS() {
+ super.test_equalityExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_equalityExpression_missing_LHS_RHS() {
+ super.test_equalityExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_equalityExpression_missing_RHS() {
+ super.test_equalityExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_equalityExpression_missing_RHS_super() {
+ super.test_equalityExpression_missing_RHS_super();
+ }
+
+ @failingTest
+ void test_equalityExpression_precedence_relational_left() {
+ super.test_equalityExpression_precedence_relational_left();
+ }
+
+ @failingTest
+ void test_equalityExpression_precedence_relational_right() {
+ super.test_equalityExpression_precedence_relational_right();
+ }
+
+ @failingTest
+ void test_equalityExpression_super() {
+ super.test_equalityExpression_super();
+ }
+
+ @failingTest
+ void test_expressionList_multiple_end() {
+ super.test_expressionList_multiple_end();
+ }
+
+ @failingTest
+ void test_expressionList_multiple_middle() {
+ super.test_expressionList_multiple_middle();
+ }
+
+ @failingTest
+ void test_expressionList_multiple_start() {
+ super.test_expressionList_multiple_start();
+ }
+
+ @failingTest
+ void test_functionExpression_in_ConstructorFieldInitializer() {
+ super.test_functionExpression_in_ConstructorFieldInitializer();
+ }
+
+ @failingTest
+ void test_functionExpression_named() {
+ super.test_functionExpression_named();
+ }
+
+ @failingTest
+ void test_ifStatement_noElse_statement() {
+ super.test_ifStatement_noElse_statement();
+ }
+
+ @failingTest
+ void test_importDirectivePartial_as() {
+ super.test_importDirectivePartial_as();
+ }
+
+ @failingTest
+ void test_importDirectivePartial_hide() {
+ super.test_importDirectivePartial_hide();
+ }
+
+ @failingTest
+ void test_importDirectivePartial_show() {
+ super.test_importDirectivePartial_show();
+ }
+
+ @failingTest
+ void test_incomplete_conditionalExpression() {
+ super.test_incomplete_conditionalExpression();
+ }
+
+ @failingTest
+ void test_incomplete_constructorInitializers_empty() {
+ super.test_incomplete_constructorInitializers_empty();
+ }
+
+ @failingTest
+ void test_incomplete_constructorInitializers_missingEquals() {
+ super.test_incomplete_constructorInitializers_missingEquals();
+ }
+
+ @failingTest
+ void test_incomplete_constructorInitializers_this() {
+ super.test_incomplete_constructorInitializers_this();
+ }
+
+ @failingTest
+ void test_incomplete_constructorInitializers_thisField() {
+ super.test_incomplete_constructorInitializers_thisField();
+ }
+
+ @failingTest
+ void test_incomplete_constructorInitializers_thisPeriod() {
+ super.test_incomplete_constructorInitializers_thisPeriod();
+ }
+
+ @failingTest
+ void test_incomplete_constructorInitializers_variable() {
+ super.test_incomplete_constructorInitializers_variable();
+ }
+
+ @failingTest
+ void test_incomplete_functionExpression() {
+ super.test_incomplete_functionExpression();
+ }
+
+ @failingTest
+ void test_incomplete_functionExpression2() {
+ super.test_incomplete_functionExpression2();
+ }
+
+ @failingTest
+ void test_incomplete_returnType() {
+ super.test_incomplete_returnType();
+ }
+
+ @failingTest
+ void test_incomplete_topLevelFunction() {
+ super.test_incomplete_topLevelFunction();
+ }
+
+ @failingTest
+ void test_incomplete_topLevelVariable() {
+ super.test_incomplete_topLevelVariable();
+ }
+
+ @failingTest
+ void test_incomplete_topLevelVariable_const() {
+ super.test_incomplete_topLevelVariable_const();
+ }
+
+ @failingTest
+ void test_incomplete_topLevelVariable_final() {
+ super.test_incomplete_topLevelVariable_final();
+ }
+
+ @failingTest
+ void test_incomplete_topLevelVariable_var() {
+ super.test_incomplete_topLevelVariable_var();
+ }
+
+ @failingTest
+ void test_incompleteField_const() {
+ super.test_incompleteField_const();
+ }
+
+ @failingTest
+ void test_incompleteField_final() {
+ super.test_incompleteField_final();
+ }
+
+ @failingTest
+ void test_incompleteField_static() {
+ super.test_incompleteField_static();
+ }
+
+ @failingTest
+ void test_incompleteField_static2() {
+ super.test_incompleteField_static2();
+ }
+
+ @failingTest
+ void test_incompleteField_type() {
+ super.test_incompleteField_type();
+ }
+
+ @failingTest
+ void test_incompleteField_var() {
+ super.test_incompleteField_var();
+ }
+
+ @failingTest
+ void test_incompleteForEach() {
+ super.test_incompleteForEach();
+ }
+
+ @failingTest
+ void test_incompleteLocalVariable_atTheEndOfBlock() {
+ super.test_incompleteLocalVariable_atTheEndOfBlock();
+ }
+
+ @failingTest
+ void test_incompleteLocalVariable_atTheEndOfBlock_modifierOnly() {
+ super.test_incompleteLocalVariable_atTheEndOfBlock_modifierOnly();
+ }
+
+ @failingTest
+ void test_incompleteLocalVariable_beforeIdentifier() {
+ super.test_incompleteLocalVariable_beforeIdentifier();
+ }
+
+ @failingTest
+ void test_incompleteLocalVariable_beforeKeyword() {
+ super.test_incompleteLocalVariable_beforeKeyword();
+ }
+
+ @failingTest
+ void test_incompleteLocalVariable_beforeNextBlock() {
+ super.test_incompleteLocalVariable_beforeNextBlock();
+ }
+
+ @failingTest
+ void test_incompleteLocalVariable_parameterizedType() {
+ super.test_incompleteLocalVariable_parameterizedType();
+ }
+
+ @failingTest
+ void test_incompleteTypeArguments_field() {
+ super.test_incompleteTypeArguments_field();
+ }
+
+ @failingTest
+ void test_incompleteTypeParameters() {
+ super.test_incompleteTypeParameters();
+ }
+
+ @failingTest
+ void test_incompleteTypeParameters2() {
+ super.test_incompleteTypeParameters2();
+ }
+
+ @failingTest
+ void test_invalidFunctionBodyModifier() {
+ super.test_invalidFunctionBodyModifier();
+ }
+
+ @failingTest
+ void test_invalidTypeParameters() {
+ super.test_invalidTypeParameters();
+ }
+
+ @failingTest
+ void test_isExpression_noType() {
+ super.test_isExpression_noType();
+ }
+
+ @failingTest
+ void test_keywordInPlaceOfIdentifier() {
+ super.test_keywordInPlaceOfIdentifier();
+ }
+
+ @failingTest
+ void test_logicalAndExpression_missing_LHS() {
+ super.test_logicalAndExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_logicalAndExpression_missing_LHS_RHS() {
+ super.test_logicalAndExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_logicalAndExpression_missing_RHS() {
+ super.test_logicalAndExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_logicalAndExpression_precedence_bitwiseOr_left() {
+ super.test_logicalAndExpression_precedence_bitwiseOr_left();
+ }
+
+ @failingTest
+ void test_logicalAndExpression_precedence_bitwiseOr_right() {
+ super.test_logicalAndExpression_precedence_bitwiseOr_right();
+ }
+
+ @failingTest
+ void test_logicalOrExpression_missing_LHS() {
+ super.test_logicalOrExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_logicalOrExpression_missing_LHS_RHS() {
+ super.test_logicalOrExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_logicalOrExpression_missing_RHS() {
+ super.test_logicalOrExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_logicalOrExpression_precedence_logicalAnd_left() {
+ super.test_logicalOrExpression_precedence_logicalAnd_left();
+ }
+
+ @failingTest
+ void test_logicalOrExpression_precedence_logicalAnd_right() {
+ super.test_logicalOrExpression_precedence_logicalAnd_right();
+ }
+
+ @failingTest
+ void test_method_missingBody() {
+ super.test_method_missingBody();
+ }
+
+ @failingTest
+ void test_missing_commaInArgumentList() {
+ super.test_missing_commaInArgumentList();
+ }
+
+ @failingTest
+ void test_missingComma_beforeNamedArgument() {
+ super.test_missingComma_beforeNamedArgument();
+ }
+
+ @failingTest
+ void test_missingGet() {
+ super.test_missingGet();
+ }
+
+ @failingTest
+ void test_missingIdentifier_afterAnnotation() {
+ super.test_missingIdentifier_afterAnnotation();
+ }
+
+ @failingTest
+ void test_missingSemicolon_varialeDeclarationList() {
+ super.test_missingSemicolon_varialeDeclarationList();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_missing_LHS() {
+ super.test_multiplicativeExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_missing_LHS_RHS() {
+ super.test_multiplicativeExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_missing_RHS() {
+ super.test_multiplicativeExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_missing_RHS_super() {
+ super.test_multiplicativeExpression_missing_RHS_super();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_precedence_unary_left() {
+ super.test_multiplicativeExpression_precedence_unary_left();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_precedence_unary_right() {
+ super.test_multiplicativeExpression_precedence_unary_right();
+ }
+
+ @failingTest
+ void test_multiplicativeExpression_super() {
+ super.test_multiplicativeExpression_super();
+ }
+
+ @failingTest
+ void test_namedParameterOutsideGroup() {
+ super.test_namedParameterOutsideGroup();
+ }
+
+ @failingTest
+ void test_nonStringLiteralUri_import() {
+ super.test_nonStringLiteralUri_import();
+ }
+
+ @failingTest
+ void test_prefixExpression_missing_operand_minus() {
+ super.test_prefixExpression_missing_operand_minus();
+ }
+
+ @failingTest
+ void test_primaryExpression_argumentDefinitionTest() {
+ super.test_primaryExpression_argumentDefinitionTest();
+ }
+
+ @failingTest
+ void test_propertyAccess_missing_LHS_RHS() {
+ super.test_propertyAccess_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_relationalExpression_missing_LHS() {
+ super.test_relationalExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_relationalExpression_missing_LHS_RHS() {
+ super.test_relationalExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_relationalExpression_missing_RHS() {
+ super.test_relationalExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_relationalExpression_precedence_shift_right() {
+ super.test_relationalExpression_precedence_shift_right();
+ }
+
+ @failingTest
+ void test_shiftExpression_missing_LHS() {
+ super.test_shiftExpression_missing_LHS();
+ }
+
+ @failingTest
+ void test_shiftExpression_missing_LHS_RHS() {
+ super.test_shiftExpression_missing_LHS_RHS();
+ }
+
+ @failingTest
+ void test_shiftExpression_missing_RHS() {
+ super.test_shiftExpression_missing_RHS();
+ }
+
+ @failingTest
+ void test_shiftExpression_missing_RHS_super() {
+ super.test_shiftExpression_missing_RHS_super();
+ }
+
+ @failingTest
+ void test_shiftExpression_precedence_unary_left() {
+ super.test_shiftExpression_precedence_unary_left();
+ }
+
+ @failingTest
+ void test_shiftExpression_precedence_unary_right() {
+ super.test_shiftExpression_precedence_unary_right();
+ }
+
+ @failingTest
+ void test_shiftExpression_super() {
+ super.test_shiftExpression_super();
+ }
+
+ @failingTest
+ void test_typedef_eof() {
+ super.test_typedef_eof();
+ }
+
+ @failingTest
+ void test_unaryPlus() {
+ super.test_unaryPlus();
+ }
+}
+
+@reflectiveTest
+class SimpleParserTest_Forest extends FastaBodyBuilderTestCase
+ with SimpleParserTestMixin {
+ SimpleParserTest_Forest() : super(false);
+
+ @failingTest
+ void test_classDeclaration_complexTypeParam() {
+ super.test_classDeclaration_complexTypeParam();
+ }
+
+ @failingTest
+ void test_parseAnnotation_n1() {
+ super.test_parseAnnotation_n1();
+ }
+
+ @failingTest
+ void test_parseAnnotation_n1_a() {
+ super.test_parseAnnotation_n1_a();
+ }
+
+ @failingTest
+ void test_parseAnnotation_n2() {
+ super.test_parseAnnotation_n2();
+ }
+
+ @failingTest
+ void test_parseAnnotation_n2_a() {
+ super.test_parseAnnotation_n2_a();
+ }
+
+ @failingTest
+ void test_parseAnnotation_n3() {
+ super.test_parseAnnotation_n3();
+ }
+
+ @failingTest
+ void test_parseAnnotation_n3_a() {
+ super.test_parseAnnotation_n3_a();
+ }
+
+ @failingTest
+ void test_parseArgumentList_empty() {
+ super.test_parseArgumentList_empty();
+ }
+
+ @failingTest
+ void test_parseArgumentList_mixed() {
+ super.test_parseArgumentList_mixed();
+ }
+
+ @failingTest
+ void test_parseArgumentList_noNamed() {
+ super.test_parseArgumentList_noNamed();
+ }
+
+ @failingTest
+ void test_parseArgumentList_onlyNamed() {
+ super.test_parseArgumentList_onlyNamed();
+ }
+
+ @failingTest
+ void test_parseArgumentList_trailing_comma() {
+ super.test_parseArgumentList_trailing_comma();
+ }
+
+ @failingTest
+ void test_parseArgumentList_typeArguments() {
+ super.test_parseArgumentList_typeArguments();
+ }
+
+ @failingTest
+ void test_parseArgumentList_typeArguments_none() {
+ super.test_parseArgumentList_typeArguments_none();
+ }
+
+ @failingTest
+ void test_parseArgumentList_typeArguments_prefixed() {
+ super.test_parseArgumentList_typeArguments_prefixed();
+ }
+
+ @failingTest
+ void test_parseCombinators_h() {
+ super.test_parseCombinators_h();
+ }
+
+ @failingTest
+ void test_parseCombinators_hs() {
+ super.test_parseCombinators_hs();
+ }
+
+ @failingTest
+ void test_parseCombinators_hshs() {
+ super.test_parseCombinators_hshs();
+ }
+
+ @failingTest
+ void test_parseCombinators_s() {
+ super.test_parseCombinators_s();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_c() {
+ super.test_parseCommentAndMetadata_c();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_cmc() {
+ super.test_parseCommentAndMetadata_cmc();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_cmcm() {
+ super.test_parseCommentAndMetadata_cmcm();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_cmm() {
+ super.test_parseCommentAndMetadata_cmm();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_m() {
+ super.test_parseCommentAndMetadata_m();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_mcm() {
+ super.test_parseCommentAndMetadata_mcm();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_mcmc() {
+ super.test_parseCommentAndMetadata_mcmc();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_mm() {
+ super.test_parseCommentAndMetadata_mm();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_none() {
+ super.test_parseCommentAndMetadata_none();
+ }
+
+ @failingTest
+ void test_parseCommentAndMetadata_singleLine() {
+ super.test_parseCommentAndMetadata_singleLine();
+ }
+
+ @failingTest
+ void test_parseConfiguration_noOperator_dottedIdentifier() {
+ super.test_parseConfiguration_noOperator_dottedIdentifier();
+ }
+
+ @failingTest
+ void test_parseConfiguration_noOperator_simpleIdentifier() {
+ super.test_parseConfiguration_noOperator_simpleIdentifier();
+ }
+
+ @failingTest
+ void test_parseConfiguration_operator_dottedIdentifier() {
+ super.test_parseConfiguration_operator_dottedIdentifier();
+ }
+
+ @failingTest
+ void test_parseConfiguration_operator_simpleIdentifier() {
+ super.test_parseConfiguration_operator_simpleIdentifier();
+ }
+
+ @failingTest
+ void test_parseConstructorName_named_noPrefix() {
+ super.test_parseConstructorName_named_noPrefix();
+ }
+
+ @failingTest
+ void test_parseConstructorName_named_prefixed() {
+ super.test_parseConstructorName_named_prefixed();
+ }
+
+ @failingTest
+ void test_parseConstructorName_unnamed_noPrefix() {
+ super.test_parseConstructorName_unnamed_noPrefix();
+ }
+
+ @failingTest
+ void test_parseConstructorName_unnamed_prefixed() {
+ super.test_parseConstructorName_unnamed_prefixed();
+ }
+
+ @failingTest
+ void test_parseDocumentationComment_block() {
+ super.test_parseDocumentationComment_block();
+ }
+
+ @failingTest
+ void test_parseDocumentationComment_block_withReference() {
+ super.test_parseDocumentationComment_block_withReference();
+ }
+
+ @failingTest
+ void test_parseDocumentationComment_endOfLine() {
+ super.test_parseDocumentationComment_endOfLine();
+ }
+
+ @failingTest
+ void test_parseExtendsClause() {
+ super.test_parseExtendsClause();
+ }
+
+ @failingTest
+ void test_parseFunctionBody_block() {
+ super.test_parseFunctionBody_block();
+ }
+
+ @failingTest
+ void test_parseFunctionBody_block_async() {
+ super.test_parseFunctionBody_block_async();
+ }
+
+ @failingTest
+ void test_parseFunctionBody_block_asyncGenerator() {
+ super.test_parseFunctionBody_block_asyncGenerator();
+ }
+
+ @failingTest
+ void test_parseFunctionBody_block_syncGenerator() {
+ super.test_parseFunctionBody_block_syncGenerator();
+ }
+
+ @failingTest
+ void test_parseFunctionBody_empty() {
+ super.test_parseFunctionBody_empty();
+ }
+
+ @failingTest
+ void test_parseFunctionBody_expression() {
+ super.test_parseFunctionBody_expression();
+ }
+
+ @failingTest
+ void test_parseFunctionBody_expression_async() {
+ super.test_parseFunctionBody_expression_async();
+ }
+
+ @failingTest
+ void test_parseIdentifierList_multiple() {
+ super.test_parseIdentifierList_multiple();
+ }
+
+ @failingTest
+ void test_parseIdentifierList_single() {
+ super.test_parseIdentifierList_single();
+ }
+
+ @failingTest
+ void test_parseImplementsClause_multiple() {
+ super.test_parseImplementsClause_multiple();
+ }
+
+ @failingTest
+ void test_parseImplementsClause_single() {
+ super.test_parseImplementsClause_single();
+ }
+
+ @failingTest
+ void test_parseInstanceCreation_noKeyword_noPrefix() {
+ super.test_parseInstanceCreation_noKeyword_noPrefix();
+ }
+
+ @failingTest
+ void test_parseInstanceCreation_noKeyword_prefix() {
+ super.test_parseInstanceCreation_noKeyword_prefix();
+ }
+
+ @failingTest
+ void test_parseInstanceCreation_noKeyword_varInit() {
+ super.test_parseInstanceCreation_noKeyword_varInit();
+ }
+
+ @failingTest
+ void test_parseLibraryIdentifier_builtin() {
+ super.test_parseLibraryIdentifier_builtin();
+ }
+
+ @failingTest
+ void test_parseLibraryIdentifier_invalid() {
+ super.test_parseLibraryIdentifier_invalid();
+ }
+
+ @failingTest
+ void test_parseLibraryIdentifier_multiple() {
+ super.test_parseLibraryIdentifier_multiple();
+ }
+
+ @failingTest
+ void test_parseLibraryIdentifier_pseudo() {
+ super.test_parseLibraryIdentifier_pseudo();
+ }
+
+ @failingTest
+ void test_parseLibraryIdentifier_single() {
+ super.test_parseLibraryIdentifier_single();
+ }
+
+ @failingTest
+ void test_parseReturnStatement_value() {
+ super.test_parseReturnStatement_value();
+ }
+
+ @failingTest
+ void test_parseStatement_function_noReturnType() {
+ super.test_parseStatement_function_noReturnType();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_noReturnType_noParameters() {
+ super.test_parseTypeAnnotation_function_noReturnType_noParameters();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_noReturnType_parameters() {
+ super.test_parseTypeAnnotation_function_noReturnType_parameters();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_noReturnType_typeParameters() {
+ super.test_parseTypeAnnotation_function_noReturnType_typeParameters();
+ }
+
+ @failingTest
+ void
+ test_parseTypeAnnotation_function_noReturnType_typeParameters_parameters() {
+ super
+ .test_parseTypeAnnotation_function_noReturnType_typeParameters_parameters();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_returnType_classFunction() {
+ super.test_parseTypeAnnotation_function_returnType_classFunction();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_returnType_function() {
+ super.test_parseTypeAnnotation_function_returnType_function();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_returnType_noParameters() {
+ super.test_parseTypeAnnotation_function_returnType_noParameters();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_returnType_parameters() {
+ super.test_parseTypeAnnotation_function_returnType_parameters();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_returnType_simple() {
+ super.test_parseTypeAnnotation_function_returnType_simple();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_returnType_typeParameters() {
+ super.test_parseTypeAnnotation_function_returnType_typeParameters();
+ }
+
+ @failingTest
+ void
+ test_parseTypeAnnotation_function_returnType_typeParameters_parameters() {
+ super
+ .test_parseTypeAnnotation_function_returnType_typeParameters_parameters();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_function_returnType_withArguments() {
+ super.test_parseTypeAnnotation_function_returnType_withArguments();
+ }
+
+ @failingTest
+ void test_parseTypeAnnotation_named() {
+ super.test_parseTypeAnnotation_named();
+ }
+
+ @failingTest
+ void test_parseTypeArgumentList_empty() {
+ super.test_parseTypeArgumentList_empty();
+ }
+
+ @failingTest
+ void test_parseTypeArgumentList_multiple() {
+ super.test_parseTypeArgumentList_multiple();
+ }
+
+ @failingTest
+ void test_parseTypeArgumentList_nested() {
+ super.test_parseTypeArgumentList_nested();
+ }
+
+ @failingTest
+ void test_parseTypeArgumentList_nested_withComment_double() {
+ super.test_parseTypeArgumentList_nested_withComment_double();
+ }
+
+ @failingTest
+ void test_parseTypeArgumentList_nested_withComment_tripple() {
+ super.test_parseTypeArgumentList_nested_withComment_tripple();
+ }
+
+ @failingTest
+ void test_parseTypeArgumentList_single() {
+ super.test_parseTypeArgumentList_single();
+ }
+
+ @failingTest
+ void test_parseTypeName_parameterized() {
+ super.test_parseTypeName_parameterized();
+ }
+
+ @failingTest
+ void test_parseTypeName_simple() {
+ super.test_parseTypeName_simple();
+ }
+
+ @failingTest
+ void test_parseTypeParameter_bounded_functionType_noReturn() {
+ super.test_parseTypeParameter_bounded_functionType_noReturn();
+ }
+
+ @failingTest
+ void test_parseTypeParameter_bounded_functionType_return() {
+ super.test_parseTypeParameter_bounded_functionType_return();
+ }
+
+ @failingTest
+ void test_parseTypeParameter_bounded_generic() {
+ super.test_parseTypeParameter_bounded_generic();
+ }
+
+ @failingTest
+ void test_parseTypeParameter_bounded_simple() {
+ super.test_parseTypeParameter_bounded_simple();
+ }
+
+ @failingTest
+ void test_parseTypeParameter_simple() {
+ super.test_parseTypeParameter_simple();
+ }
+
+ @failingTest
+ void test_parseTypeParameterList_multiple() {
+ super.test_parseTypeParameterList_multiple();
+ }
+
+ @failingTest
+ void test_parseTypeParameterList_parameterizedWithTrailingEquals() {
+ super.test_parseTypeParameterList_parameterizedWithTrailingEquals();
+ }
+
+ @failingTest
+ void test_parseTypeParameterList_parameterizedWithTrailingEquals2() {
+ super.test_parseTypeParameterList_parameterizedWithTrailingEquals2();
+ }
+
+ @failingTest
+ void test_parseTypeParameterList_single() {
+ super.test_parseTypeParameterList_single();
+ }
+
+ @failingTest
+ void test_parseTypeParameterList_withTrailingEquals() {
+ super.test_parseTypeParameterList_withTrailingEquals();
+ }
+
+ @failingTest
+ void test_parseVariableDeclaration_equals() {
+ super.test_parseVariableDeclaration_equals();
+ }
+
+ @failingTest
+ void test_parseVariableDeclaration_noEquals() {
+ super.test_parseVariableDeclaration_noEquals();
+ }
+
+ @failingTest
+ void test_parseWithClause_multiple() {
+ super.test_parseWithClause_multiple();
+ }
+
+ @failingTest
+ void test_parseWithClause_single() {
+ super.test_parseWithClause_single();
+ }
+}
+
@reflectiveTest
class StatementParserTest_Forest extends FastaBodyBuilderTestCase
with StatementParserTestMixin {
@@ -1032,16 +5038,6 @@
}
@failingTest
- void test_parseBlock_empty() {
- super.test_parseBlock_empty();
- }
-
- @failingTest
- void test_parseBlock_nonEmpty() {
- super.test_parseBlock_nonEmpty();
- }
-
- @failingTest
void test_parseBreakStatement_label() {
super.test_parseBreakStatement_label();
}
@@ -1067,11 +5063,6 @@
}
@failingTest
- void test_parseEmptyStatement() {
- super.test_parseEmptyStatement();
- }
-
- @failingTest
void test_parseForStatement_each_await() {
super.test_parseForStatement_each_await();
}
@@ -1177,6 +5168,13 @@
}
@failingTest
+ void test_parseIfStatement_else_emptyStatements() {
+ super.test_parseIfStatement_else_emptyStatements();
+ fail(
+ 'This passes under Dart 1, but fails under Dart 2 because of a cast exception');
+ }
+
+ @failingTest
void test_parseIfStatement_else_statement() {
super.test_parseIfStatement_else_statement();
}
@@ -1192,21 +5190,6 @@
}
@failingTest
- void test_parseNonLabeledStatement_const_list_empty() {
- super.test_parseNonLabeledStatement_const_list_empty();
- }
-
- @failingTest
- void test_parseNonLabeledStatement_const_list_nonEmpty() {
- super.test_parseNonLabeledStatement_const_list_nonEmpty();
- }
-
- @failingTest
- void test_parseNonLabeledStatement_const_map_empty() {
- super.test_parseNonLabeledStatement_const_map_empty();
- }
-
- @failingTest
void test_parseNonLabeledStatement_const_map_nonEmpty() {
super.test_parseNonLabeledStatement_const_map_nonEmpty();
}
@@ -1227,11 +5210,6 @@
}
@failingTest
- void test_parseNonLabeledStatement_false() {
- super.test_parseNonLabeledStatement_false();
- }
-
- @failingTest
void test_parseNonLabeledStatement_functionDeclaration() {
super.test_parseNonLabeledStatement_functionDeclaration();
}
@@ -1262,21 +5240,11 @@
}
@failingTest
- void test_parseNonLabeledStatement_null() {
- super.test_parseNonLabeledStatement_null();
- }
-
- @failingTest
void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() {
super.test_parseNonLabeledStatement_startingWithBuiltInIdentifier();
}
@failingTest
- void test_parseNonLabeledStatement_true() {
- super.test_parseNonLabeledStatement_true();
- }
-
- @failingTest
void test_parseNonLabeledStatement_typeCast() {
super.test_parseNonLabeledStatement_typeCast();
}
@@ -1359,11 +5327,6 @@
}
@failingTest
- void test_parseStatement_functionDeclaration_noReturnType() {
- super.test_parseStatement_functionDeclaration_noReturnType();
- }
-
- @failingTest
void
test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
super
@@ -1451,11 +5414,6 @@
}
@failingTest
- void test_parseTryStatement_finally() {
- super.test_parseTryStatement_finally();
- }
-
- @failingTest
void test_parseTryStatement_multiple() {
super.test_parseTryStatement_multiple();
}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 7c45cac..611ee186 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1573,7 +1573,7 @@
createParser('external const factory C();');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_parseConstructor_factory_named() {
@@ -2542,28 +2542,16 @@
errors: [expectedError(ParserErrorCode.ABSTRACT_TYPEDEF, 0, 8)]);
}
- void test_annotationOnEnumConstant_first() {
- parseCompilationUnit("enum E { @override C }", errors: [
- expectedError(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, 9, 9)
- ]);
- }
-
- void test_annotationOnEnumConstant_middle() {
- parseCompilationUnit("enum E { C, @override D, E }", errors: [
- expectedError(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, 12, 9)
- ]);
- }
-
void test_breakOutsideOfLoop_breakInDoStatement() {
DoStatement statement = parseStatement('do {break;} while (x);');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_breakOutsideOfLoop_breakInForStatement() {
Statement statement = parseStatement('for (; x;) {break;}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_breakOutsideOfLoop_breakInIfStatement() {
@@ -2576,13 +2564,13 @@
void test_breakOutsideOfLoop_breakInSwitchStatement() {
SwitchStatement statement = parseStatement('switch (x) {case 1: break;}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_breakOutsideOfLoop_breakInWhileStatement() {
WhileStatement statement = parseStatement('while (x) {break;}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_breakOutsideOfLoop_functionExpression_inALoop() {
@@ -2613,11 +2601,16 @@
void test_classTypeAlias_abstractAfterEq() {
// This syntax has been removed from the language in favor of
// "abstract class A = B with C;" (issue 18098).
- createParser('class A = abstract B with C;');
+ createParser('class A = abstract B with C;', expectedEndOffset: 21);
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
listener.assertErrors(usingFastaParser
- ? [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 10, 8)]
+ ? [
+ expectedError(
+ CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 10, 8),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 19, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 21, 4)
+ ]
: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 0),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 0)
@@ -2742,13 +2735,13 @@
void test_continueOutsideOfLoop_continueInDoStatement() {
DoStatement statement = parseStatement('do {continue;} while (x);');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_continueOutsideOfLoop_continueInForStatement() {
Statement statement = parseStatement('for (; x;) {continue;}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_continueOutsideOfLoop_continueInIfStatement() {
@@ -2762,13 +2755,13 @@
SwitchStatement statement =
parseStatement('switch (x) {case 1: continue a;}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_continueOutsideOfLoop_continueInWhileStatement() {
WhileStatement statement = parseStatement('while (x) {continue;}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_continueOutsideOfLoop_functionExpression_inALoop() {
@@ -2793,14 +2786,14 @@
SwitchStatement statement =
parseStatement('switch (x) {case 1: continue a;}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_continueWithoutLabelInCase_noError_switchInLoop() {
WhileStatement statement =
parseStatement('while (a) { switch (b) {default: continue;}}');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_covariantAfterVar() {
@@ -4175,11 +4168,11 @@
parseCompilationUnit("typedef var Function(var arg);",
errors: usingFastaParser
? [
- expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 8, 3),
- expectedError(ParserErrorCode.VAR_AND_TYPE, 21, 3),
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, 29, 1),
- expectedError(
- ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, 29, 1),
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
+ expectedError(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, 8, 3),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 3),
+ expectedError(ParserErrorCode.VAR_RETURN_TYPE, 8, 3),
+ expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 29, 1),
]
: [
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
@@ -4189,6 +4182,31 @@
]);
}
+ void test_invalidTypedef2() {
+ // https://github.com/dart-lang/sdk/issues/31171
+ parseCompilationUnit(
+ "typedef T = typedef F = Map<String, dynamic> Function();",
+ errors: usingFastaParser
+ ? [
+ expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 7),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 7),
+ expectedError(
+ ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, 10, 1),
+ ]
+ : [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 7),
+ expectedError(
+ ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, 20, 1),
+ expectedError(
+ ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 20, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 36, 7),
+ expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 43, 1),
+ expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 43, 1),
+ expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 55, 1),
+ expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 55, 1),
+ ]);
+ }
+
void test_invalidUnicodeEscape_incomplete_noDigits() {
Expression expression = parseStringLiteral("'\\u{'");
expectNotNullIfNoErrors(expression);
@@ -5428,7 +5446,7 @@
createParser('get x => 7;');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
- listener.assertNoErrors();
+ assertNoErrors();
expect(member, new isInstanceOf<FunctionDeclaration>());
FunctionDeclaration function = member;
expect(function.functionExpression.parameters, isNull);
@@ -5513,13 +5531,9 @@
}
void test_typedef_namedFunction() {
- // TODO(brianwilkerson) Improve recovery for this case.
parseCompilationUnit('typedef void Function();',
codes: usingFastaParser
- ? [
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.MISSING_TYPEDEF_PARAMETERS
- ]
+ ? [ParserErrorCode.MISSING_IDENTIFIER]
: [
ParserErrorCode.UNEXPECTED_TOKEN,
ParserErrorCode.MISSING_IDENTIFIER,
@@ -5565,9 +5579,10 @@
}
void test_unexpectedToken_endOfFieldDeclarationStatement() {
- parseStatement("String s = (null));");
- listener
- .assertErrors([expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 1)]);
+ parseStatement("String s = (null));", expectedEndOffset: 17);
+ listener.assertErrors(usingFastaParser
+ ? [expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1)]
+ : [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 1)]);
}
void test_unexpectedToken_invalidPostfixExpression() {
@@ -5805,21 +5820,21 @@
NormalFormalParameter parameter =
parseFormalParameterList('(void a)').parameters[0];
expectNotNullIfNoErrors(parameter);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_voidVariable_parseClassMember_initializer() {
createParser('void x = 0;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_voidVariable_parseClassMember_noInitializer() {
createParser('void x;');
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_voidVariable_parseCompilationUnit_initializer() {
@@ -5834,24 +5849,24 @@
createParser('void a = 0;');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_voidVariable_parseCompilationUnitMember_noInitializer() {
createParser('void a;');
CompilationUnitMember member = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(member);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_voidVariable_statement_initializer() {
parseStatement("void x = 0;");
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_voidVariable_statement_noInitializer() {
parseStatement("void x;");
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_withBeforeExtends() {
@@ -9731,13 +9746,27 @@
@reflectiveTest
class NonErrorParserTest extends ParserTestCase {
+ void test_annotationOnEnumConstant_first() {
+ createParser("enum E { @override C }");
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ expectNotNullIfNoErrors(unit);
+ assertNoErrors();
+ }
+
+ void test_annotationOnEnumConstant_middle() {
+ createParser("enum E { C, @override D, E }");
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ expectNotNullIfNoErrors(unit);
+ assertNoErrors();
+ }
+
void test_staticMethod_notParsingFunctionBodies() {
ParserTestCase.parseFunctionBodies = false;
try {
createParser('class C { static void m() {} }');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
} finally {
ParserTestCase.parseFunctionBodies = true;
}
@@ -10902,7 +10931,7 @@
// and instead parseExpressionList is mapped to parseExpression('[$code]')
// which allows and ignores an optional trailing comma.
if (usingFastaParser) {
- listener.assertNoErrors();
+ assertNoErrors();
expect(result, hasLength(3));
} else {
listener.assertErrors(
@@ -12319,7 +12348,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('new a.b', 7);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
PrefixedIdentifier prefixedIdentifier = reference.identifier;
SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12337,7 +12366,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('new a', 5);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
SimpleIdentifier identifier = reference.identifier;
expect(identifier.token, isNotNull);
@@ -12349,7 +12378,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('operator ==', 5);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
SimpleIdentifier identifier = reference.identifier;
expect(identifier.token, isNotNull);
@@ -12362,7 +12391,7 @@
CommentReference reference =
parser.parseCommentReference('Object.operator==', 7);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
PrefixedIdentifier prefixedIdentifier = reference.identifier;
SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12380,7 +12409,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('==', 5);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
SimpleIdentifier identifier = reference.identifier;
expect(identifier.token, isNotNull);
@@ -12392,7 +12421,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('Object.==', 7);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
PrefixedIdentifier prefixedIdentifier = reference.identifier;
SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12410,7 +12439,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('a.b', 7);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
PrefixedIdentifier prefixedIdentifier = reference.identifier;
SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12428,7 +12457,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('a', 5);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
SimpleIdentifier identifier = reference.identifier;
expect(identifier.token, isNotNull);
@@ -12440,7 +12469,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('', 5);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
SimpleIdentifier identifier = reference.identifier;
expect(identifier, isNotNull);
@@ -12461,7 +12490,7 @@
createParser('');
CommentReference reference = parser.parseCommentReference('this', 5);
expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
+ assertNoErrors();
SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
(obj) => obj is SimpleIdentifier,
SimpleIdentifier,
@@ -12478,7 +12507,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
List<Token> tokenReferences = token.references;
expect(references, hasLength(2));
expect(tokenReferences, hasLength(2));
@@ -12511,7 +12540,7 @@
List<CommentReference> references =
parser.parseCommentReferences(<DocumentationCommentToken>[docToken]);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(docToken.references, hasLength(1));
expect(references, hasLength(1));
Token referenceToken = docToken.references[0];
@@ -12534,7 +12563,7 @@
List<CommentReference> references =
parser.parseCommentReferences(<DocumentationCommentToken>[docToken]);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(docToken.references, hasLength(1));
expect(references, hasLength(1));
Token referenceToken = docToken.references[0];
@@ -12560,7 +12589,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(3));
CommentReference reference = references[0];
expect(reference, isNotNull);
@@ -12584,7 +12613,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, isEmpty);
}
@@ -12598,7 +12627,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, isEmpty);
}
@@ -12610,7 +12639,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(1));
CommentReference reference = references[0];
expect(reference, isNotNull);
@@ -12626,7 +12655,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(1));
CommentReference reference = references[0];
expect(reference, isNotNull);
@@ -12652,7 +12681,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, isEmpty);
}
@@ -12672,7 +12701,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, isEmpty);
}
@@ -12684,7 +12713,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(2));
}
@@ -12696,7 +12725,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(1));
CommentReference reference = references[0];
expect(reference, isNotNull);
@@ -12712,7 +12741,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(1));
CommentReference reference = references[0];
expect(reference, isNotNull);
@@ -12728,7 +12757,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(1));
CommentReference reference = references[0];
expect(reference, isNotNull);
@@ -12744,7 +12773,7 @@
createParser('');
List<CommentReference> references = parser.parseCommentReferences(tokens);
expectNotNullIfNoErrors(references);
- listener.assertNoErrors();
+ assertNoErrors();
expect(references, hasLength(1));
CommentReference reference = references[0];
expect(reference, isNotNull);
@@ -12756,7 +12785,7 @@
createParser('a.b.c');
DottedName name = parser.parseDottedName();
expectNotNullIfNoErrors(name);
- listener.assertNoErrors();
+ assertNoErrors();
expectDottedName(name, ["a", "b", "c"]);
}
@@ -12764,7 +12793,7 @@
createParser('a');
DottedName name = parser.parseDottedName();
expectNotNullIfNoErrors(name);
- listener.assertNoErrors();
+ assertNoErrors();
expectDottedName(name, ["a"]);
}
@@ -12772,7 +12801,7 @@
createParser('const int Function(int) f');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12784,7 +12813,7 @@
createParser('const A a');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12796,7 +12825,7 @@
createParser('const');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12808,7 +12837,7 @@
createParser('final int Function(int) f');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12820,7 +12849,7 @@
createParser('final A a');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12832,7 +12861,7 @@
createParser('final');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12844,7 +12873,7 @@
createParser('final p.A a');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12856,7 +12885,7 @@
createParser('int Function(int) f');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12865,7 +12894,7 @@
createParser('A<B> a');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12874,7 +12903,7 @@
createParser('p.A a');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12883,7 +12912,7 @@
createParser('p.A,');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12892,7 +12921,7 @@
createParser('p.A<B> a');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12901,7 +12930,7 @@
createParser('A a');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12911,7 +12940,7 @@
FinalConstVarOrType result =
parser.parseFinalConstVarOrType(false, inFunctionType: true);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12920,7 +12949,7 @@
createParser('var');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
Token keyword = result.keyword;
expect(keyword, isNotNull);
expect(keyword.type.isKeyword, true);
@@ -12932,7 +12961,7 @@
createParser('void f()');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12941,7 +12970,7 @@
createParser('void x');
FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
expectNotNullIfNoErrors(result);
- listener.assertNoErrors();
+ assertNoErrors();
expect(result.keyword, isNull);
expect(result.type, isNotNull);
}
@@ -12959,7 +12988,7 @@
createParser('{}');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
}
@@ -12981,7 +13010,7 @@
createParser('{ {} }');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
}
@@ -12990,7 +13019,7 @@
createParser('=> y;');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
}
@@ -12998,7 +13027,7 @@
createParser('abstract A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.abstractKeyword, isNotNull);
}
@@ -13006,7 +13035,7 @@
createParser('const A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.constKeyword, isNotNull);
}
@@ -13014,7 +13043,7 @@
createParser('covariant A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.covariantKeyword, isNotNull);
}
@@ -13022,7 +13051,7 @@
createParser('external A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.externalKeyword, isNotNull);
}
@@ -13030,7 +13059,7 @@
createParser('factory A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.factoryKeyword, isNotNull);
}
@@ -13038,7 +13067,7 @@
createParser('final A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.finalKeyword, isNotNull);
}
@@ -13046,7 +13075,7 @@
createParser('static A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.staticKeyword, isNotNull);
}
@@ -13054,7 +13083,7 @@
createParser('var A');
Modifiers modifiers = parser.parseModifiers();
expectNotNullIfNoErrors(modifiers);
- listener.assertNoErrors();
+ assertNoErrors();
expect(modifiers.varKeyword, isNotNull);
}
@@ -13067,7 +13096,7 @@
createParser('List<int>?');
TypeName typeName = parser.parseTypeName(false);
expectNotNullIfNoErrors(typeName);
- listener.assertNoErrors();
+ assertNoErrors();
expect(typeName.name, isNotNull);
expect(typeName.typeArguments, isNotNull);
expect(typeName.question, isNotNull);
@@ -13078,7 +13107,7 @@
createParser('String?');
TypeName typeName = parser.parseTypeName(false);
expectNotNullIfNoErrors(typeName);
- listener.assertNoErrors();
+ assertNoErrors();
expect(typeName.name, isNotNull);
expect(typeName.typeArguments, isNull);
expect(typeName.question, isNotNull);
@@ -13089,7 +13118,7 @@
createParser('A extends B?');
TypeParameter parameter = parser.parseTypeParameter();
expectNotNullIfNoErrors(parameter);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameter.bound, new isInstanceOf<TypeName>());
expect(parameter.extendsKeyword, isNotNull);
expect(parameter.name, isNotNull);
@@ -13240,7 +13269,7 @@
String _computeStringValue(String lexeme, bool first, bool last) {
createParser('');
String value = parser.computeStringValue(lexeme, first, last);
- listener.assertNoErrors();
+ assertNoErrors();
return value;
}
@@ -13407,7 +13436,7 @@
createParser('@A');
Annotation annotation = parser.parseAnnotation();
expectNotNullIfNoErrors(annotation);
- listener.assertNoErrors();
+ assertNoErrors();
expect(annotation.atSign, isNotNull);
expect(annotation.name, isNotNull);
expect(annotation.period, isNull);
@@ -13419,7 +13448,7 @@
createParser('@A(x,y)');
Annotation annotation = parser.parseAnnotation();
expectNotNullIfNoErrors(annotation);
- listener.assertNoErrors();
+ assertNoErrors();
expect(annotation.atSign, isNotNull);
expect(annotation.name, isNotNull);
expect(annotation.period, isNull);
@@ -13431,7 +13460,7 @@
createParser('@A.B');
Annotation annotation = parser.parseAnnotation();
expectNotNullIfNoErrors(annotation);
- listener.assertNoErrors();
+ assertNoErrors();
expect(annotation.atSign, isNotNull);
expect(annotation.name, isNotNull);
expect(annotation.period, isNull);
@@ -13443,7 +13472,7 @@
createParser('@A.B(x,y)');
Annotation annotation = parser.parseAnnotation();
expectNotNullIfNoErrors(annotation);
- listener.assertNoErrors();
+ assertNoErrors();
expect(annotation.atSign, isNotNull);
expect(annotation.name, isNotNull);
expect(annotation.period, isNull);
@@ -13455,7 +13484,7 @@
createParser('@A.B.C');
Annotation annotation = parser.parseAnnotation();
expectNotNullIfNoErrors(annotation);
- listener.assertNoErrors();
+ assertNoErrors();
expect(annotation.atSign, isNotNull);
expect(annotation.name, isNotNull);
expect(annotation.period, isNotNull);
@@ -13467,7 +13496,7 @@
createParser('@A.B.C(x,y)');
Annotation annotation = parser.parseAnnotation();
expectNotNullIfNoErrors(annotation);
- listener.assertNoErrors();
+ assertNoErrors();
expect(annotation.atSign, isNotNull);
expect(annotation.name, isNotNull);
expect(annotation.period, isNotNull);
@@ -13479,7 +13508,7 @@
createParser('()');
ArgumentList argumentList = parser.parseArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
NodeList<Expression> arguments = argumentList.arguments;
expect(arguments, hasLength(0));
}
@@ -13488,7 +13517,7 @@
createParser('(w, x, y: y, z: z)');
ArgumentList argumentList = parser.parseArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
NodeList<Expression> arguments = argumentList.arguments;
expect(arguments, hasLength(4));
}
@@ -13497,7 +13526,7 @@
createParser('(x, y, z)');
ArgumentList argumentList = parser.parseArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
NodeList<Expression> arguments = argumentList.arguments;
expect(arguments, hasLength(3));
}
@@ -13506,7 +13535,7 @@
createParser('(x: x, y: y)');
ArgumentList argumentList = parser.parseArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
NodeList<Expression> arguments = argumentList.arguments;
expect(arguments, hasLength(2));
}
@@ -13515,16 +13544,43 @@
createParser('(x, y, z,)');
ArgumentList argumentList = parser.parseArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
NodeList<Expression> arguments = argumentList.arguments;
expect(arguments, hasLength(3));
}
+ void test_parseArgumentList_typeArguments() {
+ createParser('(a<b,c>(d))');
+ ArgumentList argumentList = parser.parseArgumentList();
+ expectNotNullIfNoErrors(argumentList);
+ assertNoErrors();
+ NodeList<Expression> arguments = argumentList.arguments;
+ expect(arguments, hasLength(1));
+ }
+
+ void test_parseArgumentList_typeArguments_prefixed() {
+ createParser('(a<b,p.c>(d))');
+ ArgumentList argumentList = parser.parseArgumentList();
+ expectNotNullIfNoErrors(argumentList);
+ assertNoErrors();
+ NodeList<Expression> arguments = argumentList.arguments;
+ expect(arguments, hasLength(1));
+ }
+
+ void test_parseArgumentList_typeArguments_none() {
+ createParser('(a<b,p.q.c>(d))');
+ ArgumentList argumentList = parser.parseArgumentList();
+ expectNotNullIfNoErrors(argumentList);
+ assertNoErrors();
+ NodeList<Expression> arguments = argumentList.arguments;
+ expect(arguments, hasLength(2));
+ }
+
void test_parseCombinators_h() {
createParser('hide a');
List<Combinator> combinators = parser.parseCombinators();
expectNotNullIfNoErrors(combinators);
- listener.assertNoErrors();
+ assertNoErrors();
expect(combinators, hasLength(1));
HideCombinator combinator = combinators[0] as HideCombinator;
expect(combinator, isNotNull);
@@ -13536,7 +13592,7 @@
createParser('hide a show b');
List<Combinator> combinators = parser.parseCombinators();
expectNotNullIfNoErrors(combinators);
- listener.assertNoErrors();
+ assertNoErrors();
expect(combinators, hasLength(2));
HideCombinator hideCombinator = combinators[0] as HideCombinator;
expect(hideCombinator, isNotNull);
@@ -13552,7 +13608,7 @@
createParser('hide a show b hide c show d');
List<Combinator> combinators = parser.parseCombinators();
expectNotNullIfNoErrors(combinators);
- listener.assertNoErrors();
+ assertNoErrors();
expect(combinators, hasLength(4));
}
@@ -13560,7 +13616,7 @@
createParser('show a');
List<Combinator> combinators = parser.parseCombinators();
expectNotNullIfNoErrors(combinators);
- listener.assertNoErrors();
+ assertNoErrors();
expect(combinators, hasLength(1));
ShowCombinator combinator = combinators[0] as ShowCombinator;
expect(combinator, isNotNull);
@@ -13572,7 +13628,7 @@
createParser('/** 1 */ class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNotNull);
expect(declaration.metadata, isEmpty);
@@ -13582,7 +13638,7 @@
createParser('/** 1 */ @A /** 2 */ class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNotNull);
expect(declaration.metadata, hasLength(1));
@@ -13592,7 +13648,7 @@
createParser('/** 1 */ @A /** 2 */ @B class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNotNull);
expect(declaration.metadata, hasLength(2));
@@ -13602,7 +13658,7 @@
createParser('/** 1 */ @A @B class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNotNull);
expect(declaration.metadata, hasLength(2));
@@ -13612,7 +13668,7 @@
createParser('@A class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNull);
expect(declaration.metadata, hasLength(1));
@@ -13622,7 +13678,7 @@
createParser('@A /** 1 */ @B class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNotNull);
expect(declaration.metadata, hasLength(2));
@@ -13632,7 +13688,7 @@
createParser('@A /** 1 */ @B /** 2 */ class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNotNull);
expect(declaration.documentationComment.tokens[0].lexeme, contains('2'));
@@ -13643,7 +13699,7 @@
createParser('@A @B(x) class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNull);
expect(declaration.metadata, hasLength(2));
@@ -13653,7 +13709,7 @@
createParser('class C {}');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNull);
expect(declaration.metadata, isEmpty);
@@ -13667,7 +13723,7 @@
''');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertNoErrors();
+ assertNoErrors();
ClassDeclaration declaration = unit.declarations[0];
expect(declaration.documentationComment, isNotNull);
expect(declaration.metadata, isEmpty);
@@ -13677,7 +13733,7 @@
createParser("if (a.b) 'c.dart'");
Configuration configuration = parser.parseConfiguration();
expectNotNullIfNoErrors(configuration);
- listener.assertNoErrors();
+ assertNoErrors();
expect(configuration.ifKeyword, isNotNull);
expect(configuration.leftParenthesis, isNotNull);
expectDottedName(configuration.name, ["a", "b"]);
@@ -13691,7 +13747,7 @@
createParser("if (a) 'b.dart'");
Configuration configuration = parser.parseConfiguration();
expectNotNullIfNoErrors(configuration);
- listener.assertNoErrors();
+ assertNoErrors();
expect(configuration.ifKeyword, isNotNull);
expect(configuration.leftParenthesis, isNotNull);
expectDottedName(configuration.name, ["a"]);
@@ -13705,7 +13761,7 @@
createParser("if (a.b == 'c') 'd.dart'");
Configuration configuration = parser.parseConfiguration();
expectNotNullIfNoErrors(configuration);
- listener.assertNoErrors();
+ assertNoErrors();
expect(configuration.ifKeyword, isNotNull);
expect(configuration.leftParenthesis, isNotNull);
expectDottedName(configuration.name, ["a", "b"]);
@@ -13719,7 +13775,7 @@
createParser("if (a == 'b') 'c.dart'");
Configuration configuration = parser.parseConfiguration();
expectNotNullIfNoErrors(configuration);
- listener.assertNoErrors();
+ assertNoErrors();
expect(configuration.ifKeyword, isNotNull);
expect(configuration.leftParenthesis, isNotNull);
expectDottedName(configuration.name, ["a"]);
@@ -13732,7 +13788,7 @@
void test_parseConstructorName_named_noPrefix() {
ConstructorName name = parseConstructorName('A.n');
expectNotNullIfNoErrors(name);
- listener.assertNoErrors();
+ assertNoErrors();
expect(name.type, isNotNull);
expect(name.period, isNull);
expect(name.name, isNull);
@@ -13741,7 +13797,7 @@
void test_parseConstructorName_named_prefixed() {
ConstructorName name = parseConstructorName('p.A.n');
expectNotNullIfNoErrors(name);
- listener.assertNoErrors();
+ assertNoErrors();
expect(name.type, isNotNull);
expect(name.period, isNotNull);
expect(name.name, isNotNull);
@@ -13750,7 +13806,7 @@
void test_parseConstructorName_unnamed_noPrefix() {
ConstructorName name = parseConstructorName('A');
expectNotNullIfNoErrors(name);
- listener.assertNoErrors();
+ assertNoErrors();
expect(name.type, isNotNull);
expect(name.period, isNull);
expect(name.name, isNull);
@@ -13759,7 +13815,7 @@
void test_parseConstructorName_unnamed_prefixed() {
ConstructorName name = parseConstructorName('p.A');
expectNotNullIfNoErrors(name);
- listener.assertNoErrors();
+ assertNoErrors();
expect(name.type, isNotNull);
expect(name.period, isNull);
expect(name.name, isNull);
@@ -13770,7 +13826,7 @@
CompilationUnit unit = parser.parseCompilationUnit2();
Comment comment = unit.declarations[0].documentationComment;
expectNotNullIfNoErrors(comment);
- listener.assertNoErrors();
+ assertNoErrors();
expect(comment.isBlock, isFalse);
expect(comment.isDocumentation, isTrue);
expect(comment.isEndOfLine, isFalse);
@@ -13781,7 +13837,7 @@
CompilationUnit unit = parser.parseCompilationUnit2();
Comment comment = unit.declarations[0].documentationComment;
expectNotNullIfNoErrors(comment);
- listener.assertNoErrors();
+ assertNoErrors();
expect(comment.isBlock, isFalse);
expect(comment.isDocumentation, isTrue);
expect(comment.isEndOfLine, isFalse);
@@ -13797,7 +13853,7 @@
CompilationUnit unit = parser.parseCompilationUnit2();
Comment comment = unit.declarations[0].documentationComment;
expectNotNullIfNoErrors(comment);
- listener.assertNoErrors();
+ assertNoErrors();
expect(comment.isBlock, isFalse);
expect(comment.isDocumentation, isTrue);
expect(comment.isEndOfLine, isFalse);
@@ -13806,7 +13862,7 @@
void test_parseExtendsClause() {
ExtendsClause clause = parseExtendsClause('extends B');
expectNotNullIfNoErrors(clause);
- listener.assertNoErrors();
+ assertNoErrors();
expect(clause.extendsKeyword, isNotNull);
expect(clause.superclass, isNotNull);
expect(clause.superclass, new isInstanceOf<TypeName>());
@@ -13816,7 +13872,7 @@
createParser('{}');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<BlockFunctionBody>());
BlockFunctionBody body = functionBody;
expect(body.keyword, isNull);
@@ -13831,7 +13887,7 @@
createParser('async {}');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<BlockFunctionBody>());
BlockFunctionBody body = functionBody;
expect(body.keyword, isNotNull);
@@ -13847,7 +13903,7 @@
createParser('async* {}');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<BlockFunctionBody>());
BlockFunctionBody body = functionBody;
expect(body.keyword, isNotNull);
@@ -13863,7 +13919,7 @@
createParser('sync* {}');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<BlockFunctionBody>());
BlockFunctionBody body = functionBody;
expect(body.keyword, isNotNull);
@@ -13879,7 +13935,7 @@
createParser(';');
FunctionBody functionBody = parser.parseFunctionBody(true, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
EmptyFunctionBody body = functionBody;
expect(body.semicolon, isNotNull);
@@ -13889,7 +13945,7 @@
createParser('=> y;');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<ExpressionFunctionBody>());
ExpressionFunctionBody body = functionBody;
expect(body.keyword, isNull);
@@ -13905,7 +13961,7 @@
createParser('async => y;');
FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
expectNotNullIfNoErrors(functionBody);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionBody, new isInstanceOf<ExpressionFunctionBody>());
ExpressionFunctionBody body = functionBody;
expect(body.keyword, isNotNull);
@@ -13921,21 +13977,21 @@
void test_parseIdentifierList_multiple() {
List<SimpleIdentifier> list = parseIdentifierList('a, b, c');
expectNotNullIfNoErrors(list);
- listener.assertNoErrors();
+ assertNoErrors();
expect(list, hasLength(3));
}
void test_parseIdentifierList_single() {
List<SimpleIdentifier> list = parseIdentifierList('a');
expectNotNullIfNoErrors(list);
- listener.assertNoErrors();
+ assertNoErrors();
expect(list, hasLength(1));
}
void test_parseImplementsClause_multiple() {
ImplementsClause clause = parseImplementsClause('implements A, B, C');
expectNotNullIfNoErrors(clause);
- listener.assertNoErrors();
+ assertNoErrors();
expect(clause.interfaces, hasLength(3));
expect(clause.implementsKeyword, isNotNull);
}
@@ -13943,7 +13999,7 @@
void test_parseImplementsClause_single() {
ImplementsClause clause = parseImplementsClause('implements A');
expectNotNullIfNoErrors(clause);
- listener.assertNoErrors();
+ assertNoErrors();
expect(clause.interfaces, hasLength(1));
expect(clause.implementsKeyword, isNotNull);
}
@@ -14003,7 +14059,7 @@
String name = "deferred";
LibraryIdentifier identifier = parseLibraryIdentifier(name);
expectNotNullIfNoErrors(identifier);
- listener.assertNoErrors();
+ assertNoErrors();
expect(identifier.name, name);
expect(identifier.beginToken.type.isBuiltIn, isTrue);
}
@@ -14023,7 +14079,7 @@
String name = "a.b.c";
LibraryIdentifier identifier = parseLibraryIdentifier(name);
expectNotNullIfNoErrors(identifier);
- listener.assertNoErrors();
+ assertNoErrors();
expect(identifier.name, name);
}
@@ -14031,7 +14087,7 @@
String name = "await";
LibraryIdentifier identifier = parseLibraryIdentifier(name);
expectNotNullIfNoErrors(identifier);
- listener.assertNoErrors();
+ assertNoErrors();
expect(identifier.name, name);
expect(identifier.beginToken.type.isPseudo, isTrue);
}
@@ -14040,7 +14096,7 @@
String name = "a";
LibraryIdentifier identifier = parseLibraryIdentifier(name);
expectNotNullIfNoErrors(identifier);
- listener.assertNoErrors();
+ assertNoErrors();
expect(identifier.name, name);
}
@@ -14051,7 +14107,7 @@
void test_parseReturnStatement_noValue() {
ReturnStatement statement = parseStatement('return;');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
expect(statement.returnKeyword, isNotNull);
expect(statement.expression, isNull);
expect(statement.semicolon, isNotNull);
@@ -14060,7 +14116,7 @@
void test_parseReturnStatement_value() {
ReturnStatement statement = parseStatement('return x;');
expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
+ assertNoErrors();
expect(statement.returnKeyword, isNotNull);
expect(statement.expression, isNotNull);
expect(statement.semicolon, isNotNull);
@@ -14092,7 +14148,7 @@
createParser('Function()');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNull);
expect(functionType.functionKeyword, isNotNull);
expect(functionType.typeParameters, isNull);
@@ -14105,7 +14161,7 @@
createParser('Function(int, int)');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNull);
expect(functionType.functionKeyword, isNotNull);
expect(functionType.typeParameters, isNull);
@@ -14131,7 +14187,7 @@
createParser('Function<S, T>()');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNull);
expect(functionType.functionKeyword, isNotNull);
TypeParameterList typeParameters = functionType.typeParameters;
@@ -14147,7 +14203,7 @@
createParser('Function<T>(String, {T t})');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNull);
expect(functionType.functionKeyword, isNotNull);
TypeParameterList typeParameters = functionType.typeParameters;
@@ -14162,7 +14218,7 @@
createParser('Function');
TypeName functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_parseTypeAnnotation_function_returnType_function() {
@@ -14170,14 +14226,14 @@
// TODO(scheglov) improve the test to verify also the node properties
var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType;
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_parseTypeAnnotation_function_returnType_noParameters() {
createParser('List<int> Function()');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNotNull);
expect(functionType.functionKeyword, isNotNull);
expect(functionType.typeParameters, isNull);
@@ -14190,7 +14246,7 @@
createParser('List<int> Function(String s, int i)');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNotNull);
expect(functionType.functionKeyword, isNotNull);
expect(functionType.typeParameters, isNull);
@@ -14219,14 +14275,14 @@
// TODO(scheglov) improve the test to verify also the node properties
var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType;
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_parseTypeAnnotation_function_returnType_typeParameters() {
createParser('List<T> Function<T>()');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNotNull);
expect(functionType.functionKeyword, isNotNull);
TypeParameterList typeParameters = functionType.typeParameters;
@@ -14242,7 +14298,7 @@
createParser('List<T> Function<T>(String s, [T])');
GenericFunctionType functionType = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
expect(functionType.returnType, isNotNull);
expect(functionType.functionKeyword, isNotNull);
TypeParameterList typeParameters = functionType.typeParameters;
@@ -14258,14 +14314,14 @@
// TODO(scheglov) improve this test to verify also the node properties
var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType;
expectNotNullIfNoErrors(functionType);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_parseTypeAnnotation_named() {
createParser('A<B>');
TypeName typeName = parser.parseTypeAnnotation(false);
expectNotNullIfNoErrors(typeName);
- listener.assertNoErrors();
+ assertNoErrors();
}
void test_parseTypeArgumentList_empty() {
@@ -14282,7 +14338,7 @@
createParser('<int, int, int>');
TypeArgumentList argumentList = parser.parseTypeArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(argumentList.leftBracket, isNotNull);
expect(argumentList.arguments, hasLength(3));
expect(argumentList.rightBracket, isNotNull);
@@ -14292,7 +14348,7 @@
createParser('<A<B>>');
TypeArgumentList argumentList = parser.parseTypeArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(argumentList.leftBracket, isNotNull);
expect(argumentList.arguments, hasLength(1));
TypeName argument = argumentList.arguments[0];
@@ -14307,7 +14363,7 @@
createParser('<A<B /* 0 */ >>');
TypeArgumentList argumentList = parser.parseTypeArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(argumentList.leftBracket, isNotNull);
expect(argumentList.rightBracket, isNotNull);
expect(argumentList.arguments, hasLength(1));
@@ -14327,7 +14383,7 @@
createParser('<A<B<C /* 0 */ >>>');
TypeArgumentList argumentList = parser.parseTypeArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(argumentList.leftBracket, isNotNull);
expect(argumentList.rightBracket, isNotNull);
expect(argumentList.arguments, hasLength(1));
@@ -14356,7 +14412,7 @@
createParser('<int>');
TypeArgumentList argumentList = parser.parseTypeArgumentList();
expectNotNullIfNoErrors(argumentList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(argumentList.leftBracket, isNotNull);
expect(argumentList.arguments, hasLength(1));
expect(argumentList.rightBracket, isNotNull);
@@ -14366,7 +14422,7 @@
createParser('List<int>');
TypeName typeName = parser.parseTypeName(false);
expectNotNullIfNoErrors(typeName);
- listener.assertNoErrors();
+ assertNoErrors();
expect(typeName.name, isNotNull);
expect(typeName.typeArguments, isNotNull);
expect(typeName.question, isNull);
@@ -14376,7 +14432,7 @@
createParser('int');
TypeName typeName = parser.parseTypeName(false);
expectNotNullIfNoErrors(typeName);
- listener.assertNoErrors();
+ assertNoErrors();
expect(typeName.name, isNotNull);
expect(typeName.typeArguments, isNull);
expect(typeName.question, isNull);
@@ -14386,7 +14442,7 @@
createParser('A extends Function(int)');
TypeParameter parameter = parser.parseTypeParameter();
expectNotNullIfNoErrors(parameter);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameter.bound, new isInstanceOf<GenericFunctionType>());
expect(parameter.extendsKeyword, isNotNull);
expect(parameter.name, isNotNull);
@@ -14396,7 +14452,7 @@
createParser('A extends String Function(int)');
TypeParameter parameter = parser.parseTypeParameter();
expectNotNullIfNoErrors(parameter);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameter.bound, new isInstanceOf<GenericFunctionType>());
expect(parameter.extendsKeyword, isNotNull);
expect(parameter.name, isNotNull);
@@ -14406,7 +14462,7 @@
createParser('A extends B<C>');
TypeParameter parameter = parser.parseTypeParameter();
expectNotNullIfNoErrors(parameter);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameter.bound, new isInstanceOf<TypeName>());
expect(parameter.extendsKeyword, isNotNull);
expect(parameter.name, isNotNull);
@@ -14416,7 +14472,7 @@
createParser('A extends B');
TypeParameter parameter = parser.parseTypeParameter();
expectNotNullIfNoErrors(parameter);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameter.bound, new isInstanceOf<TypeName>());
expect(parameter.extendsKeyword, isNotNull);
expect(parameter.name, isNotNull);
@@ -14426,7 +14482,7 @@
createParser('A');
TypeParameter parameter = parser.parseTypeParameter();
expectNotNullIfNoErrors(parameter);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameter.bound, isNull);
expect(parameter.extendsKeyword, isNull);
expect(parameter.name, isNotNull);
@@ -14436,7 +14492,7 @@
createParser('<A, B extends C, D>');
TypeParameterList parameterList = parser.parseTypeParameterList();
expectNotNullIfNoErrors(parameterList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameterList.leftBracket, isNotNull);
expect(parameterList.rightBracket, isNotNull);
expect(parameterList.typeParameters, hasLength(3));
@@ -14446,7 +14502,7 @@
createParser('<A extends B<E>>=', expectedEndOffset: 16);
TypeParameterList parameterList = parser.parseTypeParameterList();
expectNotNullIfNoErrors(parameterList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameterList.leftBracket, isNotNull);
expect(parameterList.rightBracket, isNotNull);
expect(parameterList.typeParameters, hasLength(1));
@@ -14456,7 +14512,7 @@
createParser('<A extends B<E /* foo */ >>=', expectedEndOffset: 27);
TypeParameterList parameterList = parser.parseTypeParameterList();
expectNotNullIfNoErrors(parameterList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameterList.leftBracket, isNotNull);
expect(parameterList.rightBracket, isNotNull);
expect(parameterList.typeParameters, hasLength(1));
@@ -14476,7 +14532,7 @@
createParser('<<A>');
TypeParameterList parameterList = parser.parseTypeParameterList();
expectNotNullIfNoErrors(parameterList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameterList.leftBracket, isNotNull);
expect(parameterList.rightBracket, isNotNull);
expect(parameterList.typeParameters, hasLength(1));
@@ -14486,7 +14542,7 @@
createParser('<A>=', expectedEndOffset: 3);
TypeParameterList parameterList = parser.parseTypeParameterList();
expectNotNullIfNoErrors(parameterList);
- listener.assertNoErrors();
+ assertNoErrors();
expect(parameterList.leftBracket, isNotNull);
expect(parameterList.rightBracket, isNotNull);
expect(parameterList.typeParameters, hasLength(1));
@@ -14495,7 +14551,7 @@
void test_parseVariableDeclaration_equals() {
VariableDeclaration declaration = parseVariableDeclaration('var a = b;');
expectNotNullIfNoErrors(declaration);
- listener.assertNoErrors();
+ assertNoErrors();
expect(declaration.name, isNotNull);
expect(declaration.equals, isNotNull);
expect(declaration.initializer, isNotNull);
@@ -14504,7 +14560,7 @@
void test_parseVariableDeclaration_noEquals() {
VariableDeclaration declaration = parseVariableDeclaration('var a;');
expectNotNullIfNoErrors(declaration);
- listener.assertNoErrors();
+ assertNoErrors();
expect(declaration.name, isNotNull);
expect(declaration.equals, isNull);
expect(declaration.initializer, isNull);
@@ -14513,7 +14569,7 @@
void test_parseWithClause_multiple() {
WithClause clause = parseWithClause('with A, B, C');
expectNotNullIfNoErrors(clause);
- listener.assertNoErrors();
+ assertNoErrors();
expect(clause.withKeyword, isNotNull);
expect(clause.mixinTypes, hasLength(3));
}
@@ -14521,7 +14577,7 @@
void test_parseWithClause_single() {
WithClause clause = parseWithClause('with M');
expectNotNullIfNoErrors(clause);
- listener.assertNoErrors();
+ assertNoErrors();
expect(clause.withKeyword, isNotNull);
expect(clause.mixinTypes, hasLength(1));
}
@@ -15031,6 +15087,18 @@
expect(statement.elseStatement, isNotNull);
}
+ void test_parseIfStatement_else_emptyStatements() {
+ var statement = parseStatement('if (true) ; else ;') as IfStatement;
+ assertNoErrors();
+ expect(statement.ifKeyword, isNotNull);
+ expect(statement.leftParenthesis, isNotNull);
+ expect(statement.condition, isNotNull);
+ expect(statement.rightParenthesis, isNotNull);
+ expect(statement.thenStatement, isNotNull);
+ expect(statement.elseKeyword, isNotNull);
+ expect(statement.elseStatement, isNotNull);
+ }
+
void test_parseIfStatement_else_statement() {
var statement = parseStatement('if (x) f(x); else f(y);') as IfStatement;
assertNoErrors();
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 8f8a4f4..e518b96 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -6,6 +6,8 @@
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
@@ -93,6 +95,12 @@
expect(await session.getUnitElementSignature('path'), signature);
}
+ test_resourceProvider() {
+ ResourceProvider resourceProvider = new MemoryResourceProvider();
+ driver.resourceProvider = resourceProvider;
+ expect(session.resourceProvider, resourceProvider);
+ }
+
test_sourceFactory() {
SourceFactory sourceFactory = new SourceFactory([]);
driver.sourceFactory = sourceFactory;
@@ -155,6 +163,7 @@
ErrorsResult errorsResult;
Map<String, LibraryElement> libraryMap = <String, LibraryElement>{};
ParseResult parseResult;
+ ResourceProvider resourceProvider;
AnalysisResult result;
SourceFactory sourceFactory;
SourceKind sourceKind;
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index c76c2a4..c860a24 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -470,7 +470,18 @@
bool get enableNewAnalysisDriver => true;
- void assertIsConst(String snippet, bool isConst) {
+ void assertCanBeConst(String snippet, bool expectedResult) {
+ int index = testSource.indexOf(snippet);
+ expect(index >= 0, isTrue);
+ NodeLocator visitor = new NodeLocator(index);
+ AstNodeImpl node = visitor.searchWithin(testUnit);
+ node = node.getAncestor((node) => node is InstanceCreationExpressionImpl);
+ expect(node, isNotNull);
+ expect((node as InstanceCreationExpressionImpl).canBeConst(),
+ expectedResult ? isTrue : isFalse);
+ }
+
+ void assertIsConst(String snippet, bool expectedResult) {
int index = testSource.indexOf(snippet);
expect(index >= 0, isTrue);
NodeLocator visitor = new NodeLocator(index);
@@ -478,7 +489,7 @@
node = node.getAncestor((node) => node is InstanceCreationExpressionImpl);
expect(node, isNotNull);
expect((node as InstanceCreationExpressionImpl).isConst,
- isConst ? isTrue : isFalse);
+ expectedResult ? isTrue : isFalse);
}
void enablePreviewDart2() {
@@ -490,6 +501,68 @@
testUnit = await resolveSource2('/test.dart', source);
}
+ void test_canBeConst_false_argument_invocation() async {
+ enablePreviewDart2();
+ await resolve('''
+class A {}
+class B {
+ const B(A a);
+}
+A f() => A();
+B g() => B(f());
+''');
+ assertCanBeConst("B(f", false);
+ }
+
+ void test_canBeConst_false_argument_invocationInList() async {
+ enablePreviewDart2();
+ await resolve('''
+class A {}
+class B {
+ const B(a);
+}
+A f() => A();
+B g() => B([f()]);
+''');
+ assertCanBeConst("B([", false);
+ }
+
+ void test_canBeConst_false_argument_nonConstConstructor() async {
+ enablePreviewDart2();
+ await resolve('''
+class A {}
+class B {
+ const B(A a);
+}
+B f() => B(A());
+''');
+ assertCanBeConst("B(A(", false);
+ }
+
+ void test_canBeConst_false_nonConstConstructor() async {
+ enablePreviewDart2();
+ await resolve('''
+class A {}
+A f() => A();
+''');
+ assertCanBeConst("A(", false);
+ }
+
+ @failingTest
+ void test_canBeConst_true_argument_constConstructor() async {
+ enablePreviewDart2();
+ await resolve('''
+class A {
+ const A();
+}
+class B {
+ const B(A a);
+}
+B f() => B(A());
+''');
+ assertCanBeConst("B(A(", true);
+ }
+
void
test_isConst_notInContext_constructor_const_constParam_identifier() async {
enablePreviewDart2();
diff --git a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
index c39a719..ab21c64 100644
--- a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
+++ b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/fasta/ast_body_builder.dart';
+import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer/src/generated/resolver.dart';
import "package:front_end/src/api_prototype/front_end.dart";
import "package:front_end/src/api_prototype/memory_file_system.dart";
@@ -25,6 +26,7 @@
import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
import "package:front_end/src/fasta/kernel/kernel_target.dart";
import 'package:front_end/src/fasta/modifier.dart' as Modifier;
+import 'package:front_end/src/fasta/parser/async_modifier.dart';
import 'package:front_end/src/fasta/parser/parser.dart';
import 'package:front_end/src/fasta/scanner.dart';
import 'package:front_end/src/fasta/ticker.dart';
@@ -34,14 +36,13 @@
import 'package:kernel/class_hierarchy.dart' as kernel;
import 'package:kernel/core_types.dart' as kernel;
import 'package:kernel/kernel.dart' as kernel;
+import 'package:test/test.dart';
import '../../generated/parser_test.dart';
import '../../generated/test_support.dart';
-/**
- * Implementation of [AbstractParserTestCase] specialized for testing building
- * Analyzer AST using the fasta [Forest] API.
- */
+/// Implementation of [AbstractParserTestCase] specialized for testing building
+/// Analyzer AST using the fasta [Forest] API.
class FastaBodyBuilderTestCase extends Object
with ParserTestHelpers
implements AbstractParserTestCase {
@@ -63,8 +64,16 @@
final bool resolveTypes;
+ String content;
+
+ /// The expected offset of the next token to be parsed after the parser has
+ /// finished parsing, or `null` (the default) if EOF is expected.
+ int expectedEndOffset;
+
FastaBodyBuilderTestCase(this.resolveTypes);
+ analyzer.Parser get parser => new ParserProxy(this);
+
TypeProvider get typeProvider => _typeProvider;
@override
@@ -72,6 +81,16 @@
// TODO(brianwilkerson) Implement this.
}
+ void createParser(String content, {int expectedEndOffset}) {
+ this.content = content;
+ this.expectedEndOffset = expectedEndOffset;
+ }
+
+ @override
+ void expectNotNullIfNoErrors(Object result) {
+ // TODO(brianwilkerson) Implement this.
+ }
+
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@override
@@ -92,7 +111,7 @@
@override
AwaitExpression parseAwaitExpression(String code) {
- return parseExpression(code);
+ return parseExpression(code, inAsync: true);
}
@override
@@ -139,7 +158,7 @@
@override
CompilationUnit parseDirectives(String source,
[List<ErrorCode> errorCodes = const <ErrorCode>[]]) {
- throw new UnimplementedError();
+ return parseCompilationUnit(content, codes: errorCodes);
}
@override
@@ -151,9 +170,12 @@
Expression parseExpression(String source,
{List<ErrorCode> codes,
List<ExpectedError> errors,
- int expectedEndOffset}) {
+ int expectedEndOffset,
+ bool inAsync: false,
+ bool inCatchBlock: false}) {
// TODO(brianwilkerson) Check error codes.
- return _parse(source, (parser, token) => parser.parseExpression(token));
+ return _parse(source, (parser, token) => parser.parseExpression(token),
+ inAsync: inAsync, inCatchBlock: inCatchBlock);
}
@override
@@ -182,12 +204,18 @@
@override
CompilationUnitMember parseFullCompilationUnitMember() {
- throw new UnimplementedError();
+ CompilationUnit unit = parseCompilationUnit(content);
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ return unit.declarations[0];
}
@override
Directive parseFullDirective() {
- throw new UnimplementedError();
+ CompilationUnit unit = parseCompilationUnit(content);
+ expect(unit.directives, hasLength(1));
+ expect(unit.declarations, hasLength(0));
+ return unit.directives[0];
}
@override
@@ -204,7 +232,16 @@
@override
ListLiteral parseListLiteral(
Token token, String typeArgumentsCode, String code) {
- return parseExpression(code);
+ StringBuffer buffer = new StringBuffer();
+ if (token != null) {
+ buffer.write(token.lexeme);
+ buffer.write(' ');
+ }
+ if (typeArgumentsCode != null) {
+ buffer.write(typeArgumentsCode);
+ }
+ buffer.write(code);
+ return parseExpression(buffer.toString());
}
@override
@@ -225,12 +262,25 @@
@override
MapLiteral parseMapLiteral(
Token token, String typeArgumentsCode, String code) {
- return parseExpression(code);
+ StringBuffer buffer = new StringBuffer();
+ if (token != null) {
+ buffer.write(token.lexeme);
+ buffer.write(' ');
+ }
+ if (typeArgumentsCode != null) {
+ buffer.write(typeArgumentsCode);
+ }
+ buffer.write(code);
+ return parseExpression(buffer.toString());
}
@override
MapLiteralEntry parseMapLiteralEntry(String code) {
- throw new UnimplementedError();
+ Expression expression = parseExpression('{$code}');
+ expect(expression, new isInstanceOf<MapLiteral>());
+ MapLiteral literal = expression;
+ expect(literal.entries, hasLength(1));
+ return literal.entries[0];
}
@override
@@ -274,7 +324,11 @@
@override
RethrowExpression parseRethrowExpression(String code) {
- return parseExpression(code);
+ Statement statement = parseStatement(code, inCatchBlock: true);
+ expect(statement, new isInstanceOf<ExpressionStatement>());
+ Expression expression = (statement as ExpressionStatement).expression;
+ expect(expression, new isInstanceOf<RethrowExpression>());
+ return expression;
}
@override
@@ -289,9 +343,12 @@
@override
Statement parseStatement(String source,
- {bool enableLazyAssignmentOperators, int expectedEndOffset}) {
+ {bool enableLazyAssignmentOperators,
+ int expectedEndOffset,
+ bool inCatchBlock: true}) {
// TODO(brianwilkerson) Check error codes.
- return _parse(source, (parser, token) => parser.parseStatement(token));
+ return _parse(source, (parser, token) => parser.parseStatement(token),
+ inCatchBlock: inCatchBlock);
}
@override
@@ -321,7 +378,15 @@
@override
VariableDeclarationList parseVariableDeclarationList(String source) {
- throw new UnimplementedError();
+ CompilationUnit unit = parseCompilationUnit('''
+f() {
+ $source;
+}
+''');
+ FunctionDeclaration function = unit.declarations[0];
+ BlockFunctionBody body = function.functionExpression.body;
+ VariableDeclarationStatement statement = body.block.statements[0];
+ return statement.variables;
}
Future setUp() async {
@@ -412,7 +477,8 @@
}
T _parse<T>(
- String source, void parseFunction(Parser parser, Token previousToken)) {
+ String source, void parseFunction(Parser parser, Token previousToken),
+ {bool inAsync: false, bool inCatchBlock: false}) {
ScannerResult scan = scanString(source);
return CompilerContext.runWithOptions(options, (CompilerContext c) {
@@ -463,8 +529,246 @@
)..constantContext = ConstantContext.none; // .inferred ?
Parser parser = new Parser(builder);
+ if (inAsync) {
+ parser.asyncState = AsyncModifier.Async;
+ }
+ if (inCatchBlock) {
+ builder.inCatchBlock = inCatchBlock;
+ }
parseFunction(parser, parser.syntheticPreviousToken(scan.tokens));
+ // TODO(brianwilkerson) Check `expectedEndOffset` if it is not `null`.
return builder.pop();
});
}
}
+
+/// A parser that can be used by [FastaBodyBuilderTestCase] to support the tests
+/// that still call methods on the parser directly.
+class ParserProxy implements analyzer.Parser {
+ final FastaBodyBuilderTestCase testCase;
+
+ ParserProxy(this.testCase);
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ Annotation parseAnnotation() {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('${testCase.content} var v;');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(
+ unit.declarations[0], new isInstanceOf<TopLevelVariableDeclaration>());
+ TopLevelVariableDeclaration declaration = unit.declarations[0];
+ expect(declaration.metadata, hasLength(1));
+ return declaration.metadata[0];
+ }
+
+ @override
+ ArgumentList parseArgumentList() {
+ Expression expression = testCase.parseExpression('f${testCase.content}');
+ expect(expression, new isInstanceOf<MethodInvocation>());
+ MethodInvocation invocation = expression;
+ return invocation.argumentList;
+ }
+
+ @override
+ ClassMember parseClassMember(String className) {
+ CompilationUnit unit = testCase
+ .parseCompilationUnit('class $className { ${testCase.content} }');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+ ClassDeclaration classDeclaration = unit.declarations[0];
+ expect(classDeclaration.members, hasLength(1));
+ return classDeclaration.members[0];
+ }
+
+ @override
+ List<Combinator> parseCombinators() {
+ CompilationUnit unit = testCase
+ .parseCompilationUnit('import "file.dart" ${testCase.content};');
+ expect(unit.directives, hasLength(1));
+ expect(unit.declarations, hasLength(0));
+ expect(unit.directives[0], new isInstanceOf<LibraryDirective>());
+ ImportDirective directive = unit.directives[0];
+ return directive.combinators;
+ }
+
+ @override
+ CommentReference parseCommentReference(
+ String referenceSource, int sourceOffset) {
+ // TODO(brianwilkerson) Implement this.
+ throw new UnimplementedError();
+ }
+
+ @override
+ CompilationUnit parseCompilationUnit2() {
+ return testCase.parseCompilationUnit(testCase.content);
+ }
+
+ @override
+ Configuration parseConfiguration() {
+ CompilationUnit unit = testCase
+ .parseCompilationUnit('import "file.dart" ${testCase.content};');
+ expect(unit.directives, hasLength(1));
+ expect(unit.declarations, hasLength(0));
+ expect(unit.directives[0], new isInstanceOf<LibraryDirective>());
+ ImportDirective directive = unit.directives[0];
+ expect(directive.configurations, hasLength(1));
+ return directive.configurations[0];
+ }
+
+ @override
+ DottedName parseDottedName() {
+ CompilationUnit unit = testCase.parseCompilationUnit(
+ 'import "file.dart" if (${testCase.content}) "file2.dart";');
+ expect(unit.directives, hasLength(1));
+ expect(unit.declarations, hasLength(0));
+ expect(unit.directives[0], new isInstanceOf<LibraryDirective>());
+ ImportDirective directive = unit.directives[0];
+ expect(directive.configurations, hasLength(1));
+ return directive.configurations[0].name;
+ }
+
+ @override
+ ExtendsClause parseExtendsClause() {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('class C ${testCase.content} {}');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+ ClassDeclaration classDeclaration = unit.declarations[0];
+ return classDeclaration.extendsClause;
+ }
+
+ @override
+ analyzer.FinalConstVarOrType parseFinalConstVarOrType(bool optional,
+ {bool inFunctionType: false}) {
+ // TODO(brianwilkerson) Implement this or re-write the tests.
+ throw new UnimplementedError();
+ }
+
+ @override
+ FormalParameterList parseFormalParameterList({bool inFunctionType: false}) {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('f${testCase.content} {}');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(unit.declarations[0], new isInstanceOf<FunctionDeclaration>());
+ FunctionDeclaration function = unit.declarations[0];
+ return function.functionExpression.parameters;
+ }
+
+ @override
+ FunctionBody parseFunctionBody(bool mayBeEmpty,
+ analyzer.ParserErrorCode emptyErrorCode, bool inExpression) {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('f() ${testCase.content}');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(unit.declarations[0], new isInstanceOf<FunctionDeclaration>());
+ FunctionDeclaration declaration = unit.declarations[0];
+ return declaration.functionExpression.body;
+ }
+
+ @override
+ ImplementsClause parseImplementsClause() {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('class C ${testCase.content} {}');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+ ClassDeclaration classDeclaration = unit.declarations[0];
+ return classDeclaration.implementsClause;
+ }
+
+ @override
+ analyzer.Modifiers parseModifiers() {
+ // TODO(brianwilkerson) Implement this or re-write the tests (this might
+ // need context to create the right kind of declaration for the modifiers).
+ throw new UnimplementedError();
+ }
+
+ @override
+ Expression parseMultiplicativeExpression() {
+ return testCase.parseExpression(testCase.content);
+ }
+
+ @override
+ Expression parsePrimaryExpression() {
+ return testCase.parseExpression(testCase.content);
+ }
+
+ @override
+ SimpleIdentifier parseSimpleIdentifier(
+ {bool allowKeyword: false, bool isDeclaration: false}) {
+ return testCase.parseExpression(testCase.content);
+ }
+
+ @override
+ Statement parseStatement2() {
+ return testCase.parseStatement(testCase.content);
+ }
+
+ @override
+ TypeAnnotation parseTypeAnnotation(bool inExpression) {
+ if (inExpression) {
+ // TODO(brianwilkerson) As far as I can see, this path is not used.
+ throw new UnimplementedError();
+ }
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('${testCase.content} x;');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(
+ unit.declarations[0], new isInstanceOf<TopLevelVariableDeclaration>());
+ TopLevelVariableDeclaration variable = unit.declarations[0];
+ return variable.variables.type;
+ }
+
+ @override
+ TypeArgumentList parseTypeArgumentList() {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('C${testCase.content} c;');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(
+ unit.declarations[0], new isInstanceOf<TopLevelVariableDeclaration>());
+ TopLevelVariableDeclaration variable = unit.declarations[0];
+ return (variable.variables.type as TypeName).typeArguments;
+ }
+
+ @override
+ TypeName parseTypeName(bool inExpression) {
+ return parseTypeAnnotation(inExpression) as TypeName;
+ }
+
+ @override
+ TypeParameter parseTypeParameter() {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('class C<${testCase.content}> {}');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+ ClassDeclaration classDeclaration = unit.declarations[0];
+ return classDeclaration.typeParameters.typeParameters[0];
+ }
+
+ @override
+ Expression parseUnaryExpression() {
+ return testCase.parseExpression(testCase.content);
+ }
+
+ @override
+ WithClause parseWithClause() {
+ CompilationUnit unit =
+ testCase.parseCompilationUnit('class C ${testCase.content} {}');
+ expect(unit.directives, hasLength(0));
+ expect(unit.declarations, hasLength(1));
+ expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+ ClassDeclaration classDeclaration = unit.declarations[0];
+ return classDeclaration.withClause;
+ }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
index e6af706..1e2348b 100644
--- a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
@@ -22,6 +22,66 @@
*/
@reflectiveTest
class AngleBracketsTest extends AbstractRecoveryTest {
+ void test_typeParameters_extraGt() {
+ testRecovery('''
+f<T>>() => null;
+''', [
+ ParserErrorCode.TOP_LEVEL_OPERATOR,
+ ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+ ParserErrorCode.MISSING_FUNCTION_BODY
+ ], '''
+f<T> > () => null;
+''', expectedErrorsInValidCode: [
+ ParserErrorCode.TOP_LEVEL_OPERATOR,
+ ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+ ParserErrorCode.MISSING_FUNCTION_BODY
+ ]);
+ }
+
+ void test_typeParameters_funct() {
+ testRecovery('''
+f<T extends Function()() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T extends Function()>() => null;
+''');
+ }
+
+ void test_typeParameters_funct2() {
+ testRecovery('''
+f<T extends Function<X>()() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T extends Function<X>()>() => null;
+''');
+ }
+
+ void test_typeParameters_gtEq() {
+ testRecovery('''
+f<T>=() => null;
+''', [
+ ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+ ParserErrorCode.MISSING_FUNCTION_BODY
+ ], '''
+f<T> = () => null;
+''', expectedErrorsInValidCode: [
+ ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+ ParserErrorCode.MISSING_FUNCTION_BODY
+ ]);
+ }
+
+ void test_typeParameters_gtGtEq() {
+ testRecovery('''
+f<T extends List<int>>=() => null;
+''', [
+ ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+ ParserErrorCode.MISSING_FUNCTION_BODY
+ ], '''
+f<T extends List<int>> = () => null;
+''', expectedErrorsInValidCode: [
+ ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+ ParserErrorCode.MISSING_FUNCTION_BODY
+ ]);
+ }
+
@failingTest
void test_typeArguments_inner_last() {
// Parser crashes
@@ -51,6 +111,22 @@
List<int> _s_;
''');
}
+
+ void test_typeParameters_last() {
+ testRecovery('''
+f<T() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T>() => null;
+''');
+ }
+
+ void test_typeParameters_outer_last() {
+ testRecovery('''
+f<T extends List<int>() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T extends List<int>>() => null;
+''');
+ }
}
/**
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index 5041adb..af6f438 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -12,17 +12,6 @@
class ClassDeclarationTest extends PartialCodeTest {
buildAll() {
- List<String> allExceptEof = <String>[
- 'class',
- 'typedef',
- 'functionVoid',
- 'functionNonVoid',
- 'var',
- 'const',
- 'final',
- 'getter',
- 'setter'
- ];
buildTests(
'class_declaration',
[
@@ -45,15 +34,14 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A extends _s_ {}',
- failing: allExceptEof),
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
new TestDescriptor('extendsBody', 'class A extends {}',
[ParserErrorCode.EXPECTED_TYPE_NAME], 'class A extends _s_ {}'),
new TestDescriptor(
'extendsWithNameBody',
'class A extends with B {}',
[ParserErrorCode.EXPECTED_TYPE_NAME],
- 'class A extends _s_ with B {}',
- allFailing: true),
+ 'class A extends _s_ with B {}'),
new TestDescriptor(
'extendsImplementsNameBody',
'class A extends implements B {}',
@@ -82,7 +70,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A extends B implements _s_ {}',
- failing: allExceptEof),
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
new TestDescriptor(
'extendsNameImplementsBody',
'class A extends B implements {}',
@@ -96,7 +84,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A extends B with C implements _s_ {}',
- failing: allExceptEof),
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
new TestDescriptor(
'extendsNameWithNameImplementsBody',
'class A extends B with C implements {}',
@@ -110,7 +98,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A implements _s_ {}',
- failing: allExceptEof),
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
new TestDescriptor(
'implementsBody',
'class A implements {}',
@@ -124,12 +112,42 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A implements B, _s_ {}',
- failing: allExceptEof),
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
new TestDescriptor(
'implementsNameCommaBody',
'class A implements B, {}',
[ParserErrorCode.EXPECTED_TYPE_NAME],
'class A implements B, _s_ {}'),
+ new TestDescriptor(
+ 'equals',
+ 'class A =',
+ [
+ ParserErrorCode.EXPECTED_TYPE_NAME,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ 'class A = _s_ with _s_;',
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ new TestDescriptor(
+ 'equalsName',
+ 'class A = B',
+ [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ 'class A = B with _s_;',
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ new TestDescriptor(
+ 'equalsNameWith',
+ 'class A = B with',
+ [
+ ParserErrorCode.EXPECTED_TYPE_NAME,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ 'class A = B with _s_;',
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ new TestDescriptor(
+ 'equalsNameName',
+ 'class A = B C',
+ [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ 'class A = B with C;'),
],
PartialCodeTest.declarationSuffixes);
}
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
index 22b63e2..167587a 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
@@ -12,9 +12,6 @@
class EnumDeclarationTest extends PartialCodeTest {
buildAll() {
- List<String> allExceptEof = PartialCodeTest.declarationSuffixes
- .map((TestSuffix t) => t.name)
- .toList();
buildTests(
'enum_declaration',
[
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
index 9d91815..95f261e 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
@@ -12,8 +12,6 @@
class TypedefTest extends PartialCodeTest {
buildAll() {
- List<String> allExceptEof =
- PartialCodeTest.declarationSuffixes.map((t) => t.name).toList();
buildTests(
'typedef',
[
@@ -26,14 +24,16 @@
ParserErrorCode.EXPECTED_TOKEN
],
"typedef _s_();",
- failing: [
- 'functionVoid',
- 'functionNonVoid',
- 'var',
- 'const',
- 'final',
- 'getter'
- ]),
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ new TestDescriptor(
+ 'name',
+ 'typedef T',
+ [
+ ParserErrorCode.MISSING_TYPEDEF_PARAMETERS,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "typedef T();",
+ failing: ['functionNonVoid', 'getter', 'setter']),
new TestDescriptor(
'keywordEquals',
'typedef =',
@@ -43,7 +43,20 @@
ParserErrorCode.EXPECTED_TOKEN
],
"typedef _s_ = _s_;",
- failing: allExceptEof),
+ allFailing: true),
+ new TestDescriptor(
+ 'equals',
+ 'typedef T =',
+ [
+ ParserErrorCode.EXPECTED_TYPE_NAME,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE
+ ],
+ "typedef T = _s_;",
+ expectedErrorsInValidCode: [
+ ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE
+ ],
+ failing: ['functionVoid', 'functionNonVoid', 'getter']),
],
PartialCodeTest.declarationSuffixes);
}
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 3852241..2228fa0 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -2957,18 +2957,18 @@
// For as, the validity of checks is deferred to runtime.
Function f;
f = /*info:UNNECESSARY_CAST*/foo as I2I;
- f = /*info:UNNECESSARY_CAST*/foo as D2I;
+ f = foo as D2I;
f = /*info:UNNECESSARY_CAST*/foo as I2D;
- f = /*info:UNNECESSARY_CAST*/foo as D2D;
+ f = foo as D2D;
f = /*info:UNNECESSARY_CAST*/bar as II2I;
- f = /*info:UNNECESSARY_CAST*/bar as DI2I;
- f = /*info:UNNECESSARY_CAST*/bar as ID2I;
+ f = bar as DI2I;
+ f = bar as ID2I;
f = /*info:UNNECESSARY_CAST*/bar as II2D;
- f = /*info:UNNECESSARY_CAST*/bar as DD2I;
- f = /*info:UNNECESSARY_CAST*/bar as DI2D;
- f = /*info:UNNECESSARY_CAST*/bar as ID2D;
- f = /*info:UNNECESSARY_CAST*/bar as DD2D;
+ f = bar as DD2I;
+ f = bar as DI2D;
+ f = bar as ID2D;
+ f = bar as DD2D;
}
''');
}
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index fe9302a..4596071 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -56,7 +56,7 @@
print('Generating $modeName mode summary.');
Stopwatch sw = new Stopwatch()..start();
List<int> bytes = new SummaryBuilder.forSdk(sdkPath, strong).build();
- new File(outPath).writeAsBytesSync(bytes, mode: FileMode.WRITE_ONLY);
+ new File(outPath).writeAsBytesSync(bytes, mode: FileMode.writeOnly);
print('\tDone in ${sw.elapsedMilliseconds} ms.');
}
diff --git a/pkg/analyzer_cli/lib/src/ansi.dart b/pkg/analyzer_cli/lib/src/ansi.dart
index c764fd8..1b9a539 100644
--- a/pkg/analyzer_cli/lib/src/ansi.dart
+++ b/pkg/analyzer_cli/lib/src/ansi.dart
@@ -10,7 +10,7 @@
bool terminalSupportsAnsi() {
return !runningTests &&
!Platform.isWindows &&
- stdioType(stdout) == StdioType.TERMINAL;
+ stdioType(stdout) == StdioType.terminal;
}
class AnsiLogger {
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 41ecfab8..87f6f10 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -266,13 +266,13 @@
if (options.buildSummaryOutput != null) {
io.File file = new io.File(options.buildSummaryOutput);
file.writeAsBytesSync(bundle.toBuffer(),
- mode: io.FileMode.WRITE_ONLY);
+ mode: io.FileMode.writeOnly);
}
if (options.buildSummaryOutputSemantic != null) {
bundle.flushInformative();
io.File file = new io.File(options.buildSummaryOutputSemantic);
file.writeAsBytesSync(bundle.toBuffer(),
- mode: io.FileMode.WRITE_ONLY);
+ mode: io.FileMode.writeOnly);
}
});
} else {
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index fdf9630..e0d511d 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1280,7 +1280,7 @@
An enumeration of the kinds of folding regions.
</p>
- <dl><dt class="value">COMMENT</dt><dt class="value">CLASS_MEMBER</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">TOP_LEVEL_DECLARATION</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
+ <dl><dt class="value">ANNOTATIONS</dt><dt class="value">CLASS_BODY</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">FILE_HEADER</dt><dt class="value">FUNCTION_BODY</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
<p>
A description of a region that can be folded.
</p>
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index d940ac8..e724ab7 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -1963,37 +1963,40 @@
* FoldingKind
*
* enum {
- * COMMENT
- * CLASS_MEMBER
+ * ANNOTATIONS
+ * CLASS_BODY
* DIRECTIVES
* DOCUMENTATION_COMMENT
- * TOP_LEVEL_DECLARATION
+ * FILE_HEADER
+ * FUNCTION_BODY
* }
*
* Clients may not extend, implement or mix-in this class.
*/
class FoldingKind implements Enum {
- static const FoldingKind COMMENT = const FoldingKind._("COMMENT");
+ static const FoldingKind ANNOTATIONS = const FoldingKind._("ANNOTATIONS");
- static const FoldingKind CLASS_MEMBER = const FoldingKind._("CLASS_MEMBER");
+ static const FoldingKind CLASS_BODY = const FoldingKind._("CLASS_BODY");
static const FoldingKind DIRECTIVES = const FoldingKind._("DIRECTIVES");
static const FoldingKind DOCUMENTATION_COMMENT =
const FoldingKind._("DOCUMENTATION_COMMENT");
- static const FoldingKind TOP_LEVEL_DECLARATION =
- const FoldingKind._("TOP_LEVEL_DECLARATION");
+ static const FoldingKind FILE_HEADER = const FoldingKind._("FILE_HEADER");
+
+ static const FoldingKind FUNCTION_BODY = const FoldingKind._("FUNCTION_BODY");
/**
* A list containing all of the enum values that are defined.
*/
static const List<FoldingKind> VALUES = const <FoldingKind>[
- COMMENT,
- CLASS_MEMBER,
+ ANNOTATIONS,
+ CLASS_BODY,
DIRECTIVES,
DOCUMENTATION_COMMENT,
- TOP_LEVEL_DECLARATION
+ FILE_HEADER,
+ FUNCTION_BODY
];
@override
@@ -2003,16 +2006,18 @@
factory FoldingKind(String name) {
switch (name) {
- case "COMMENT":
- return COMMENT;
- case "CLASS_MEMBER":
- return CLASS_MEMBER;
+ case "ANNOTATIONS":
+ return ANNOTATIONS;
+ case "CLASS_BODY":
+ return CLASS_BODY;
case "DIRECTIVES":
return DIRECTIVES;
case "DOCUMENTATION_COMMENT":
return DOCUMENTATION_COMMENT;
- case "TOP_LEVEL_DECLARATION":
- return TOP_LEVEL_DECLARATION;
+ case "FILE_HEADER":
+ return FILE_HEADER;
+ case "FUNCTION_BODY":
+ return FUNCTION_BODY;
}
throw new Exception('Illegal enum value: $name');
}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
index fe90449..807264c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
@@ -184,13 +184,15 @@
} finally {
int end = offset + _buffer.length;
int length = end - start;
- Position position = new Position(fileEditBuilder.fileEdit.file, start);
- fileEditBuilder.changeBuilder._lockedPositions.add(position);
- LinkedEditGroup group =
- fileEditBuilder.changeBuilder.getLinkedEditGroup(groupName);
- group.addPosition(position, length);
- for (LinkedEditSuggestion suggestion in builder.suggestions) {
- group.addSuggestion(suggestion);
+ if (length != 0) {
+ Position position = new Position(fileEditBuilder.fileEdit.file, start);
+ fileEditBuilder.changeBuilder._lockedPositions.add(position);
+ LinkedEditGroup group =
+ fileEditBuilder.changeBuilder.getLinkedEditGroup(groupName);
+ group.addPosition(position, length);
+ for (LinkedEditSuggestion suggestion in builder.suggestions) {
+ group.addSuggestion(suggestion);
+ }
}
}
}
@@ -229,9 +231,8 @@
}
@override
- void write(String string, {StringBuffer displayTextBuffer}) {
+ void write(String string) {
_buffer.write(string);
- displayTextBuffer?.write(string);
}
@override
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index b9b3f80..ef91dc7 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -24,7 +24,6 @@
import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:charcode/ascii.dart';
import 'package:meta/meta.dart';
-import 'package:path/path.dart' as path;
/**
* A [ChangeBuilder] used to build changes in Dart files.
@@ -43,8 +42,14 @@
@override
Future<Null> addFileEdit(
- String path, void buildFileEdit(DartFileEditBuilder builder)) =>
- super.addFileEdit(path, (builder) => buildFileEdit(builder));
+ String path, void buildFileEdit(DartFileEditBuilder builder),
+ {ImportPrefixGenerator importPrefixGenerator}) {
+ return super.addFileEdit(path, (builder) {
+ DartFileEditBuilderImpl dartBuilder = builder;
+ dartBuilder.importPrefixGenerator = importPrefixGenerator;
+ buildFileEdit(dartBuilder);
+ });
+ }
@override
Future<DartFileEditBuilderImpl> createFileEditBuilder(String path) async {
@@ -65,6 +70,28 @@
List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];
/**
+ * Whether [_enclosingClass] and [_enclosingExecutable] have been initialized.
+ */
+ bool _hasEnclosingElementsInitialized = false;
+
+ /**
+ * The enclosing class element, possibly `null`.
+ * This field is lazily initialized in [_initializeEnclosingElements].
+ */
+ ClassElement _enclosingClass;
+
+ /**
+ * The enclosing executable element, possibly `null`.
+ * This field is lazily initialized in [_initializeEnclosingElements].
+ */
+ ExecutableElement _enclosingExecutable;
+
+ /**
+ * If not `null`, [write] will copy everything into this buffer.
+ */
+ StringBuffer _carbonCopyBuffer;
+
+ /**
* Initialize a newly created builder to build a source edit.
*/
DartEditBuilderImpl(
@@ -88,11 +115,10 @@
*/
String getIndent(int level) => ' ' * level;
- /**
- * Arrange to have an import added for the given [library].
- */
- void importLibrary(Source library) {
- dartFileEditBuilder.librariesToImport.add(library);
+ @override
+ void write(String string) {
+ super.write(string);
+ _carbonCopyBuffer?.write(string);
}
@override
@@ -335,6 +361,15 @@
@override
void writeOverrideOfInheritedMember(ExecutableElement member,
{StringBuffer displayTextBuffer, String returnTypeGroupName}) {
+ void withCarbonCopyBuffer(f()) {
+ this._carbonCopyBuffer = displayTextBuffer;
+ try {
+ f();
+ } finally {
+ this._carbonCopyBuffer = null;
+ }
+ }
+
String prefix = getIndent(1);
String prefix2 = getIndent(2);
ElementKind elementKind = member.kind;
@@ -376,7 +411,9 @@
}
// name
- write(memberName, displayTextBuffer: displayTextBuffer);
+ withCarbonCopyBuffer(() {
+ write(memberName);
+ });
// parameters + body
if (isGetter) {
@@ -396,11 +433,11 @@
}
displayTextBuffer?.write(' => …');
} else {
- writeTypeParameters(member.typeParameters,
- methodBeingCopied: member, displayTextBuffer: displayTextBuffer);
List<ParameterElement> parameters = member.parameters;
- writeParameters(parameters,
- methodBeingCopied: member, displayTextBuffer: displayTextBuffer);
+ withCarbonCopyBuffer(() {
+ writeTypeParameters(member.typeParameters, methodBeingCopied: member);
+ writeParameters(parameters, methodBeingCopied: member);
+ });
writeln(' {');
// TO-DO
@@ -467,20 +504,18 @@
@override
void writeParameter(String name,
- {StringBuffer displayTextBuffer,
- ExecutableElement methodBeingCopied,
- DartType type}) {
- String parameterSource;
+ {ExecutableElement methodBeingCopied, DartType type}) {
if (type != null) {
- _EnclosingElementFinder finder = new _EnclosingElementFinder();
- finder.find(dartFileEditBuilder.unit, offset);
- parameterSource = _getTypeSource(
- type, finder.enclosingClass, finder.enclosingExecutable,
- parameterName: name, methodBeingCopied: methodBeingCopied);
+ bool hasType = _writeType(type, methodBeingCopied: methodBeingCopied);
+ if (name.isNotEmpty) {
+ if (hasType) {
+ write(' ');
+ }
+ write(name);
+ }
} else {
- parameterSource = name;
+ write(name);
}
- write(parameterSource, displayTextBuffer: displayTextBuffer);
}
@override
@@ -509,51 +544,49 @@
@override
void writeParameters(Iterable<ParameterElement> parameters,
- {StringBuffer displayTextBuffer, ExecutableElement methodBeingCopied}) {
- write('(', displayTextBuffer: displayTextBuffer);
+ {ExecutableElement methodBeingCopied}) {
+ write('(');
bool sawNamed = false;
bool sawPositional = false;
for (int i = 0; i < parameters.length; i++) {
ParameterElement parameter = parameters.elementAt(i);
if (i > 0) {
- write(', ', displayTextBuffer: displayTextBuffer);
+ write(', ');
}
// Might be optional
if (parameter.isNamed) {
if (!sawNamed) {
- write('{', displayTextBuffer: displayTextBuffer);
+ write('{');
sawNamed = true;
}
} else if (parameter.isOptionalPositional) {
if (!sawPositional) {
- write('[', displayTextBuffer: displayTextBuffer);
+ write('[');
sawPositional = true;
}
}
// parameter
writeParameter(parameter.name,
- displayTextBuffer: displayTextBuffer,
- methodBeingCopied: methodBeingCopied,
- type: parameter.type);
+ methodBeingCopied: methodBeingCopied, type: parameter.type);
// default value
String defaultCode = parameter.defaultValueCode;
if (defaultCode != null) {
if (sawPositional) {
- write(' = ', displayTextBuffer: displayTextBuffer);
+ write(' = ');
} else {
- write(': ', displayTextBuffer: displayTextBuffer);
+ write(': ');
}
- write(defaultCode, displayTextBuffer: displayTextBuffer);
+ write(defaultCode);
}
}
// close parameters
if (sawNamed) {
- write('}', displayTextBuffer: displayTextBuffer);
+ write('}');
}
if (sawPositional) {
- write(']', displayTextBuffer: displayTextBuffer);
+ write(']');
}
- write(')', displayTextBuffer: displayTextBuffer);
+ write(')');
}
@override
@@ -582,24 +615,8 @@
@override
void writeReference(Element element) {
if (element.enclosingElement is CompilationUnitElement) {
- LibraryElement definingLibrary = element.library;
- LibraryElement importingLibrary =
- dartFileEditBuilder.unit.element.library;
-
- // TODO(scheglov) Extract this code (it is already used twice).
- // TODO(scheglov) Consider updating `show` combinator to show the element.
- ImportElement existingImport =
- _getImportElement(element, importingLibrary);
- if (existingImport != null) {
- if (existingImport.prefix != null) {
- write(existingImport.prefix.displayName);
- write('.');
- }
- } else {
- importLibrary(definingLibrary.source);
- }
+ _writeLibraryReference(element);
}
-
write(element.displayName);
}
@@ -609,66 +626,50 @@
String groupName,
ExecutableElement methodBeingCopied,
bool required: false}) {
+ bool wroteType = false;
if (type != null && !type.isDynamic) {
- _EnclosingElementFinder finder = new _EnclosingElementFinder();
- finder.find(dartFileEditBuilder.unit, offset);
- String typeSource = _getTypeSource(
- type, finder.enclosingClass, finder.enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (typeSource.isNotEmpty && typeSource != 'dynamic') {
- if (groupName != null) {
- addLinkedEdit(groupName, (LinkedEditBuilder builder) {
- write(typeSource);
- if (addSupertypeProposals) {
- _addSuperTypeProposals(builder, type, new Set<DartType>());
- }
- });
- } else {
- write(typeSource);
- }
- return true;
+ if (groupName != null) {
+ addLinkedEdit(groupName, (LinkedEditBuilder builder) {
+ wroteType = _writeType(type, methodBeingCopied: methodBeingCopied);
+ if (wroteType && addSupertypeProposals) {
+ _addSuperTypeProposals(builder, type, new Set<DartType>());
+ }
+ });
+ } else {
+ wroteType = _writeType(type, methodBeingCopied: methodBeingCopied);
}
}
- if (required) {
+ if (!wroteType && required) {
write(Keyword.VAR.lexeme);
return true;
}
- return false;
+ return wroteType;
}
@override
void writeTypeParameter(TypeParameterElement typeParameter,
- {StringBuffer displayTextBuffer, ExecutableElement methodBeingCopied}) {
- write(typeParameter.name, displayTextBuffer: displayTextBuffer);
+ {ExecutableElement methodBeingCopied}) {
+ write(typeParameter.name);
if (typeParameter.bound != null) {
- _EnclosingElementFinder finder = new _EnclosingElementFinder();
- finder.find(dartFileEditBuilder.unit, offset);
- String bound = _getTypeSource(typeParameter.bound, finder.enclosingClass,
- finder.enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (bound != null) {
- write(' extends ', displayTextBuffer: displayTextBuffer);
- write(bound, displayTextBuffer: displayTextBuffer);
- }
+ write(' extends ');
+ _writeType(typeParameter.bound, methodBeingCopied: methodBeingCopied);
}
}
@override
void writeTypeParameters(List<TypeParameterElement> typeParameters,
- {StringBuffer displayTextBuffer, ExecutableElement methodBeingCopied}) {
+ {ExecutableElement methodBeingCopied}) {
if (typeParameters.isNotEmpty) {
- write('<', displayTextBuffer: displayTextBuffer);
+ write('<');
bool isFirst = true;
for (TypeParameterElement typeParameter in typeParameters) {
if (!isFirst) {
- write(', ', displayTextBuffer: displayTextBuffer);
+ write(', ');
}
isFirst = false;
- writeTypeParameter(typeParameter,
- methodBeingCopied: methodBeingCopied,
- displayTextBuffer: displayTextBuffer);
+ writeTypeParameter(typeParameter, methodBeingCopied: methodBeingCopied);
}
- write('>', displayTextBuffer: displayTextBuffer);
+ write('>');
}
}
@@ -847,28 +848,6 @@
}
/**
- * Return the import element used to import the given [element] into the given
- * [library], or `null` if the element was not imported, such as when the
- * element is declared in the same library.
- */
- ImportElement _getImportElement(Element element, LibraryElement library) {
- for (ImportElement importElement in library.imports) {
- Map<String, Element> definedNames = _getImportNamespace(importElement);
- if (definedNames.containsValue(element)) {
- return importElement;
- }
- }
- return null;
- }
-
- /**
- * Return the namespace added by the given import [element].
- */
- Map<String, Element> _getImportNamespace(ImportElement element) {
- return element.namespace.definedNames;
- }
-
- /**
* Return a list containing the suggested names for a parameter with the given
* [type] whose value in one location is computed by the given [expression].
* The list will not contain any names in the set of [excluded] names. The
@@ -887,189 +866,6 @@
}
/**
- * Returns the source to reference [type] in this compilation unit.
- *
- * If an [enclosingClass] is provided then the reference is being generated
- * within the class and the type parameters of the class will be considered to
- * be visible.
- *
- * If an [enclosingExecutable] is provided, then the reference is being
- * generated within the class and the type parameters of the method will be
- * considered to be visible.
- *
- * If a [methodBeingCopied] is provided, then the type parameters of that
- * method will be duplicated in the copy and will therefore be visible.
- *
- * If a [parameterName] is given, then the type is the type of a parameter
- * and the parameter name will be included, either in-line in a function type
- * or after the type source for other types.
- *
- * Causes any libraries whose elements are used by the generated source, to be
- * imported.
- */
- String _getTypeSource(DartType type, ClassElement enclosingClass,
- ExecutableElement enclosingExecutable,
- {String parameterName, ExecutableElement methodBeingCopied}) {
- // type parameter
- type = _getVisibleType(type, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (type == null || type.isDynamic || type.isBottom) {
- if (parameterName != null) {
- return parameterName;
- }
- return 'dynamic';
- }
-
- Element element = type.element;
-
- // Typedef(s) are represented as GenericFunctionTypeElement(s).
- if (element is GenericFunctionTypeElement &&
- element.typeParameters.isEmpty &&
- element.enclosingElement is GenericTypeAliasElement) {
- element = element.enclosingElement;
- }
-
- // just a Function, not FunctionTypeAliasElement
- if (type is FunctionType && element is! FunctionTypeAliasElement) {
- if (parameterName == null) {
- return 'Function';
- }
- // TODO(brianwilkerson) Using a buffer here means that we cannot re-use
- // the existing `write*` functions. Refactor this code to remove the
- // duplication.
- StringBuffer buffer = new StringBuffer();
- String returnType = _getTypeSource(
- type.returnType, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (returnType != null) {
- buffer.write(returnType);
- buffer.write(' ');
- }
- if (element is GenericFunctionTypeElement) {
- buffer.write('Function');
- if (element.typeParameters.isNotEmpty) {
- buffer.write('<');
- bool isFirst = true;
- for (TypeParameterElement typeParameter in element.typeParameters) {
- if (!isFirst) {
- buffer.write(', ');
- }
- isFirst = false;
- buffer.write(typeParameter.name);
- if (typeParameter.bound != null) {
- String bound = _getTypeSource(
- typeParameter.bound, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (bound != null) {
- buffer.write(' extends ');
- buffer.write(bound);
- }
- }
- }
- buffer.write('>');
- }
- } else {
- buffer.write(parameterName);
- }
- buffer.write('(');
- int count = type.parameters.length;
- for (int i = 0; i < count; i++) {
- ParameterElement parameter = type.parameters[i];
- String parameterType = _getTypeSource(
- parameter.type, enclosingClass, enclosingExecutable,
- parameterName: parameter.name,
- methodBeingCopied: methodBeingCopied);
- if (i > 0) {
- buffer.write(', ');
- }
- buffer.write(parameterType);
- }
- buffer.write(')');
- if (element is GenericFunctionTypeElement) {
- buffer.write(' ');
- buffer.write(parameterName);
- }
- return buffer.toString();
- }
- // prepare element
- if (element == null) {
- String source = type.toString();
- source = source.replaceAll('<dynamic>', '');
- source = source.replaceAll('<dynamic, dynamic>', '');
- if (parameterName != null) {
- return '$source $parameterName';
- }
- return source;
- }
- // check if imported
- StringBuffer buffer = new StringBuffer();
- LibraryElement definingLibrary = element.library;
- LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
- if (definingLibrary != null && definingLibrary != importingLibrary) {
- // no source, if private
- if (element.isPrivate) {
- if (parameterName != null) {
- return parameterName;
- }
- return '';
- }
- // ensure import
- ImportElement importElement =
- _getImportElement(element, importingLibrary);
- if (importElement != null) {
- if (importElement.prefix != null) {
- buffer.write(importElement.prefix.displayName);
- buffer.write(".");
- }
- } else {
- importLibrary(definingLibrary.source);
- }
- }
- // append simple name
- String name = element.displayName;
- buffer.write(name);
- // may be type arguments
- if (type is ParameterizedType) {
- List<DartType> arguments = type.typeArguments;
- // check if has arguments
- bool hasArguments = false;
- bool allArgumentsVisible = true;
- for (DartType argument in arguments) {
- hasArguments = hasArguments || !argument.isDynamic;
- allArgumentsVisible = allArgumentsVisible &&
- _getVisibleType(argument, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied) !=
- null;
- }
- // append type arguments
- if (hasArguments && allArgumentsVisible) {
- buffer.write("<");
- for (int i = 0; i < arguments.length; i++) {
- DartType argument = arguments[i];
- if (i != 0) {
- buffer.write(", ");
- }
- String argumentSrc = _getTypeSource(
- argument, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (argumentSrc != null) {
- buffer.write(argumentSrc);
- } else {
- return null;
- }
- }
- buffer.write(">");
- }
- }
- if (parameterName != null) {
- buffer.write(' ');
- buffer.write(parameterName);
- }
- // done
- return buffer.toString();
- }
-
- /**
* Returns possible names for a variable with the given expected type and
* expression assigned.
*/
@@ -1109,15 +905,15 @@
}
/**
- * If the given [type] is visible in either the [enclosingExecutable] or
- * [enclosingClass], or if there is a local equivalent to the type (such as in
- * the case of a type parameter from a superclass), then return the type that
- * is locally visible. Otherwise, return `null`.
+ * If the given [type] is visible in either the [_enclosingExecutable] or
+ * [_enclosingClass], or if there is a local equivalent to the type (such as
+ * in the case of a type parameter from a superclass), then return the type
+ * that is locally visible. Otherwise, return `null`.
*/
- DartType _getVisibleType(DartType type, ClassElement enclosingClass,
- ExecutableElement enclosingExecutable,
+ DartType _getVisibleType(DartType type,
{ExecutableElement methodBeingCopied}) {
if (type is TypeParameterType) {
+ _initializeEnclosingElements();
TypeParameterElement parameterElement = type.element;
Element parameterParent = parameterElement.enclosingElement;
while (parameterParent is GenericFunctionTypeElement ||
@@ -1125,24 +921,24 @@
parameterParent = parameterParent.enclosingElement;
}
// TODO(brianwilkerson) This needs to compare the parameterParent with
- // each of the parents of the enclosingExecutable. (That means that we
+ // each of the parents of the _enclosingExecutable. (That means that we
// only need the most closely enclosing element.)
- if (parameterParent == enclosingExecutable ||
- parameterParent == enclosingClass ||
+ if (parameterParent == _enclosingExecutable ||
+ parameterParent == _enclosingClass ||
parameterParent == methodBeingCopied) {
return type;
}
- if (enclosingClass != null &&
+ if (_enclosingClass != null &&
methodBeingCopied != null &&
parameterParent is ClassElement &&
parameterParent == methodBeingCopied.enclosingElement) {
// The parameter is from the class enclosing the methodBeingCopied. That
// means that somewhere along the inheritance chain there must be a type
// argument corresponding to the type parameter (either a concrete type
- // or a type parameter of the enclosingClass). That's the visible type
+ // or a type parameter of the _enclosingClass). That's the visible type
// that needs to be returned.
_InheritanceChain chain = new _InheritanceChain(
- subtype: enclosingClass, supertype: parameterParent);
+ subtype: _enclosingClass, supertype: parameterParent);
while (chain != null) {
DartType mappedType = chain.mapParameter(parameterElement);
if (mappedType is TypeParameterType) {
@@ -1160,15 +956,136 @@
if (element == null) {
return type;
}
- LibraryElement definingLibrary = element.library;
- LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
- if (definingLibrary != null &&
- definingLibrary != importingLibrary &&
- element.isPrivate) {
+ if (element.isPrivate && !dartFileEditBuilder._isDefinedLocally(element)) {
return null;
}
return type;
}
+
+ /**
+ * Initialize the [_enclosingClass] and [_enclosingExecutable].
+ */
+ void _initializeEnclosingElements() {
+ if (!_hasEnclosingElementsInitialized) {
+ _EnclosingElementFinder finder = new _EnclosingElementFinder();
+ finder.find(dartFileEditBuilder.unit, offset);
+ _enclosingClass = finder.enclosingClass;
+ _enclosingExecutable = finder.enclosingExecutable;
+ _hasEnclosingElementsInitialized = true;
+ }
+ }
+
+ /**
+ * Write the import prefix to reference the [element], if needed.
+ *
+ * The prefix is not needed if the [element] is defined in the target library,
+ * or there is already an import without prefix that exports the [element].
+ * If there there are no existing import that exports the [element], a library
+ * that exports the [element] is scheduled for import, possibly with a prefix.
+ */
+ void _writeLibraryReference(Element element) {
+ // If the element is defined in the library, then no prefix needed.
+ if (dartFileEditBuilder._isDefinedLocally(element)) {
+ return;
+ }
+
+ ImportElement import = dartFileEditBuilder._getImportElement(element);
+ if (import != null) {
+ if (import.prefix != null) {
+ write(import.prefix.displayName);
+ write('.');
+ }
+ } else {
+ Uri library = element.library.source.uri;
+ _LibraryToImport import = dartFileEditBuilder._importLibrary(library);
+ if (import.prefix != null) {
+ write(import.prefix);
+ write('.');
+ }
+ }
+ }
+
+ /**
+ * Write the code to reference [type] in this compilation unit.
+ *
+ * If a [methodBeingCopied] is provided, then the type parameters of that
+ * method will be duplicated in the copy and will therefore be visible.
+ *
+ * Causes any libraries whose elements are used by the generated code, to be
+ * imported.
+ */
+ bool _writeType(DartType type, {ExecutableElement methodBeingCopied}) {
+ type = _getVisibleType(type, methodBeingCopied: methodBeingCopied);
+
+ // If not a useful type, don't write it.
+ if (type == null || type.isDynamic || type.isBottom) {
+ return false;
+ }
+
+ Element element = type.element;
+
+ // No element, e.g. "void".
+ if (element == null) {
+ write(type.displayName);
+ return true;
+ }
+
+ // Typedef(s) are represented as GenericFunctionTypeElement(s).
+ if (element is GenericFunctionTypeElement &&
+ element.typeParameters.isEmpty &&
+ element.enclosingElement is GenericTypeAliasElement) {
+ element = element.enclosingElement;
+ }
+
+ // Just a Function, not FunctionTypeAliasElement.
+ if (type is FunctionType &&
+ element is FunctionTypedElement &&
+ element is! FunctionTypeAliasElement) {
+ if (_writeType(type.returnType, methodBeingCopied: methodBeingCopied)) {
+ write(' ');
+ }
+ write('Function');
+ writeTypeParameters(element.typeParameters,
+ methodBeingCopied: methodBeingCopied);
+ writeParameters(type.parameters, methodBeingCopied: methodBeingCopied);
+ return true;
+ }
+
+ // Ensure that the element is imported.
+ _writeLibraryReference(element);
+
+ // Write the simple name.
+ String name = element.displayName;
+ write(name);
+
+ // Write type arguments.
+ if (type is ParameterizedType) {
+ List<DartType> arguments = type.typeArguments;
+ // Check if has arguments.
+ bool hasArguments = false;
+ bool allArgumentsVisible = true;
+ for (DartType argument in arguments) {
+ hasArguments = hasArguments || !argument.isDynamic;
+ allArgumentsVisible = allArgumentsVisible &&
+ _getVisibleType(argument, methodBeingCopied: methodBeingCopied) !=
+ null;
+ }
+ // Write type arguments only if they are useful.
+ if (hasArguments && allArgumentsVisible) {
+ write('<');
+ for (int i = 0; i < arguments.length; i++) {
+ DartType argument = arguments[i];
+ if (i != 0) {
+ write(', ');
+ }
+ _writeType(argument, methodBeingCopied: methodBeingCopied);
+ }
+ write('>');
+ }
+ }
+
+ return true;
+ }
}
/**
@@ -1179,22 +1096,33 @@
/**
* The compilation unit to which the code will be added.
*/
- CompilationUnit unit;
+ final CompilationUnit unit;
/**
- * A set containing the sources of the libraries that need to be imported in
- * order to make visible the names used in generated code.
+ * The target library, which contains the [unit].
*/
- Set<Source> librariesToImport = new Set<Source>();
+ final LibraryElement libraryElement;
+
+ /**
+ * The optional generator of prefixes for new imports.
+ */
+ ImportPrefixGenerator importPrefixGenerator;
+
+ /**
+ * A mapping from libraries that need to be imported in order to make visible
+ * the names used in generated code, to information about these imports.
+ */
+ Map<Uri, _LibraryToImport> librariesToImport = {};
/**
* Initialize a newly created builder to build a source file edit within the
* change being built by the given [changeBuilder]. The file being edited has
- * the given [source] and [timeStamp], and the given fully resolved [unit].
+ * the given [path] and [timeStamp], and the given fully resolved [unit].
*/
DartFileEditBuilderImpl(DartChangeBuilderImpl changeBuilder, String path,
int timeStamp, this.unit)
- : super(changeBuilder, path, timeStamp);
+ : libraryElement = unit.element.library,
+ super(changeBuilder, path, timeStamp);
@override
void addInsertion(int offset, void buildEdit(DartEditBuilder builder)) =>
@@ -1226,25 +1154,23 @@
@override
Future<Null> finalize() async {
if (librariesToImport.isNotEmpty) {
- CompilationUnitElement unitElement = unit.element;
- LibraryElement libraryElement = unitElement.library;
CompilationUnitElement definingUnitElement =
libraryElement.definingCompilationUnit;
- if (definingUnitElement == unitElement) {
- _addLibraryImports(libraryElement, librariesToImport);
+ if (definingUnitElement == unit.element) {
+ _addLibraryImports(librariesToImport.values);
} else {
await (changeBuilder as DartChangeBuilder).addFileEdit(
definingUnitElement.source.fullName, (DartFileEditBuilder builder) {
(builder as DartFileEditBuilderImpl)
- ._addLibraryImports(libraryElement, librariesToImport);
+ ._addLibraryImports(librariesToImport.values);
});
}
}
}
@override
- void importLibraries(Iterable<Source> libraries) {
- librariesToImport.addAll(libraries);
+ String importLibrary(Uri uri) {
+ return _importLibrary(uri).uriText;
}
@override
@@ -1274,10 +1200,9 @@
}
/**
- * Adds edits ensure that all the [libraries] are imported into the given
- * [targetLibrary].
+ * Adds edits ensure that all the [imports] are imported into the library.
*/
- void _addLibraryImports(LibraryElement targetLibrary, Set<Source> libraries) {
+ void _addLibraryImports(Iterable<_LibraryToImport> imports) {
// Prepare information about existing imports.
LibraryDirective libraryDirective;
List<ImportDirective> importDirectives = <ImportDirective>[];
@@ -1289,23 +1214,31 @@
}
}
- // Prepare all URIs to import.
- List<String> uriList = libraries
- .map((library) => _getLibrarySourceUri(targetLibrary, library))
- .toList();
- uriList.sort((a, b) => a.compareTo(b));
+ // Sort imports by URIs.
+ List<_LibraryToImport> importList = imports.toList();
+ importList.sort((a, b) => a.uriText.compareTo(b.uriText));
+
+ void writeImport(EditBuilder builder, _LibraryToImport import) {
+ builder.write("import '");
+ builder.write(import.uriText);
+ builder.write("'");
+ if (import.prefix != null) {
+ builder.write(' as ');
+ builder.write(import.prefix);
+ }
+ builder.write(';');
+ }
// Insert imports: between existing imports.
if (importDirectives.isNotEmpty) {
- for (String importUri in uriList) {
- bool isDart = importUri.startsWith('dart:');
- bool isPackage = importUri.startsWith('package:');
+ for (var import in importList) {
+ bool isDart = import.uriText.startsWith('dart:');
+ bool isPackage = import.uriText.startsWith('package:');
bool inserted = false;
void insert(
{ImportDirective prev,
ImportDirective next,
- String uri,
bool trailingNewLine: false}) {
LineInfo lineInfo = unit.lineInfo;
if (prev != null) {
@@ -1320,16 +1253,13 @@
}
addInsertion(offset, (EditBuilder builder) {
builder.writeln();
- builder.write("import '");
- builder.write(uri);
- builder.write("';");
+ writeImport(builder, import);
});
} else {
int offset = next.offset;
addInsertion(offset, (EditBuilder builder) {
- builder.write("import '");
- builder.write(uri);
- builder.writeln("';");
+ writeImport(builder, import);
+ builder.writeln();
if (trailingNewLine) {
builder.writeln();
}
@@ -1350,14 +1280,13 @@
bool isExistingPackage = existingUri.startsWith('package:');
bool isExistingRelative = !existingUri.contains(':');
- bool isNewBeforeExisting = importUri.compareTo(existingUri) < 0;
+ bool isNewBeforeExisting = import.uriText.compareTo(existingUri) < 0;
if (isDart) {
if (!isExistingDart || isNewBeforeExisting) {
insert(
prev: lastExistingDart,
next: existingImport,
- uri: importUri,
trailingNewLine: !isExistingDart);
break;
}
@@ -1366,13 +1295,12 @@
insert(
prev: lastExistingPackage,
next: existingImport,
- uri: importUri,
trailingNewLine: isExistingRelative);
break;
}
} else {
if (!isExistingDart && !isExistingPackage && isNewBeforeExisting) {
- insert(next: existingImport, uri: importUri);
+ insert(next: existingImport);
break;
}
}
@@ -1398,9 +1326,7 @@
}
}
builder.writeln();
- builder.write("import '");
- builder.write(importUri);
- builder.write("';");
+ writeImport(builder, import);
});
}
}
@@ -1409,18 +1335,17 @@
// Insert imports: after the library directive.
if (libraryDirective != null) {
- for (int i = 0; i < uriList.length; i++) {
- String importUri = uriList[i];
- addInsertion(libraryDirective.end, (EditBuilder builder) {
+ addInsertion(libraryDirective.end, (EditBuilder builder) {
+ for (int i = 0; i < importList.length; i++) {
+ var import = importList[i];
if (i == 0) {
builder.writeln();
}
builder.writeln();
- builder.write("import '");
- builder.write(importUri);
- builder.writeln("';");
- });
- }
+ writeImport(builder, import);
+ builder.writeln();
+ }
+ });
return;
}
@@ -1433,34 +1358,69 @@
} else {
offset = unit.end;
}
- for (int i = 0; i < uriList.length; i++) {
- String importUri = uriList[i];
- addInsertion(offset, (EditBuilder builder) {
- builder.write("import '");
- builder.write(importUri);
- builder.writeln("';");
- if (i == uriList.length - 1 && insertEmptyLineAfter) {
+ addInsertion(offset, (EditBuilder builder) {
+ for (int i = 0; i < importList.length; i++) {
+ var import = importList[i];
+ writeImport(builder, import);
+ builder.writeln();
+ if (i == importList.length - 1 && insertEmptyLineAfter) {
builder.writeln();
}
- });
- }
+ }
+ });
}
/**
- * Computes the best URI to import [what] into [from].
+ * Return the import element used to import the given [element] into the
+ * target library, or `null` if the element was not imported, such as when
+ * the element is declared in the same library.
*/
- String _getLibrarySourceUri(LibraryElement from, Source what) {
- String whatPath = what.fullName;
- // check if an absolute URI (such as 'dart:' or 'package:')
- Uri whatUri = what.uri;
- String whatUriScheme = whatUri.scheme;
- if (whatUriScheme != '' && whatUriScheme != 'file') {
- return whatUri.toString();
+ ImportElement _getImportElement(Element element) {
+ for (ImportElement import in libraryElement.imports) {
+ Map<String, Element> definedNames = import.namespace.definedNames;
+ if (definedNames.containsValue(element)) {
+ return import;
+ }
}
- // compute a relative URI
- String fromFolder = path.dirname(from.source.fullName);
- String relativeFile = path.relative(whatPath, from: fromFolder);
- return path.split(relativeFile).join('/');
+ return null;
+ }
+
+ /**
+ * Computes the best URI to import [what] into the target library.
+ */
+ String _getLibraryUriText(Uri what) {
+ if (what.scheme == 'file') {
+ var session = (changeBuilder as DartChangeBuilderImpl).session;
+ var pathContext = session.resourceProvider.pathContext;
+ String whatPath = pathContext.fromUri(what);
+ String libraryPath = libraryElement.source.fullName;
+ String libraryFolder = pathContext.dirname(libraryPath);
+ String relativeFile = pathContext.relative(whatPath, from: libraryFolder);
+ return pathContext.split(relativeFile).join('/');
+ }
+ return what.toString();
+ }
+
+ /**
+ * Arrange to have an import added for the library with the given [uri].
+ */
+ _LibraryToImport _importLibrary(Uri uri) {
+ var import = librariesToImport[uri];
+ if (import == null) {
+ String uriText = _getLibraryUriText(uri);
+ String prefix =
+ importPrefixGenerator != null ? importPrefixGenerator(uri) : null;
+ import = new _LibraryToImport(uriText, prefix);
+ librariesToImport[uri] = import;
+ }
+ return import;
+ }
+
+ /**
+ * Return `true` if the [element] is defined in the target library.
+ */
+ bool _isDefinedLocally(Element element) {
+ return element.library == libraryElement;
}
/**
@@ -1626,3 +1586,23 @@
return null;
}
}
+
+/**
+ * Information about a new library to import.
+ */
+class _LibraryToImport {
+ final String uriText;
+ final String prefix;
+
+ _LibraryToImport(this.uriText, this.prefix);
+
+ @override
+ int get hashCode => uriText.hashCode;
+
+ @override
+ bool operator ==(other) {
+ return other is _LibraryToImport &&
+ other.uriText == uriText &&
+ other.prefix == prefix;
+ }
+}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index a7a52c0..da284db 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -121,6 +121,16 @@
optype.inStaticMethodBody =
mthDecl is MethodDeclaration && mthDecl.isStatic;
+ // If a value should be suggested, suggest also constructors.
+ if (optype.includeReturnValueSuggestions) {
+ // Careful: in angular plugin, `target.unit` may be null!
+ CompilationUnitElement unitElement = target.unit?.element;
+ if (unitElement != null &&
+ unitElement.context.analysisOptions.previewDart2) {
+ optype.includeConstructorSuggestions = true;
+ }
+ }
+
// Compute the type required by the context and set filters.
optype._computeRequiredTypeAndFilters(target);
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index f1f68be..4cd16ae 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -14,6 +14,11 @@
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
/**
+ * The optional generator for prefix that should be used for new imports.
+ */
+typedef ImportPrefixGenerator = String Function(Uri);
+
+/**
* A [ChangeBuilder] used to build changes in Dart files.
*
* Clients may not extend, implement or mix-in this class.
@@ -24,9 +29,18 @@
*/
factory DartChangeBuilder(AnalysisSession session) = DartChangeBuilderImpl;
+ /**
+ * Use the [buildFileEdit] function to create a collection of edits to the
+ * file with the given [path]. The edits will be added to the source change
+ * that is being built.
+ *
+ * If [importPrefixGenerator] is provided, it will be asked to generate an
+ * import prefix for every newly imported library.
+ */
@override
Future<Null> addFileEdit(
- String path, void buildFileEdit(DartFileEditBuilder builder));
+ String path, void buildFileEdit(DartFileEditBuilder builder),
+ {ImportPrefixGenerator importPrefixGenerator});
}
/**
@@ -305,9 +319,12 @@
FunctionBody body, TypeProvider typeProvider);
/**
- * Arrange to have imports added for each of the given [libraries].
+ * Arrange to have an import added for the library with the given [uri].
+ *
+ * Returns the text of the URI that will be used in the import directive.
+ * It can be different than the given [Uri].
*/
- void importLibraries(Iterable<Source> libraries);
+ String importLibrary(Uri uri);
/**
* Optionally create an edit to replace the given [typeAnnotation] with the
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index 30d0bb6..841a96f 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -317,19 +317,21 @@
* FoldingKind
*
* enum {
- * COMMENT
- * CLASS_MEMBER
+ * ANNOTATIONS
+ * CLASS_BODY
* DIRECTIVES
* DOCUMENTATION_COMMENT
- * TOP_LEVEL_DECLARATION
+ * FILE_HEADER
+ * FUNCTION_BODY
* }
*/
final Matcher isFoldingKind = new MatchesEnum("FoldingKind", [
- "COMMENT",
- "CLASS_MEMBER",
+ "ANNOTATIONS",
+ "CLASS_BODY",
"DIRECTIVES",
"DOCUMENTATION_COMMENT",
- "TOP_LEVEL_DECLARATION"
+ "FILE_HEADER",
+ "FUNCTION_BODY"
]);
/**
diff --git a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
index bf6ede1..e8e2d46 100644
--- a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
@@ -74,7 +74,7 @@
@override
void computeFolding(FoldingRequest request, FoldingCollector collector) {
for (int i = 0; i < regionCount; i++) {
- collector.addRegion(i * 20, 10, FoldingKind.COMMENT);
+ collector.addRegion(i * 20, 10, FoldingKind.FILE_HEADER);
}
}
}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
index fe72dfa..e662d11 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
@@ -337,7 +337,8 @@
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(10, (EditBuilder builder) {
builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
- builder.addSuggestion(LinkedEditSuggestionKind.TYPE, 'A');
+ builder.write('A');
+ builder.addSuggestion(LinkedEditSuggestionKind.TYPE, 'B');
});
});
});
@@ -346,13 +347,28 @@
expect(group.suggestions, hasLength(1));
}
+ test_addSuggestion_zeroLength() async {
+ String groupName = 'a';
+ ChangeBuilderImpl builder = new ChangeBuilderImpl();
+ await builder.addFileEdit(path, (FileEditBuilder builder) {
+ builder.addInsertion(10, (EditBuilder builder) {
+ builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
+ builder.addSuggestion(LinkedEditSuggestionKind.TYPE, 'A');
+ });
+ });
+ });
+
+ expect(builder.sourceChange.linkedEditGroups, isEmpty);
+ }
+
test_addSuggestions() async {
String groupName = 'a';
ChangeBuilderImpl builder = new ChangeBuilderImpl();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(10, (EditBuilder builder) {
builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
- builder.addSuggestions(LinkedEditSuggestionKind.TYPE, ['A', 'B']);
+ builder.write('A');
+ builder.addSuggestions(LinkedEditSuggestionKind.TYPE, ['B', 'C']);
});
});
});
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index d8d76f8..c7d2f7b 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -74,7 +74,7 @@
class DartEditBuilderImplTest extends AbstractContextTest
with BuilderTestMixin {
test_importLibraries_DP() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:aaa';
import 'dart:ccc';
@@ -92,7 +92,7 @@
}
test_importLibraries_PD() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:aaa';
import 'dart:ccc';
@@ -110,7 +110,7 @@
}
test_importLibrary_afterLibraryDirective_dart() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
library test;
class A {}
@@ -125,7 +125,7 @@
}
test_importLibrary_dart_beforeDart() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:aaa';
import 'dart:ccc';
''', ['dart:bbb'], '''
@@ -136,7 +136,7 @@
}
test_importLibrary_dart_beforeDart_first() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:bbb';
''', ['dart:aaa'], '''
import 'dart:aaa';
@@ -145,7 +145,7 @@
}
test_importLibrary_dart_beforePackage() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'package:foo/foo.dart';
''', ['dart:async'], '''
import 'dart:async';
@@ -155,7 +155,7 @@
}
test_importLibrary_noDirectives_docComment() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
/// Documentation comment.
/// Continues.
void main() {}
@@ -169,7 +169,7 @@
}
test_importLibrary_noDirectives_hashBang() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
#!/bin/dart
void main() {}
@@ -183,7 +183,7 @@
}
test_importLibrary_noDirectives_lineComment() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
// Not documentation comment.
// Continues.
@@ -199,7 +199,7 @@
}
test_importLibrary_package_afterDart() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:async';
''', ['package:aaa/aaa.dart'], '''
import 'dart:async';
@@ -209,7 +209,7 @@
}
test_importLibrary_package_afterPackage() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'package:aaa/a1.dart';
import 'foo.dart';
@@ -222,7 +222,7 @@
}
test_importLibrary_package_afterPackage_leadingComment() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
// comment
import 'package:aaa/a1.dart';
@@ -237,7 +237,7 @@
}
test_importLibrary_package_afterPackage_trailingComment() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'package:aaa/a1.dart'; // comment
import 'foo.dart';
@@ -250,7 +250,7 @@
}
test_importLibrary_package_beforePackage() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'package:aaa/a1.dart';
import 'package:aaa/a3.dart';
@@ -265,7 +265,7 @@
}
test_importLibrary_package_beforePackage_first() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'package:aaa/a2.dart';
import 'foo.dart';
@@ -278,7 +278,7 @@
}
test_importLibrary_package_beforePackage_leadingComments() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
// comment a2
import 'package:aaa/a2.dart';
@@ -293,7 +293,7 @@
}
test_importLibrary_package_beforePackage_trailingComments() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'package:aaa/a2.dart'; // comment a2
import 'foo.dart';
@@ -306,7 +306,7 @@
}
test_importLibrary_package_beforeRelative() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'foo.dart';
''', ['package:aaa/aaa.dart'], '''
import 'package:aaa/aaa.dart';
@@ -316,7 +316,7 @@
}
test_importLibrary_relative_afterDart() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:async';
''', ['aaa.dart'], '''
import 'dart:async';
@@ -326,7 +326,7 @@
}
test_importLibrary_relative_afterPackage() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'package:foo/foo.dart';
''', ['aaa.dart'], '''
import 'package:foo/foo.dart';
@@ -336,7 +336,7 @@
}
test_importLibrary_relative_beforeRelative() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:async';
import 'package:foo/foo.dart';
@@ -355,7 +355,7 @@
}
test_importLibrary_relative_beforeRelative_first() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:async';
import 'package:foo/foo.dart';
@@ -372,7 +372,7 @@
}
test_importLibrary_relative_last() async {
- await _assertImportLibraries('''
+ await _assertImportLibrary('''
import 'dart:async';
import 'package:foo/foo.dart';
@@ -1734,6 +1734,32 @@
expect(edit.replacement, equalsIgnoringWhitespace(''));
}
+ test_writeType_function() async {
+ await _assertWriteType('int Function(double a, String b)');
+ }
+
+ @failingTest
+ test_writeType_function_generic() async {
+ // TODO(scheglov) Fails because T/U are considered invisible.
+ await _assertWriteType('T Function<T, U>(T a, U b)');
+ }
+
+ test_writeType_function_noReturnType() async {
+ await _assertWriteType('Function()');
+ }
+
+ test_writeType_function_parameters_named() async {
+ await _assertWriteType('int Function(int a, {int b, int c})');
+ }
+
+ test_writeType_function_parameters_noName() async {
+ await _assertWriteType('int Function(double, String)');
+ }
+
+ test_writeType_function_parameters_positional() async {
+ await _assertWriteType('int Function(int a, [int b, int c])');
+ }
+
test_writeType_genericType() async {
String path = provider.convertPath('/test.dart');
String content = 'class A {} class B<E> {}';
@@ -1806,6 +1832,33 @@
expect(values, contains('C'));
}
+ test_writeType_groupName_invalidType() async {
+ String path = provider.convertPath('/test.dart');
+ String content = 'class A<T> {}';
+ addSource(path, content);
+
+ InterfaceType typeA = await _getType(path, 'A');
+ DartType typeT = typeA.typeParameters.single.type;
+
+ var builder = new DartChangeBuilder(session);
+ await builder.addFileEdit(path, (builder) {
+ builder.addInsertion(content.length, (builder) {
+ // "T" cannot be written, because we are outside of "A".
+ // So, we also should not create linked groups.
+ builder.writeType(typeT, groupName: 'type');
+ });
+ });
+ expect(builder.sourceChange.linkedEditGroups, isEmpty);
+ }
+
+ test_writeType_interface_typeArguments() async {
+ await _assertWriteType('Map<int, List<String>>');
+ }
+
+ test_writeType_interface_typeArguments_allDynamic() async {
+ await _assertWriteType('Map');
+ }
+
test_writeType_null() async {
String path = provider.convertPath('/test.dart');
String content = 'class A {}';
@@ -1821,6 +1874,56 @@
expect(edit.replacement, equalsIgnoringWhitespace(''));
}
+ test_writeType_prefixGenerator() async {
+ String aPath = provider.convertPath('/a.dart');
+ String bPath = provider.convertPath('/b.dart');
+
+ addSource(aPath, r'''
+class A1 {}
+class A2 {}
+''');
+ addSource(bPath, r'''
+class B {}
+''');
+
+ String path = provider.convertPath('/test.dart');
+ String content = '';
+ addSource(path, content);
+
+ ClassElement a1 = await _getClassElement(aPath, 'A1');
+ ClassElement a2 = await _getClassElement(aPath, 'A2');
+ ClassElement b = await _getClassElement(bPath, 'B');
+
+ int nextPrefixIndex = 0;
+ String prefixGenerator(_) {
+ return '_prefix${nextPrefixIndex++}';
+ }
+
+ var builder = new DartChangeBuilder(session);
+ await builder.addFileEdit(path, (builder) {
+ builder.addInsertion(content.length - 1, (builder) {
+ builder.writeType(a1.type);
+ builder.write(' a1; ');
+
+ builder.writeType(a2.type);
+ builder.write(' a2; ');
+
+ builder.writeType(b.type);
+ builder.write(' b;');
+ });
+ }, importPrefixGenerator: prefixGenerator);
+ List<SourceEdit> edits = getEdits(builder);
+ expect(edits, hasLength(2));
+ expect(
+ edits[0].replacement,
+ equalsIgnoringWhitespace(
+ "import 'a.dart' as _prefix0; import 'b.dart' as _prefix1;"));
+ expect(
+ edits[1].replacement,
+ equalsIgnoringWhitespace(
+ '_prefix0.A1 a1; _prefix0.A2 a2; _prefix1.B b;'));
+ }
+
test_writeType_required_dynamic() async {
String path = provider.convertPath('/test.dart');
String content = 'class A {}';
@@ -1890,6 +1993,15 @@
expect(edit.replacement, equalsIgnoringWhitespace('A'));
}
+ test_writeType_typedef_typeArguments() async {
+ await _assertWriteType('F<int, String>',
+ declarations: 'typedef void F<T, U>(T t, U u);');
+ }
+
+ test_writeType_void() async {
+ await _assertWriteType('void Function()');
+ }
+
test_writeTypes_empty() async {
String path = provider.convertPath('/test.dart');
String content = 'class A {}';
@@ -1955,18 +2067,15 @@
expect(edit.replacement, equalsIgnoringWhitespace('implements A, B'));
}
- Future<Null> _assertImportLibraries(
+ Future<Null> _assertImportLibrary(
String initialCode, List<String> newUris, String expectedCode) async {
String path = provider.convertPath('/test.dart');
addSource(path, initialCode);
DartChangeBuilderImpl builder = new DartChangeBuilder(session);
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
- Iterable<_MockSource> sources = newUris.map((newUri) {
- String path =
- newUri.contains(':') ? null : provider.convertPath('/$newUri');
- return new _MockSource(path, Uri.parse(newUri));
- });
- builder.importLibraries(sources);
+ for (String newUri in newUris) {
+ builder.importLibrary(Uri.parse(newUri));
+ }
});
String resultCode = initialCode;
@@ -2044,6 +2153,23 @@
}
}
+ Future<void> _assertWriteType(String typeCode, {String declarations}) async {
+ String path = provider.convertPath('/test.dart');
+ String content = (declarations ?? '') + '$typeCode v;';
+ addSource(path, content);
+
+ var f = await _getTopLevelAccessorElement(path, 'v');
+
+ var builder = new DartChangeBuilder(session);
+ await builder.addFileEdit(path, (builder) {
+ builder.addInsertion(content.length - 1, (builder) {
+ builder.writeType(f.returnType);
+ });
+ });
+ SourceEdit edit = getEdit(builder);
+ expect(edit.replacement, typeCode);
+ }
+
Future<ClassElement> _getClassElement(String path, String name) async {
UnitElementResult result = await driver.getUnitElement(path);
return result.element.getType(name);
@@ -2055,7 +2181,7 @@
return result.element.accessors.firstWhere((v) => v.name == name);
}
- Future<DartType> _getType(String path, String name) async {
+ Future<InterfaceType> _getType(String path, String name) async {
ClassElement classElement = await _getClassElement(path, name);
return classElement.type;
}
@@ -2168,16 +2294,3 @@
unorderedEquals(['Object', 'A', 'B', 'C']));
}
}
-
-class _MockSource implements Source {
- @override
- final String fullName;
-
- @override
- final Uri uri;
-
- _MockSource(this.fullName, this.uri);
-
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index 648c033..7e30303 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -6,7 +6,7 @@
</head>
<body>
<h1>Common Types</h1>
-<version>1.0.0</version>
+<version>1.0.1</version>
<p>
This document contains a specification of the types that are common between
the analysis server wire protocol and the analysis server plugin wire
@@ -533,11 +533,12 @@
An enumeration of the kinds of folding regions.
</p>
<enum>
- <value><code>COMMENT</code></value>
- <value><code>CLASS_MEMBER</code></value>
+ <value><code>ANNOTATIONS</code></value>
+ <value><code>CLASS_BODY</code></value>
<value><code>DIRECTIVES</code></value>
<value><code>DOCUMENTATION_COMMENT</code></value>
- <value><code>TOP_LEVEL_DECLARATION</code></value>
+ <value><code>FILE_HEADER</code></value>
+ <value><code>FUNCTION_BODY</code></value>
</enum>
</type>
<type name="FoldingRegion">
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
index 1c9c10e..46360f9 100644
--- a/pkg/async_helper/lib/async_helper.dart
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -23,14 +23,7 @@
library async_helper;
-// TODO(kustermann): This is problematic because we rely on a working
-// 'dart:isolate' (i.e. it is in particular problematic with dart2js).
-// It would be nice if we could use a different mechanism for different
-// runtimes.
-import 'dart:isolate';
-
bool _initialized = false;
-ReceivePort _port = null;
int _asyncLevel = 0;
Exception _buildException(String msg) {
@@ -49,7 +42,6 @@
if (!_initialized) {
print('unittest-suite-wait-for-done');
_initialized = true;
- _port = new ReceivePort();
}
_asyncLevel += count;
}
@@ -66,8 +58,6 @@
}
_asyncLevel--;
if (_asyncLevel == 0) {
- _port.close();
- _port = null;
print('unittest-suite-success');
}
}
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 1ad4fc81..cd2101a 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -17,14 +17,11 @@
import 'common.dart';
import 'compiler.dart';
import 'diagnostics/messages.dart' show Message;
-import 'elements/elements.dart' as elements;
import 'environment.dart';
-import 'library_loader.dart';
import 'io/source_file.dart';
import 'options.dart' show CompilerOptions;
import 'platform_configuration.dart' as platform_configuration;
import 'resolved_uri_translator.dart';
-import 'script.dart';
/// Implements the [Compiler] using a [api.CompilerInput] for supplying the
/// sources.
@@ -34,10 +31,6 @@
api.CompilerDiagnostics handler;
Packages packages;
- bool get mockableLibraryUsed => resolvedUriTranslator.isSet
- ? resolvedUriTranslator.mockableLibraryUsed
- : false;
-
ForwardingResolvedUriTranslator resolvedUriTranslator;
GenericTask userHandlerTask;
@@ -73,86 +66,6 @@
null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
}
- /// Report [exception] reading [uri]. Use [element] and [node] to compute
- /// the error location.
- void _reportReadError(
- Uri uri, elements.Element element, Spannable node, exception) {
- if (element == null || node == null) {
- reporter.reportErrorMessage(new SourceSpan(uri, 0, 0),
- MessageKind.READ_SELF_ERROR, {'uri': uri, 'exception': exception});
- } else {
- reporter.withCurrentElement(element, () {
- reporter.reportErrorMessage(node, MessageKind.READ_URI_ERROR,
- {'uri': uri, 'exception': exception});
- });
- }
- }
-
- /**
- * Reads the script designated by [readableUri].
- */
- Future<Script> readScript(Uri readableUri, [Spannable node]) {
- if (!readableUri.isAbsolute) {
- if (node == null) node = NO_LOCATION_SPANNABLE;
- reporter.internalError(
- node, 'Relative uri $readableUri provided to readScript(Uri).');
- }
-
- // We need to store the current element since we are reporting read errors
- // asynchronously and therefore need to restore the current element for
- // [node] to be valid.
- elements.Element element = currentElement;
-
- Uri resourceUri = translateUri(node, readableUri);
- if (resourceUri == null) return _synthesizeScript(readableUri);
- if (resourceUri.scheme == 'dart-ext') {
- reporter.withCurrentElement(element, () {
- reporter.reportErrorMessage(node, MessageKind.DART_EXT_NOT_SUPPORTED);
- });
- return _synthesizeScript(readableUri);
- }
-
- // TODO(johnniwinther): Wrap the result from [provider] in a specialized
- // [Future] to ensure that we never execute an asynchronous action without
- // setting up the current element of the compiler.
- return new Future.sync(
- () => callUserProvider(resourceUri, api.InputKind.UTF8))
- .then((api.Input sourceFile) {
- // We use [readableUri] as the URI for the script since need to preserve
- // the scheme in the script because [Script.uri] is used for resolving
- // relative URIs mentioned in the script. See the comment on
- // [LibraryLoader] for more details.
- return new Script(readableUri, resourceUri, sourceFile);
- }).catchError((error) {
- _reportReadError(readableUri, element, node, error);
- return _synthesizeScript(readableUri);
- });
- }
-
- Future<Script> _synthesizeScript(Uri readableUri) {
- return new Future.value(new Script.synthetic(readableUri));
- }
-
- Future<Binary> readBinary(Uri resourceUri, [Spannable node]) {
- if (!resourceUri.isAbsolute) {
- if (node == null) node = NO_LOCATION_SPANNABLE;
- reporter.internalError(
- node, 'Relative uri $resourceUri provided to readBinary(Uri).');
- }
-
- // We need to store the current element since we are reporting read errors
- // asynchronously and therefore need to restore the current element for
- // [node] to be valid.
- elements.Element element = currentElement;
-
- return new Future.sync(
- () => callUserProvider(resourceUri, api.InputKind.binary))
- .catchError((error) {
- _reportReadError(resourceUri, element, node, error);
- return new Binary(resourceUri, null);
- });
- }
-
/**
* Translates a readable URI into a resource URI.
*
@@ -176,21 +89,6 @@
});
}
- Future<elements.LibraryElement> analyzeUri(Uri uri,
- {bool skipLibraryWithPartOfTag: true}) {
- Future setupFuture = new Future.value();
- if (resolvedUriTranslator.isNotSet) {
- setupFuture = setupFuture.then((_) => setupSdk());
- }
- if (packages == null) {
- setupFuture = setupFuture.then((_) => setupPackages(uri));
- }
- return setupFuture.then((_) {
- return super
- .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag);
- });
- }
-
Future setupPackages(Uri uri) {
if (options.packageRoot != null) {
// Use "non-file" packages because the file version requires a [Directory]
@@ -229,8 +127,7 @@
.load(options.platformConfigUri, provider)
.then((Map<String, Uri> mapping) {
resolvedUriTranslator.resolvedUriTranslator =
- new ResolvedUriTranslator(
- mapping, reporter, options.platformConfigUri);
+ new ResolvedUriTranslator(mapping);
});
});
}
@@ -314,9 +211,6 @@
}
}
- bool get isMockCompilation =>
- mockableLibraryUsed && options.allowMockCompilation;
-
void callUserHandler(Message message, Uri uri, int begin, int end,
String text, api.Diagnostic kind) {
try {
@@ -348,11 +242,6 @@
rethrow;
}
}
-
- Uri resolvePatchUri(String libraryName) {
- return LibraryLoaderTask.resolvePatchUri(
- libraryName, options.platformConfigUri);
- }
}
class _Environment implements Environment {
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index 869ed63..a4ad683 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -2,27 +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.
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import 'common/names.dart' show Identifiers;
-import 'common/resolution.dart' show ParsingContext, Resolution;
import 'common/tasks.dart' show CompilerTask, Measurer;
import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constants/expressions.dart';
-import 'elements/elements.dart';
import 'elements/entities.dart';
-import 'elements/entity_utils.dart' as utils;
-import 'elements/modelx.dart'
- show BaseFunctionElementX, ClassElementX, ElementX;
-import 'elements/resolution_types.dart';
import 'elements/types.dart';
-import 'elements/visitor.dart' show ElementVisitor;
-import 'js_backend/js_backend.dart' show JavaScriptBackend;
-import 'js_backend/runtime_types.dart';
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'tree/tree.dart';
-import 'util/util.dart';
import 'world.dart' show ClosedWorldRefiner;
// TODO(johnniwinther,efortuna): Split [ClosureConversionTask] from
@@ -249,293 +232,6 @@
bool get isClosure => false;
}
-class ClosureTask extends ClosureConversionTask<Node> {
- Map<Node, CapturedScopeImpl> _closureInfoMap = <Node, CapturedScopeImpl>{};
- Map<MemberElement, ClosureClassMap> _closureMemberMappingCache =
- <MemberElement, ClosureClassMap>{};
- Map<FunctionExpression, ClosureClassMap> _closureNodeMappingCache =
- <FunctionExpression, ClosureClassMap>{};
- Compiler compiler;
- ClosureTask(Compiler compiler)
- : compiler = compiler,
- super(compiler.measurer);
-
- String get name => "Closure Simplifier";
-
- DiagnosticReporter get reporter => compiler.reporter;
-
- void convertClosures(Iterable<MemberEntity> processedEntities,
- ClosedWorldRefiner closedWorldRefiner) {
- createClosureClasses(closedWorldRefiner);
- }
-
- CapturedScope _getCapturedScope(Node node) {
- var value = _closureInfoMap[node];
- return value == null ? const CapturedScope() : value;
- }
-
- CapturedScope getCapturedScope(covariant MemberElement member) {
- ResolvedAst resolvedAst = member.resolvedAst;
- if (resolvedAst.kind != ResolvedAstKind.PARSED)
- return const CapturedScope();
- return _getCapturedScope(resolvedAst.node);
- }
-
- ScopeInfo getScopeInfo(MemberEntity member) {
- return _getMemberMapping(member);
- }
-
- ClosureRepresentationInfo getClosureInfoForMember(MemberEntity member) {
- return _getMemberMapping(member);
- }
-
- ClosureRepresentationInfo getClosureInfo(covariant FunctionExpression node) {
- return _getClosureMapping(node);
- }
-
- CapturedLoopScope getCapturedLoopScope(Node loopNode) {
- var value = _closureInfoMap[loopNode];
- return value == null ? const CapturedLoopScope() : value;
- }
-
- /// Returns the [ClosureClassMap] computed for [element].
- ClosureClassMap _getMemberMapping(MemberElement element) {
- return measure(() {
- if (element.isGenerativeConstructorBody) {
- ConstructorBodyElement constructorBody = element;
- element = constructorBody.constructor;
- }
- ClosureClassMap closureClassMap = _closureMemberMappingCache[element];
- assert(closureClassMap != null,
- failedAt(element, "No ClosureClassMap computed for ${element}."));
- return closureClassMap;
- });
- }
-
- /// Returns the [ClosureClassMap] computed for [node].
- ClosureClassMap _getClosureMapping(FunctionExpression node) {
- return measure(() {
- ClosureClassMap closureClassMap = _closureNodeMappingCache[node];
- assert(closureClassMap != null,
- failedAt(node, "No ClosureClassMap computed for ${node}."));
- return closureClassMap;
- });
- }
-
- /// Create [ClosureClassMap]s for all live members.
- void createClosureClasses(ClosedWorldRefiner closedWorldRefiner) {
- compiler.enqueuer.resolution.processedEntities
- .forEach((MemberEntity _element) {
- MemberElement element = _element;
- ResolvedAst resolvedAst = element.resolvedAst;
- if (element.isAbstract) return;
- if (element.isField &&
- !element.isInstanceMember &&
- resolvedAst.body == null) {
- // Skip top-level/static fields without an initializer.
- return;
- }
- computeClosureToClassMapping(element, closedWorldRefiner);
- });
- }
-
- ClosureClassMap computeClosureToClassMapping(
- MemberElement element, ClosedWorldRefiner closedWorldRefiner) {
- return measure(() {
- ClosureClassMap cached = _closureMemberMappingCache[element];
- if (cached != null) return cached;
- if (element.resolvedAst.kind != ResolvedAstKind.PARSED) {
- return _closureMemberMappingCache[element] = new ClosureClassMap(
- null, null, null, new ThisLocalVariable(element));
- }
- return reporter.withCurrentElement(element.implementation, () {
- Node node = element.resolvedAst.node;
- TreeElements elements = element.resolvedAst.elements;
-
- ClosureTranslator translator = new ClosureTranslator(
- compiler,
- closedWorldRefiner,
- elements,
- _closureMemberMappingCache,
- _closureNodeMappingCache,
- _closureInfoMap);
-
- // The translator will store the computed closure-mappings inside the
- // cache. One for given node and one for each nested closure.
- if (node is FunctionExpression) {
- translator.translateFunction(element, node);
- } else if (element.isSynthesized) {
- reporter.internalError(
- element, "Unexpected synthesized element: $element");
- _closureMemberMappingCache[element] = new ClosureClassMap(
- null, null, null, new ThisLocalVariable(element));
- } else {
- assert(element.isField,
- failedAt(element, "Expected $element to be a field."));
- Node initializer = element.resolvedAst.body;
- if (initializer != null) {
- // The lazy initializer of a static.
- translator.translateLazyInitializer(element, node, initializer);
- } else {
- assert(
- element.isInstanceMember,
- failedAt(
- element,
- "Expected $element (${element.runtimeType}) "
- "to be an instance field."));
- _closureMemberMappingCache[element] = new ClosureClassMap(
- null, null, null, new ThisLocalVariable(element));
- }
- }
- assert(_closureMemberMappingCache[element] != null,
- failedAt(element, "No ClosureClassMap computed for ${element}."));
- return _closureMemberMappingCache[element];
- });
- });
- }
-}
-
-// TODO(ahe): These classes continuously cause problems. We need to
-// find a more general solution.
-class ClosureFieldElement extends ElementX
- implements FieldElement, PrivatelyNamedJSEntity {
- /// The [BoxLocal] or [LocalElement] being accessed through the field.
- final Local local;
-
- ClosureFieldElement(String name, this.local, ClosureClassElement enclosing)
- : super(name, ElementKind.FIELD, enclosing);
-
- /// Use [closureClass] instead.
- @deprecated
- get enclosingElement => super.enclosingElement;
-
- ClosureClassElement get closureClass => super.enclosingElement;
-
- MemberElement get memberContext => closureClass.methodElement.memberContext;
-
- @override
- Local get declaredEntity => local;
-
- @override
- Entity get rootOfScope => closureClass;
-
- bool get hasNode => false;
-
- VariableDefinitions get node {
- throw failedAt(local, 'Should not access node of ClosureFieldElement.');
- }
-
- bool get hasResolvedAst => hasTreeElements;
-
- ResolvedAst get resolvedAst {
- return new ParsedResolvedAst(this, null, null, treeElements,
- memberContext.compilationUnit.script.resourceUri);
- }
-
- Expression get initializer {
- throw failedAt(
- local, 'Should not access initializer of ClosureFieldElement.');
- }
-
- bool get isInstanceMember => true;
- bool get isAssignable => false;
-
- ResolutionDartType computeType(Resolution resolution) => type;
-
- ResolutionDartType get type {
- if (local is LocalElement) {
- LocalElement element = local;
- return element.type;
- }
- return const ResolutionDynamicType();
- }
-
- String toString() => "ClosureFieldElement($name)";
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitClosureFieldElement(this, arg);
- }
-
- AnalyzableElement get analyzableElement =>
- closureClass.methodElement.analyzableElement;
-
- @override
- List<MethodElement> get nestedClosures => const <MethodElement>[];
-
- @override
- bool get hasConstant => false;
-
- @override
- ConstantExpression get constant => null;
-}
-
-// TODO(ahe): These classes continuously cause problems. We need to find
-// a more general solution.
-class ClosureClassElement extends ClassElementX {
- ResolutionInterfaceType rawType;
- ResolutionInterfaceType thisType;
- ResolutionFunctionType callType;
-
- /// Node that corresponds to this closure, used for source position.
- final FunctionExpression node;
-
- /**
- * The element for the declaration of the function expression.
- */
- final LocalFunctionElement methodElement;
-
- final List<ClosureFieldElement> _closureFields = <ClosureFieldElement>[];
-
- ClosureClassElement(
- this.node, String name, Compiler compiler, LocalFunctionElement closure)
- : this.methodElement = closure,
- super(
- name,
- closure.compilationUnit,
- // By assigning a fresh class-id we make sure that the hashcode
- // is unique, but also emit closure classes after all other
- // classes (since the emitter sorts classes by their id).
- compiler.idGenerator.getNextFreeId(),
- STATE_DONE) {
- ClassElement superclass = compiler.resolution.commonElements.closureClass;
- superclass.ensureResolved(compiler.resolution);
- supertype = superclass.thisType;
- interfaces = const Link<ResolutionDartType>();
- thisType = rawType = new ResolutionInterfaceType(this);
- allSupertypesAndSelf =
- superclass.allSupertypesAndSelf.extendClass(thisType);
- callType = methodElement.type;
- }
-
- MethodElement get callMethod => methodElement.callMethod;
-
- Iterable<ClosureFieldElement> get closureFields => _closureFields;
-
- void addField(ClosureFieldElement field, DiagnosticReporter listener) {
- _closureFields.add(field);
- addMember(field, listener);
- }
-
- bool get hasNode => true;
-
- bool get isClosure => true;
-
- Token get position => node.getBeginToken();
-
- Node parseNode(ParsingContext parsing) => node;
-
- // A [ClosureClassElement] is nested inside a function or initializer in terms
- // of [enclosingElement], but still has to be treated as a top-level
- // element.
- bool get isTopLevel => true;
-
- get enclosingElement => methodElement;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitClosureClassElement(this, arg);
- }
-}
-
/// A local variable that contains the box object holding the [BoxFieldElement]
/// fields.
class BoxLocal extends Local {
@@ -549,73 +245,6 @@
String toString() => 'BoxLocal($name)';
}
-class BoxLocalVariable extends BoxLocal implements LocalVariable {
- final MemberElement memberContext;
-
- BoxLocalVariable(String name, this.memberContext) : super(name);
-
- ExecutableElement get executableContext => memberContext;
-}
-
-// TODO(ngeoffray, ahe): These classes continuously cause problems. We need to
-// find a more general solution.
-class BoxFieldElement extends ElementX
- implements TypedElement, FieldElement, PrivatelyNamedJSEntity {
- final LocalVariableElement variableElement;
- final BoxLocalVariable box;
-
- BoxFieldElement(String name, this.variableElement, BoxLocalVariable box)
- : this.box = box,
- super(name, ElementKind.FIELD, box.executableContext);
-
- ResolutionDartType computeType(Resolution resolution) => type;
-
- ResolutionDartType get type => variableElement.type;
-
- @override
- Local get declaredEntity => variableElement;
-
- @override
- Entity get rootOfScope => box;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitBoxFieldElement(this, arg);
- }
-
- @override
- bool get hasNode => false;
-
- @override
- bool get hasResolvedAst => false;
-
- @override
- Expression get initializer {
- throw new UnsupportedError("BoxFieldElement.initializer");
- }
-
- @override
- MemberElement get memberContext => box.memberContext;
-
- @override
- List<MethodElement> get nestedClosures => const <MethodElement>[];
-
- @override
- VariableDefinitions get node {
- throw new UnsupportedError("BoxFieldElement.node");
- }
-
- @override
- ResolvedAst get resolvedAst {
- throw new UnsupportedError("BoxFieldElement.resolvedAst");
- }
-
- @override
- bool get hasConstant => false;
-
- @override
- ConstantExpression get constant => null;
-}
-
/// A local variable used encode the direct (uncaptured) references to [this].
class ThisLocal extends Local {
final ClassEntity enclosingClass;
@@ -631,906 +260,6 @@
int get hashCode => enclosingClass.hashCode;
}
-/// A local variable used encode the direct (uncaptured) references to [this].
-class ThisLocalVariable extends ThisLocal implements LocalVariable {
- final MemberElement memberContext;
-
- ThisLocalVariable(this.memberContext) : super(memberContext);
-
- ExecutableElement get executableContext => memberContext;
-}
-
-/// Call method of a closure class.
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class SynthesizedCallMethodElementX extends BaseFunctionElementX
- implements MethodElement {
- final LocalFunctionElement expression;
- final FunctionExpression node;
- final TreeElements treeElements;
-
- SynthesizedCallMethodElementX(String name, LocalFunctionElement other,
- ClosureClassElement enclosing, this.node, this.treeElements)
- : expression = other,
- super(name, other.kind, Modifiers.EMPTY, enclosing) {
- asyncMarker = other.asyncMarker;
- functionSignature = other.functionSignature;
- expression.callMethod = this;
- }
-
- /// Use [closureClass] instead.
- @deprecated
- get enclosingElement => super.enclosingElement;
-
- ClosureClassElement get closureClass => super.enclosingElement;
-
- MemberElement get memberContext {
- return closureClass.methodElement.memberContext;
- }
-
- SourceSpan get sourcePosition => expression.sourcePosition;
-
- bool get hasNode => node != null;
-
- FunctionExpression parseNode(ParsingContext parsing) => node;
-
- AnalyzableElement get analyzableElement =>
- closureClass.methodElement.analyzableElement;
-
- bool get hasResolvedAst => true;
-
- ResolvedAst get resolvedAst {
- return new ParsedResolvedAst(this, node, node.body, treeElements,
- expression.compilationUnit.script.resourceUri);
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitMethodElement(this, arg);
- }
-}
-
-// The box-element for a scope, and the captured variables that need to be
-// stored in the box.
-class CapturedScopeImpl implements CapturedScope, CapturedLoopScope {
- final BoxLocal boxElement;
- final Map<Local, BoxFieldElement> capturedVariables;
-
- // If the scope is attached to a [For] contains the variables that are
- // declared in the initializer of the [For] and that need to be boxed.
- // Otherwise contains the empty List.
- List<Local> boxedLoopVariables = const <Local>[];
-
- CapturedScopeImpl(this.boxElement, this.capturedVariables);
-
- Local get context => boxElement;
-
- bool get requiresContextBox => capturedVariables.keys.isNotEmpty;
-
- void forEachBoxedVariable(f(Local local, FieldEntity field)) {
- capturedVariables.forEach(f);
- }
-
- bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
-
- bool isBoxed(Local variable) {
- return capturedVariables.containsKey(variable);
- }
-
- void forEachCapturedVariable(
- f(LocalVariableElement variable, BoxFieldElement boxField)) {
- capturedVariables.forEach(f);
- }
-
- // Should not be called. Added to make the new interface happy.
- bool localIsUsedInTryOrSync(Local variable) =>
- throw new UnsupportedError("CapturedScopeImpl.localIsUsedInTryOrSync");
-
- // Should not be called. Added to make the new interface happy.
- Local get thisLocal =>
- throw new UnsupportedError("CapturedScopeImpl.thisLocal");
-
- String toString() {
- String separator = '';
- StringBuffer sb = new StringBuffer();
- sb.write('CapturedScopeImpl(');
- if (boxElement != null) {
- sb.write('box=$boxElement');
- separator = ',';
- }
- if (boxedLoopVariables.isNotEmpty) {
- sb.write(separator);
- sb.write('boxedLoopVariables=${boxedLoopVariables}');
- separator = ',';
- }
- if (capturedVariables.isNotEmpty) {
- sb.write(separator);
- sb.write('capturedVariables=$capturedVariables');
- }
- sb.write(')');
- return sb.toString();
- }
-}
-
-class ClosureClassMap implements ClosureRepresentationInfo {
- /// The local function element before any translation.
- ///
- /// Will be null for methods.
- final LocalFunctionElement closureEntity;
-
- /// The synthesized closure class for [closureEntity].
- ///
- /// The closureClassEntity will be null for methods that are not local
- /// closures.
- final ClosureClassElement closureClassEntity;
-
- /// The synthesized `call` method of the [closureClassEntity].
- ///
- /// The callMethod will be null for methods that are not local closures.
- final MethodElement callMethod;
-
- /// The [thisLocal] makes handling 'this' easier by treating it like any
- /// other argument. It is only set for instance-members.
- final ThisLocal thisLocal;
-
- /// Maps free locals, arguments, function elements, and box locals to
- /// their locations.
- final Map<Local, FieldEntity> freeVariableMap = new Map<Local, FieldEntity>();
-
- /// Maps [Loop] and [FunctionExpression] nodes to their [CapturedScopeImpl] which
- /// contains their box and the captured variables that are stored in the box.
- /// This map will be empty if the method/closure of this [ClosureData] does
- /// not contain any nested closure.
- final Map<Node, CapturedScopeImpl> capturingScopes =
- new Map<Node, CapturedScopeImpl>();
-
- /// Set of [variable]s referenced in this scope that are used inside a
- /// `try` block or a `sync*` generator (this is important to know because
- /// boxing/redirection needs to happen for those local variables).
- ///
- /// Variables that are used in a try must be treated as boxed because the
- /// control flow can be non-linear.
- ///
- /// Also parameters to a `sync*` generator must be boxed, because of the way
- /// we rewrite sync* functions. See also comments in [useLocal].
- // TODO(johnniwinther): Add variables to this only if the variable is mutated.
- final Set<Local> localsUsedInTryOrSync = new Set<Local>();
-
- ClosureClassMap(this.closureEntity, this.closureClassEntity, this.callMethod,
- this.thisLocal);
-
- List<Local> get createdFieldEntities {
- List<Local> fields = <Local>[];
- if (closureClassEntity == null) return const <Local>[];
- closureClassEntity.closureFields.forEach((field) {
- fields.add(field.local);
- });
- return fields;
- }
-
- @override
- Local getLocalForField(covariant ClosureFieldElement field) => field.local;
-
- void addFreeVariable(Local element) {
- assert(freeVariableMap[element] == null);
- freeVariableMap[element] = null;
- }
-
- Iterable<Local> get freeVariables => freeVariableMap.keys;
-
- bool isFreeVariable(Local element) {
- return freeVariableMap.containsKey(element);
- }
-
- void forEachFreeVariable(f(Local variable, FieldEntity field)) {
- freeVariableMap.forEach(f);
- }
-
- FieldEntity get thisFieldEntity => freeVariableMap[thisLocal];
-
- bool localIsUsedInTryOrSync(Local variable) =>
- localsUsedInTryOrSync.contains(variable);
-
- Local getLocalVariableForClosureField(ClosureFieldElement field) {
- return field.local;
- }
-
- bool get isClosure => closureEntity != null;
-
- bool capturingScopesBox(Local variable) {
- return capturingScopes.values.any((scope) {
- return scope.boxedLoopVariables.contains(variable);
- });
- }
-
- bool isVariableBoxed(Local variable) {
- FieldEntity copy = freeVariableMap[variable];
- if (copy is BoxFieldElement) {
- return true;
- }
- return capturingScopesBox(variable);
- }
-
- void forEachBoxedVariable(
- void f(LocalVariableElement local, BoxFieldElement field)) {
- freeVariableMap.forEach((variable, copy) {
- if (!isVariableBoxed(variable)) return;
- f(variable, copy);
- });
- capturingScopes.values.forEach((CapturedScopeImpl scope) {
- scope.forEachCapturedVariable(f);
- });
- }
-
- bool isBoxed(Local local) {
- bool variableIsBoxed = false;
- forEachBoxedVariable((LocalVariableElement element, BoxFieldElement field) {
- if (element == local) variableIsBoxed = true;
- });
- return variableIsBoxed;
- }
-}
-
-class ClosureTranslator extends Visitor {
- final Compiler compiler;
- final ClosedWorldRefiner closedWorldRefiner;
- final TreeElements elements;
- int closureFieldCounter = 0;
- int boxedFieldCounter = 0;
- bool inTryStatement = false;
-
- final Map<MemberElement, ClosureClassMap> memberMappingCache;
- final Map<FunctionExpression, ClosureClassMap> nodeMappingCache;
- final Map<Node, CapturedScopeImpl> closureInfo;
-
- // Map of captured variables. Initially they will map to `null`. If
- // a variable needs to be boxed then the scope declaring the variable
- // will update this to mapping to the capturing [BoxFieldElement].
- Map<Local, BoxFieldElement> _capturedVariableMapping =
- new Map<Local, BoxFieldElement>();
-
- // List of encountered closures.
- List<FunctionExpression> closures = <FunctionExpression>[];
-
- // The local variables that have been declared in the current scope.
- List<LocalVariableElement> scopeVariables;
-
- // Keep track of the mutated local variables so that we don't need to box
- // non-mutated variables.
- Set<LocalVariableElement> mutatedVariables = new Set<LocalVariableElement>();
-
- MemberElement outermostElement;
- ExecutableElement executableContext;
-
- // The closureData of the currentFunctionElement.
- ClosureClassMap closureData;
-
- bool insideClosure = false;
-
- ClosureTranslator(this.compiler, this.closedWorldRefiner, this.elements,
- this.memberMappingCache, this.nodeMappingCache, this.closureInfo);
-
- DiagnosticReporter get reporter => compiler.reporter;
-
- RuntimeTypesNeed get rtiNeed => closedWorldRefiner.closedWorld.rtiNeed;
-
- /// Generate a unique name for the [id]th closure field, with proposed name
- /// [name].
- ///
- /// The result is used as the name of [ClosureFieldElement]s, and must
- /// therefore be unique to avoid breaking an invariant in the element model
- /// (classes cannot declare multiple fields with the same name).
- ///
- /// Also, the names should be distinct from real field names to prevent
- /// clashes with selectors for those fields.
- ///
- /// These names are not used in generated code, just as element name.
- String getClosureVariableName(String name, int id) {
- return "_captured_${name}_$id";
- }
-
- /// Generate a unique name for the [id]th box field, with proposed name
- /// [name].
- ///
- /// The result is used as the name of [BoxFieldElement]s, and must
- /// therefore be unique to avoid breaking an invariant in the element model
- /// (classes cannot declare multiple fields with the same name).
- ///
- /// Also, the names should be distinct from real field names to prevent
- /// clashes with selectors for those fields.
- ///
- /// These names are not used in generated code, just as element name.
- String getBoxFieldName(int id) {
- return "_box_$id";
- }
-
- bool isCapturedVariable(Local element) {
- return _capturedVariableMapping.containsKey(element);
- }
-
- void addCapturedVariable(Node node, Local variable) {
- if (_capturedVariableMapping[variable] != null) {
- reporter.internalError(node, 'In closure analyzer.');
- }
- _capturedVariableMapping[variable] = null;
- }
-
- void setCapturedVariableBoxField(Local variable, BoxFieldElement boxField) {
- assert(isCapturedVariable(variable));
- _capturedVariableMapping[variable] = boxField;
- }
-
- BoxFieldElement getCapturedVariableBoxField(Local variable) {
- return _capturedVariableMapping[variable];
- }
-
- void translateFunction(Element element, FunctionExpression node) {
- // For constructors the [element] and the [:elements[node]:] may differ.
- // The [:elements[node]:] always points to the generative-constructor
- // element, whereas the [element] might be the constructor-body element.
- visit(node); // [visitFunctionExpression] will call [visitInvokable].
- // When variables need to be boxed their [_capturedVariableMapping] is
- // updated, but we delay updating the similar freeVariableMapping in the
- // closure datas that capture these variables.
- // The closures don't have their fields (in the closure class) set, either.
- updateClosures();
- }
-
- void translateLazyInitializer(
- FieldElement element, VariableDefinitions node, Expression initializer) {
- visitInvokable(element, node, () {
- visit(initializer);
- });
- updateClosures();
- }
-
- // This function runs through all of the existing closures and updates their
- // free variables to the boxed value. It also adds the field-elements to the
- // class representing the closure.
- void updateClosures() {
- for (FunctionExpression closure in closures) {
- // The captured variables that need to be stored in a field of the closure
- // class.
- Set<Local> fieldCaptures = new Set<Local>();
- Set<BoxLocal> boxes = new Set<BoxLocal>();
- ClosureClassMap data = nodeMappingCache[closure];
- // We get a copy of the keys and iterate over it, to avoid modifications
- // to the map while iterating over it.
- Iterable<Local> freeVariables = data.freeVariables.toList();
- freeVariables.forEach((Local fromElement) {
- assert(data.isFreeVariable(fromElement));
- assert(data.freeVariableMap[fromElement] == null);
- assert(isCapturedVariable(fromElement));
- BoxFieldElement boxFieldElement =
- getCapturedVariableBoxField(fromElement);
- if (boxFieldElement == null) {
- assert(fromElement is! BoxLocal);
- // The variable has not been boxed.
- fieldCaptures.add(fromElement);
- } else {
- // A boxed element.
- data.freeVariableMap[fromElement] = boxFieldElement;
- boxes.add(boxFieldElement.box);
- }
- });
- ClosureClassElement closureClass = data.closureClassEntity;
- assert(closureClass != null || (fieldCaptures.isEmpty && boxes.isEmpty));
-
- void addClosureField(Local local, String name) {
- ClosureFieldElement closureField =
- new ClosureFieldElement(name, local, closureClass);
- closureClass.addField(closureField, reporter);
- data.freeVariableMap[local] = closureField;
- }
-
- // Add the box elements first so we get the same ordering.
- // TODO(sra): What is the canonical order of multiple boxes?
- for (BoxLocal capturedElement in boxes) {
- addClosureField(capturedElement, capturedElement.name);
- }
-
- /// Comparator for locals. Position boxes before elements.
- int compareLocals(a, b) {
- if (a is Element && b is Element) {
- return Elements.compareByPosition(a, b);
- } else if (a is Element) {
- return 1;
- } else if (b is Element) {
- return -1;
- } else {
- return a.name.compareTo(b.name);
- }
- }
-
- for (Local capturedLocal in fieldCaptures.toList()..sort(compareLocals)) {
- int id = closureFieldCounter++;
- String name = getClosureVariableName(capturedLocal.name, id);
- addClosureField(capturedLocal, name);
- }
- }
- }
-
- void useLocal(Local variable) {
- // If the element is not declared in the current function and the element
- // is not the closure itself we need to mark the element as free variable.
- // Note that the check on [insideClosure] is not just an
- // optimization: factories have type parameters as function
- // parameters, and type parameters are declared in the class, not
- // the factory.
- bool inCurrentContext(LocalVariable variable) {
- return variable == executableContext ||
- variable.executableContext == executableContext;
- }
-
- if (insideClosure && !inCurrentContext(variable)) {
- closureData.addFreeVariable(variable);
- } else if (inTryStatement) {
- // Don't mark the this-element or a self-reference. This would complicate
- // things in the builder.
- // Note that nested (named) functions are immutable.
- if (variable != closureData.thisLocal &&
- variable != closureData.closureEntity &&
- variable is! TypeVariableLocal) {
- closureData.localsUsedInTryOrSync.add(variable);
- }
- } else if (variable is LocalParameterElement &&
- variable.functionDeclaration.asyncMarker == AsyncMarker.SYNC_STAR) {
- // Parameters in a sync* function are shared between each Iterator created
- // by the Iterable returned by the function, therefore they must be boxed.
- closureData.localsUsedInTryOrSync.add(variable);
- }
- }
-
- void useTypeVariableAsLocal(ResolutionTypeVariableType typeVariable) {
- useLocal(new TypeVariableLocalVariable(
- typeVariable, outermostElement, outermostElement.memberContext));
- }
-
- void declareLocal(LocalVariableElement element) {
- scopeVariables.add(element);
- }
-
- void registerNeedsThis() {
- if (closureData.thisLocal != null) {
- useLocal(closureData.thisLocal);
- }
- }
-
- visit(Node node) => node.accept(this);
-
- visitNode(Node node) => node.visitChildren(this);
-
- visitVariableDefinitions(VariableDefinitions node) {
- if (node.type != null) {
- visit(node.type);
- }
- for (Link<Node> link = node.definitions.nodes;
- !link.isEmpty;
- link = link.tail) {
- Node definition = link.head;
- LocalElement element = elements[definition];
- assert(element != null);
- if (!element.isInitializingFormal) {
- declareLocal(element);
- }
- // We still need to visit the right-hand sides of the init-assignments.
- // For SendSets don't visit the left again. Otherwise it would be marked
- // as mutated.
- if (definition is Send) {
- Send assignment = definition;
- Node arguments = assignment.argumentsNode;
- if (arguments != null) {
- visit(arguments);
- }
- } else {
- visit(definition);
- }
- }
- }
-
- visitTypeAnnotation(TypeAnnotation node) {
- MemberElement member = executableContext.memberContext;
- ResolutionDartType type = elements.getType(node);
- // TODO(karlklose,johnniwinther): if the type is null, the annotation is
- // from a parameter which has been analyzed before the method has been
- // resolved and the result has been thrown away.
- if (compiler.options.enableTypeAssertions &&
- type != null &&
- type.containsTypeVariables) {
- if (insideClosure && member.isFactoryConstructor) {
- // This is a closure in a factory constructor. Since there is no
- // [:this:], we have to mark the type arguments as free variables to
- // capture them in the closure.
- type.forEachTypeVariable((ResolutionTypeVariableType variable) {
- useTypeVariableAsLocal(variable);
- });
- }
- if (member.isInstanceMember && !member.isField) {
- // In checked mode, using a type variable in a type annotation may lead
- // to a runtime type check that needs to access the type argument and
- // therefore the closure needs a this-element, if it is not in a field
- // initializer; field initializers are evaluated in a context where
- // the type arguments are available in locals.
- registerNeedsThis();
- }
- }
- }
-
- visitIdentifier(Identifier node) {
- if (node.isThis()) {
- registerNeedsThis();
- } else {
- Element element = elements[node];
- if (element != null && element.isTypeVariable) {
- if (outermostElement.isConstructor || outermostElement.isField) {
- TypeVariableElement typeVariable = element;
- useTypeVariableAsLocal(typeVariable.type);
- } else {
- registerNeedsThis();
- }
- }
- }
- node.visitChildren(this);
- }
-
- visitSend(Send node) {
- Element element = elements[node];
- if (Elements.isLocal(element)) {
- LocalElement localElement = element;
- useLocal(localElement);
- } else if (element != null && element.isTypeVariable) {
- TypeVariableElement variable = element;
- analyzeType(variable.type);
- } else if (node.receiver == null &&
- Elements.isInstanceSend(node, elements)) {
- registerNeedsThis();
- } else if (node.isSuperCall) {
- registerNeedsThis();
- } else if (node.isTypeTest || node.isTypeCast) {
- TypeAnnotation annotation = node.typeAnnotationFromIsCheckOrCast;
- ResolutionDartType type = elements.getType(annotation);
- analyzeType(type);
- } else if (node.isTypeTest) {
- ResolutionDartType type =
- elements.getType(node.typeAnnotationFromIsCheckOrCast);
- analyzeType(type);
- } else if (node.isTypeCast) {
- ResolutionDartType type = elements.getType(node.arguments.head);
- analyzeType(type);
- }
- node.visitChildren(this);
- }
-
- visitSendSet(SendSet node) {
- Element element = elements[node];
- if (Elements.isLocal(element)) {
- mutatedVariables.add(element);
- if (compiler.options.enableTypeAssertions) {
- TypedElement typedElement = element;
- analyzeTypeVariables(typedElement.type);
- }
- }
- super.visitSendSet(node);
- }
-
- visitNewExpression(NewExpression node) {
- ResolutionDartType type = elements.getType(node);
- analyzeType(type);
- node.visitChildren(this);
- }
-
- visitLiteralList(LiteralList node) {
- ResolutionDartType type = elements.getType(node);
- analyzeType(type);
- node.visitChildren(this);
- }
-
- visitLiteralMap(LiteralMap node) {
- ResolutionDartType type = elements.getType(node);
- analyzeType(type);
- node.visitChildren(this);
- }
-
- void analyzeTypeVariables(ResolutionDartType type) {
- type.forEachTypeVariable((ResolutionTypeVariableType typeVariable) {
- // Field initializers are inlined and access the type variable as
- // normal parameters.
- if (!outermostElement.isField && !outermostElement.isConstructor) {
- registerNeedsThis();
- } else {
- useTypeVariableAsLocal(typeVariable);
- }
- });
- }
-
- void analyzeType(ResolutionDartType type) {
- // TODO(johnniwinther): Find out why this can be null.
- if (type == null) return;
- if (outermostElement.isClassMember &&
- rtiNeed.classNeedsTypeArguments(outermostElement.enclosingClass)) {
- if (outermostElement.isConstructor || outermostElement.isField) {
- analyzeTypeVariables(type);
- } else if (outermostElement.isInstanceMember) {
- if (type.containsTypeVariables) {
- registerNeedsThis();
- }
- }
- }
- }
-
- // If variables that are declared in the [node] scope are captured and need
- // to be boxed create a box-element and update the [capturingScopes] in the
- // current [closureData].
- // The boxed variables are updated in the [capturedVariableMapping].
- void attachCapturedScopeVariables(Node node) {
- BoxLocalVariable box = null;
- Map<LocalVariableElement, BoxFieldElement> scopeMapping =
- new Map<LocalVariableElement, BoxFieldElement>();
-
- void boxCapturedVariable(LocalVariableElement variable) {
- if (isCapturedVariable(variable)) {
- if (box == null) {
- // TODO(floitsch): construct better box names.
- String boxName = getBoxFieldName(closureFieldCounter++);
- box = new BoxLocalVariable(boxName, executableContext.memberContext);
- }
- String elementName = variable.name;
- String boxedName =
- getClosureVariableName(elementName, boxedFieldCounter++);
- // TODO(kasperl): Should this be a FieldElement instead?
- BoxFieldElement boxed = new BoxFieldElement(boxedName, variable, box);
- scopeMapping[variable] = boxed;
- setCapturedVariableBoxField(variable, boxed);
- }
- }
-
- for (LocalVariableElement variable in scopeVariables) {
- // No need to box non-assignable elements.
- if (!variable.isAssignable) continue;
- if (!mutatedVariables.contains(variable)) continue;
- boxCapturedVariable(variable);
- }
- if (!scopeMapping.isEmpty) {
- CapturedScopeImpl scope = new CapturedScopeImpl(box, scopeMapping);
- closureData.capturingScopes[node] = scope;
- assert(closureInfo[node] == null);
- closureInfo[node] = scope;
- }
- }
-
- void inNewScope(Node node, Function action) {
- List<LocalVariableElement> oldScopeVariables = scopeVariables;
- scopeVariables = <LocalVariableElement>[];
- action();
- attachCapturedScopeVariables(node);
- mutatedVariables.removeAll(scopeVariables);
- scopeVariables = oldScopeVariables;
- }
-
- visitLoop(Loop node) {
- inNewScope(node, () {
- node.visitChildren(this);
- });
- }
-
- visitFor(For node) {
- List<LocalVariableElement> boxedLoopVariables = <LocalVariableElement>[];
- inNewScope(node, () {
- // First visit initializer and update so we can easily check if a loop
- // variable was captured in one of these subexpressions.
- if (node.initializer != null) visit(node.initializer);
- if (node.update != null) visit(node.update);
-
- // Loop variables that have not been captured yet can safely be flagged as
- // non-mutated, because no nested function can observe the mutation.
- if (node.initializer is VariableDefinitions) {
- VariableDefinitions definitions = node.initializer;
- definitions.definitions.nodes.forEach((Node node) {
- LocalVariableElement local = elements[node];
- if (!isCapturedVariable(local)) {
- mutatedVariables.remove(local);
- }
- });
- }
-
- // Visit condition and body.
- // This must happen after the above, so any loop variables mutated in the
- // condition or body are indeed flagged as mutated.
- if (node.conditionStatement != null) visit(node.conditionStatement);
- if (node.body != null) visit(node.body);
-
- // See if we have declared loop variables that need to be boxed.
- if (node.initializer == null) return;
- VariableDefinitions definitions =
- node.initializer.asVariableDefinitions();
- if (definitions == null) return;
- for (Link<Node> link = definitions.definitions.nodes;
- !link.isEmpty;
- link = link.tail) {
- Node definition = link.head;
- LocalVariableElement element = elements[definition];
- // Non-mutated variables should not be boxed. The mutatedVariables set
- // gets cleared when 'inNewScope' returns, so check it here.
- if (isCapturedVariable(element) && mutatedVariables.contains(element)) {
- boxedLoopVariables.add(element);
- }
- }
- });
- CapturedScopeImpl scopeData = closureData.capturingScopes[node];
- if (scopeData == null) return;
- scopeData.boxedLoopVariables = boxedLoopVariables;
- }
-
- /** Returns a non-unique name for the given closure element. */
- String computeClosureName(Element element) {
- Link<String> parts = const Link<String>();
- String ownName = element.name;
- if (ownName == null || ownName == "") {
- parts = parts.prepend("closure");
- } else {
- parts = parts.prepend(ownName);
- }
- for (Element enclosingElement = element.enclosingElement;
- enclosingElement != null &&
- (enclosingElement.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
- enclosingElement.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
- enclosingElement.kind == ElementKind.CLASS ||
- enclosingElement.kind == ElementKind.FUNCTION ||
- enclosingElement.kind == ElementKind.GETTER ||
- enclosingElement.kind == ElementKind.SETTER);
- enclosingElement = enclosingElement.enclosingElement) {
- // TODO(johnniwinther): Simplify computed names.
- if (enclosingElement.isGenerativeConstructor ||
- enclosingElement.isGenerativeConstructorBody ||
- enclosingElement.isFactoryConstructor) {
- ConstructorElement constructor = enclosingElement;
- parts = parts.prepend(utils.reconstructConstructorName(constructor));
- } else {
- String surroundingName =
- Elements.operatorNameToIdentifier(enclosingElement.name);
- parts = parts.prepend(surroundingName);
- }
- // A generative constructors's parent is the class; the class name is
- // already part of the generative constructor's name.
- if (enclosingElement.kind == ElementKind.GENERATIVE_CONSTRUCTOR) break;
- }
- StringBuffer sb = new StringBuffer();
- parts.printOn(sb, '_');
- return sb.toString();
- }
-
- JavaScriptBackend get backend => compiler.backend;
-
- ClosureClassMap globalizeClosure(
- FunctionExpression node, LocalFunctionElement element) {
- String closureName = computeClosureName(element);
- ClosureClassElement globalizedElement =
- new ClosureClassElement(node, closureName, compiler, element);
- MethodElement callElement = new SynthesizedCallMethodElementX(
- Identifiers.call, element, globalizedElement, node, elements);
- // Extend [globalizedElement] as an instantiated class in the closed world.
- closedWorldRefiner.registerClosureClass(globalizedElement);
- backend.mirrorsDataBuilder.maybeMarkClosureAsNeededForReflection(
- globalizedElement, callElement, element);
- MemberElement enclosing = element.memberContext;
- enclosing.nestedClosures.add(callElement);
- globalizedElement.addMember(callElement, reporter);
- globalizedElement.computeAllClassMembers(compiler.resolution);
- // The nested function's 'this' is the same as the one for the outer
- // function. It could be [null] if we are inside a static method.
- ThisLocal thisElement = closureData.thisLocal;
-
- return new ClosureClassMap(
- element, globalizedElement, callElement, thisElement);
- }
-
- void visitInvokable(
- ExecutableElement element, Node node, void visitChildren()) {
- bool oldInsideClosure = insideClosure;
- Element oldFunctionElement = executableContext;
- ClosureClassMap oldClosureData = closureData;
-
- insideClosure = outermostElement != null;
- LocalFunctionElement closure;
- executableContext = element;
- bool needsRti = false;
- if (insideClosure) {
- closure = element;
- closures.add(node);
- nodeMappingCache[node] = closureData = globalizeClosure(node, closure);
- needsRti = compiler.options.enableTypeAssertions ||
- rtiNeed.localFunctionNeedsSignature(closure);
- } else {
- outermostElement = element;
- ThisLocal thisElement = null;
- if (element.isInstanceMember || element.isGenerativeConstructor) {
- MemberElement member = element;
- thisElement = new ThisLocalVariable(member);
- }
- closureData = new ClosureClassMap(null, null, null, thisElement);
- memberMappingCache[element] = closureData;
- memberMappingCache[element.declaration] = closureData;
- if (element is MethodElement) {
- needsRti = compiler.options.enableTypeAssertions ||
- rtiNeed.methodNeedsSignature(element);
- }
- }
- if (closureData.callMethod != null) {
- memberMappingCache[closureData.callMethod] = closureData;
- }
-
- inNewScope(node, () {
- // If the method needs RTI, or checked mode is set, we need to
- // escape the potential type variables used in that closure.
- if (needsRti) {
- analyzeTypeVariables(element.type);
- }
-
- visitChildren();
- });
-
- ClosureClassMap savedClosureData = closureData;
- bool savedInsideClosure = insideClosure;
-
- // Restore old values.
- insideClosure = oldInsideClosure;
- closureData = oldClosureData;
- executableContext = oldFunctionElement;
-
- // Mark all free variables as captured and use them in the outer function.
- Iterable<Local> freeVariables = savedClosureData.freeVariables;
- assert(freeVariables.isEmpty || savedInsideClosure);
- for (Local freeVariable in freeVariables) {
- addCapturedVariable(node, freeVariable);
- useLocal(freeVariable);
- }
- }
-
- visitFunctionExpression(FunctionExpression node) {
- Element element = elements[node];
-
- if (element.isRegularParameter) {
- // TODO(ahe): This is a hack. This method should *not* call
- // visitChildren.
- return node.name.accept(this);
- }
-
- visitInvokable(element, node, () {
- // TODO(ahe): This is problematic. The backend should not repeat
- // the work of the resolver. It is the resolver's job to create
- // parameters, etc. Other phases should only visit statements.
- if (node.parameters != null) node.parameters.accept(this);
- if (node.initializers != null) node.initializers.accept(this);
- if (node.body != null) node.body.accept(this);
- });
- }
-
- visitTryStatement(TryStatement node) {
- // TODO(ngeoffray): implement finer grain state.
- bool oldInTryStatement = inTryStatement;
- inTryStatement = true;
- node.visitChildren(this);
- inTryStatement = oldInTryStatement;
- }
-
- visitCatchBlock(CatchBlock node) {
- if (node.type != null) {
- // The "on T" clause may contain type variables.
- analyzeType(elements.getType(node.type));
- }
- if (node.formals != null) {
- node.formals.visitChildren(this);
- }
- node.block.accept(this);
- }
-
- visitAsyncForIn(AsyncForIn node) {
- // An `await for` loop is enclosed in an implicit try-finally.
- bool oldInTryStatement = inTryStatement;
- inTryStatement = true;
- visitLoop(node);
- inTryStatement = oldInTryStatement;
- }
-}
-
/// A type variable as a local variable.
class TypeVariableLocal implements Local {
final TypeVariableType typeVariable;
@@ -1555,16 +284,6 @@
}
}
-class TypeVariableLocalVariable extends TypeVariableLocal
- implements LocalVariable {
- final ExecutableElement executableContext;
- final MemberElement memberContext;
-
- TypeVariableLocalVariable(
- TypeVariableType typeVariable, this.executableContext, this.memberContext)
- : super(typeVariable);
-}
-
///
/// Move the below classes to a JS model eventually.
///
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 0ab7475..5c38952 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -5,31 +5,8 @@
library dart2js.backend_api;
import '../common/resolution.dart' show ResolutionImpact;
-import '../constants/expressions.dart' show ConstantExpression;
-import '../elements/resolution_types.dart'
- show ResolutionDartType, ResolutionInterfaceType;
-import '../tree/tree.dart' show Node;
import '../universe/world_impact.dart' show WorldImpact;
-/// Interface for resolving native data for a target specific element.
-abstract class NativeRegistry {
- /// Registers [nativeData] as part of the resolution impact.
- void registerNativeData(dynamic nativeData);
-}
-
-/// Interface for resolving calls to foreign functions.
-abstract class ForeignResolver {
- /// Returns the constant expression of [node], or `null` if [node] is not
- /// a constant expression.
- ConstantExpression getConstant(Node node);
-
- /// Registers [type] as instantiated.
- void registerInstantiatedType(ResolutionInterfaceType type);
-
- /// Resolves [typeName] to a type in the context of [node].
- ResolutionDartType resolveTypeFromString(Node node, String typeName);
-}
-
/// Target-specific transformation for resolution world impacts.
///
/// This processes target-agnostic [ResolutionImpact]s and creates [WorldImpact]
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 327c9e5..5d1116c 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -222,10 +222,6 @@
static final Uri dart__foreign_helper =
new Uri(scheme: 'dart', path: '_foreign_helper');
- /// The URI for 'dart:_js_mirrors'.
- static final Uri dart__js_mirrors =
- new Uri(scheme: 'dart', path: '_js_mirrors');
-
/// The URI for 'dart:_js_names'.
static final Uri dart__js_names = new Uri(scheme: 'dart', path: '_js_names');
@@ -233,10 +229,6 @@
static final Uri dart__js_embedded_names =
new Uri(scheme: 'dart', path: '_js_embedded_names');
- /// The URI for 'dart:_isolate_helper'.
- static final Uri dart__isolate_helper =
- new Uri(scheme: 'dart', path: '_isolate_helper');
-
/// The URI for 'package:js'.
static final Uri package_js = new Uri(scheme: 'package', path: 'js/js.dart');
}
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 3965ba8..b0eb1ac 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -4,64 +4,10 @@
library dart2js.common.resolution;
-import '../common.dart';
-import '../compile_time_constants.dart';
import '../constants/expressions.dart' show ConstantExpression;
-import '../constants/values.dart' show ConstantValue;
-import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../elements/resolution_types.dart' show ResolutionDartType, Types;
-import '../elements/elements.dart'
- show
- ClassElement,
- Element,
- ExecutableElement,
- FunctionElement,
- FunctionSignature,
- LibraryElement,
- MemberElement,
- MetadataAnnotation,
- MethodElement,
- ResolvedAst,
- TypedefElement;
import '../elements/entities.dart';
-import '../enqueue.dart' show ResolutionEnqueuer;
-import '../id_generator.dart';
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../mirrors_used.dart';
-import '../options.dart' show CompilerOptions;
-import '../parser/element_listener.dart' show ScannerOptions;
-import '../parser/parser_task.dart';
-import '../scanner/scanner_task.dart';
-import '../patch_parser.dart';
-import '../resolution/resolution.dart';
-import '../tree/tree.dart' show Send, TypeAnnotation;
-import '../universe/call_structure.dart' show CallStructure;
import '../universe/world_impact.dart' show WorldImpact;
import '../universe/feature.dart';
-import 'backend_api.dart';
-import 'work.dart' show WorkItem;
-
-/// [WorkItem] used exclusively by the [ResolutionEnqueuer].
-abstract class ResolutionWorkItem implements WorkItem {
- factory ResolutionWorkItem(Resolution resolution, MemberElement element) =
- _ResolutionWorkItem;
-}
-
-class _ResolutionWorkItem extends WorkItem implements ResolutionWorkItem {
- bool _isAnalyzed = false;
- final MemberElement element;
- final Resolution resolution;
-
- _ResolutionWorkItem(this.resolution, this.element);
-
- WorldImpact run() {
- assert(!_isAnalyzed,
- failedAt(element, 'Element ${element} has already been analyzed'));
- WorldImpact impact = resolution.computeWorldImpact(element);
- _isAnalyzed = true;
- return impact;
- }
-}
class ResolutionImpact extends WorldImpact {
const ResolutionImpact();
@@ -76,190 +22,3 @@
Iterable<dynamic> get nativeData => const <dynamic>[];
}
-
-/// Interface defining target-specific behavior for resolution.
-abstract class Target {
- /// Returns `true` if [library] is a target specific library whose members
- /// have special treatment, such as being allowed to extends blacklisted
- /// classes or members being eagerly resolved.
- bool isTargetSpecificLibrary(LibraryElement element);
-
- /// Resolve target specific information for [element] and register it with
- /// [registry].
- void resolveNativeMember(MemberElement element, NativeRegistry registry) {}
-
- /// Processes [element] for resolution and returns the [MethodElement] that
- /// defines the implementation of [element].
- MethodElement resolveExternalFunction(MethodElement element) => element;
-
- /// Called when resolving a call to a foreign function. If a non-null value
- /// is returned, this is stored as native data for [node] in the resolved
- /// AST.
- dynamic resolveForeignCall(Send node, Element element,
- CallStructure callStructure, ForeignResolver resolver) {
- return null;
- }
-
- /// Returns `true` if [element] is a default implementation of `noSuchMethod`
- /// used by the target.
- bool isDefaultNoSuchMethod(MethodElement element);
-
- /// Returns the default superclass for the given [element] in this target.
- ClassElement defaultSuperclass(ClassElement element);
-
- /// Returns `true` if [element] is a native class, that is, that the
- /// corresponding entity already exists in the target language.
- bool isNativeClass(ClassEntity element) => false;
-
- /// Returns `true` if [element] is a foreign element, that is, that the
- /// backend has specialized handling for the element.
- bool isForeign(Element element) => false;
-
- /// Returns `true` if this target supports async/await.
- bool get supportsAsyncAwait => true;
-}
-
-// TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
-abstract class Resolution {
- ParsingContext get parsingContext;
- DiagnosticReporter get reporter;
- ElementEnvironment get elementEnvironment;
- CommonElements get commonElements;
- Types get types;
- Target get target;
- ResolverTask get resolver;
- ResolutionEnqueuer get enqueuer;
- CompilerOptions get options;
- IdGenerator get idGenerator;
- ConstantEnvironment get constants;
- MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask;
-
- /// Whether internally we computed the constant for the [proxy] variable
- /// defined in dart:core (used only for testing).
- // TODO(sigmund): delete, we need a better way to test this.
- bool get wasProxyConstantComputedTestingOnly;
-
- /// If set to `true` resolution caches will not be cleared. Use this only for
- /// testing.
- bool retainCachesForTesting;
-
- void resolveTypedef(TypedefElement typdef);
- void resolveClass(ClassElement cls);
- void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation);
- FunctionSignature resolveSignature(FunctionElement function);
- ResolutionDartType resolveTypeAnnotation(
- Element element, TypeAnnotation node);
-
- /// Returns `true` if [element] has been resolved.
- bool hasBeenResolved(Element element);
-
- /// Resolve [element] if it has not already been resolved.
- void ensureResolved(Element element);
-
- /// Ensure the resolution of all members of [element].
- void ensureClassMembers(ClassElement element);
-
- /// Registers that [element] has a compile time error.
- ///
- /// The error itself is given in [message].
- void registerCompileTimeError(Element element, DiagnosticMessage message);
-
- ResolutionWorkItem createWorkItem(MemberElement element);
-
- /// Returns `true` if [element] as a fully computed [ResolvedAst].
- bool hasResolvedAst(ExecutableElement element);
-
- /// Returns the `ResolvedAst` for the [element].
- ResolvedAst getResolvedAst(ExecutableElement element);
-
- /// Returns `true` if the [ResolutionImpact] for [element] is cached.
- bool hasResolutionImpact(MemberElement element);
-
- /// Returns the precomputed [ResolutionImpact] for [element].
- ResolutionImpact getResolutionImpact(MemberElement element);
-
- /// Returns the [ResolvedAst] for [element], computing it if necessary.
- ResolvedAst computeResolvedAst(MemberElement element);
-
- /// Returns the precomputed [WorldImpact] for [element].
- WorldImpact getWorldImpact(MemberElement element);
-
- /// Computes the [WorldImpact] for [element].
- WorldImpact computeWorldImpact(MemberElement element);
-
- WorldImpact transformResolutionImpact(
- MemberElement element, ResolutionImpact resolutionImpact);
-
- /// Removes the [WorldImpact] for [element] from the resolution cache. Later
- /// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
- void uncacheWorldImpact(MemberElement element);
-
- /// Removes the [WorldImpact]s for all [Element]s in the resolution cache. ,
- /// Later calls to [getWorldImpact] or [computeWorldImpact] returns an empty
- /// impact.
- void emptyCache();
-
- /// Returns `true` if [value] is the top-level [proxy] annotation from the
- /// core library.
- bool isProxyConstant(ConstantValue value);
-
- // TODO(het): Remove this once we move to the kernel-based frontend. This is
- // an escape hatch for types that can't be added to an impact. For example,
- // resolving a method signature will register the classes seen in the
- // signature.
- @deprecated
- void registerClass(ClassEntity cls);
-}
-
-/// A container of commonly used dependencies for tasks that involve parsing.
-abstract class ParsingContext {
- factory ParsingContext(
- DiagnosticReporter reporter,
- ParserTask parser,
- ScannerTask scanner,
- PatchParserTask patchParser,
- JavaScriptBackend backend) = _ParsingContext;
-
- DiagnosticReporter get reporter;
- ParserTask get parser;
- ScannerTask get scanner;
- PatchParserTask get patchParser;
-
- /// Use [patchParser] directly instead.
- @deprecated
- void parsePatchClass(ClassElement cls);
-
- /// Use [parser] and measure directly instead.
- @deprecated
- measure(f());
-
- /// Get the [ScannerOptions] to scan the given [element].
- ScannerOptions getScannerOptionsFor(Element element);
-}
-
-class _ParsingContext implements ParsingContext {
- final DiagnosticReporter reporter;
- final ParserTask parser;
- final ScannerTask scanner;
- final PatchParserTask patchParser;
- final JavaScriptBackend backend;
-
- _ParsingContext(
- this.reporter, this.parser, this.scanner, this.patchParser, this.backend);
-
- @override
- measure(f()) => parser.measure(f);
-
- @override
- void parsePatchClass(ClassElement cls) {
- patchParser.measure(() {
- if (cls.isPatch) {
- patchParser.parsePatchClassNode(cls);
- }
- });
- }
-
- @override
- ScannerOptions getScannerOptionsFor(Element element) => new ScannerOptions(
- canUseNative: backend.canLibraryUseNative(element.library));
-}
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index ff7d0d7..0e83adc 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -137,10 +137,6 @@
LibraryEntity get foreignLibrary =>
_foreignLibrary ??= _env.lookupLibrary(Uris.dart__foreign_helper);
- LibraryEntity _isolateHelperLibrary;
- LibraryEntity get isolateHelperLibrary =>
- _isolateHelperLibrary ??= _env.lookupLibrary(Uris.dart__isolate_helper);
-
/// Reference to the internal library to lookup functions to always inline.
LibraryEntity _internalLibrary;
LibraryEntity get internalLibrary => _internalLibrary ??=
@@ -599,19 +595,6 @@
_asyncStarStreamControllerFactory ??=
_findAsyncHelperFunction('_makeAsyncStarStreamController');
- // From dart:mirrors
- FunctionEntity _findMirrorsFunction(String name) {
- LibraryEntity library = _env.lookupLibrary(Uris.dart__js_mirrors);
- if (library == null) return null;
- return _env.lookupLibraryMember(library, name, required: true);
- }
-
- /// Holds the method "disableTreeShaking" in js_mirrors when
- /// dart:mirrors has been loaded.
- FunctionEntity _disableTreeShakingMarker;
- FunctionEntity get disableTreeShakingMarker =>
- _disableTreeShakingMarker ??= _findMirrorsFunction('disableTreeShaking');
-
/// Holds the method "preserveNames" in js_mirrors when
/// dart:mirrors has been loaded.
FunctionEntity _preserveNamesMarker;
@@ -625,19 +608,6 @@
return _preserveNamesMarker;
}
- /// Holds the method "preserveMetadata" in js_mirrors when
- /// dart:mirrors has been loaded.
- FunctionEntity _preserveMetadataMarker;
- FunctionEntity get preserveMetadataMarker =>
- _preserveMetadataMarker ??= _findMirrorsFunction('preserveMetadata');
-
- /// Holds the method "preserveLibraryNames" in js_mirrors when
- /// dart:mirrors has been loaded.
- FunctionEntity _preserveLibraryNamesMarker;
- FunctionEntity get preserveLibraryNamesMarker =>
- _preserveLibraryNamesMarker ??=
- _findMirrorsFunction('preserveLibraryNames');
-
// From dart:_interceptors
ClassEntity _findInterceptorsClass(String name) =>
_findClass(interceptorsLibrary, name);
@@ -1442,8 +1412,6 @@
ClassEntity cls, List<DartType> typeArguments);
/// Returns the `dynamic` type.
- // TODO(johnniwinther): Remove this when `ResolutionDynamicType` is no longer
- // needed.
DartType get dynamicType;
/// Returns the 'raw type' of [cls]. That is, the instantiation of [cls]
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 8a93589..9055af7 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -4,1459 +4,27 @@
library dart2js.compile_time_constant_evaluator;
-import 'common/resolution.dart' show Resolution;
import 'common/tasks.dart' show CompilerTask, Measurer;
-import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constant_system_dart.dart';
import 'constants/constant_system.dart';
-import 'constants/constructors.dart';
-import 'constants/evaluation.dart';
-import 'constants/expressions.dart';
-import 'constants/values.dart';
-import 'common_elements.dart' show CommonElements;
-import 'elements/elements.dart';
-import 'elements/types.dart' show DartTypes;
-import 'elements/modelx.dart' show ConstantVariableMixin;
-import 'elements/operators.dart';
-import 'elements/resolution_types.dart';
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'resolution/deferred_load.dart' show AstDeferredLoadTask;
-import 'tree/tree.dart';
-import 'universe/call_structure.dart' show CallStructure;
-import 'util/util.dart' show Link;
+import 'elements/entities.dart';
/// A [ConstantEnvironment] provides access for constants compiled for variable
/// initializers.
abstract class ConstantEnvironment {
/// The [ConstantSystem] used by this environment.
ConstantSystem get constantSystem;
-
- /// Returns `true` if a value has been computed for [expression].
- bool hasConstantValue(ConstantExpression expression);
-
- /// Returns the constant value computed for [expression].
- // TODO(johnniwinther): Support directly evaluation of [expression].
- ConstantValue getConstantValue(ConstantExpression expression);
-
- /// Returns the constant value for the initializer of [element].
- @deprecated
- ConstantValue getConstantValueForVariable(VariableElement element);
-}
-
-/// A class that can compile and provide constants for variables, nodes and
-/// metadata.
-abstract class ConstantCompiler extends ConstantEnvironment {
- /// Compiles the compile-time constant for the initializer of [element], or
- /// reports an error if the initializer is not a compile-time constant.
- ///
- /// Depending on implementation, the constant compiler might also compute
- /// the compile-time constant for the backend interpretation of constants.
- ///
- /// The returned constant is always of the frontend interpretation.
- ConstantExpression compileConstant(VariableElement element);
-
- /// Computes the compile-time constant for the variable initializer,
- /// if possible.
- ConstantExpression compileVariable(VariableElement element);
-
- /// Compiles the constant for [node].
- ///
- /// Reports an error if [node] is not a compile-time constant and
- /// [enforceConst].
- ///
- /// If `!enforceConst`, then if [node] is a "runtime constant" (for example
- /// a reference to a deferred constant) it will be returned - otherwise null
- /// is returned.
- ///
- /// Depending on implementation, the constant compiler might also compute
- /// the constant for the backend interpretation of constants.
- ///
- /// The returned constant is always of the frontend interpretation.
- ConstantExpression compileNode(Node node, TreeElements elements,
- {bool enforceConst: true});
-
- /// Compiles the compile-time constant for the value [metadata], or reports an
- /// error if the value is not a compile-time constant.
- ///
- /// Depending on implementation, the constant compiler might also compute
- /// the compile-time constant for the backend interpretation of constants.
- ///
- /// The returned constant is always of the frontend interpretation.
- ConstantExpression compileMetadata(
- MetadataAnnotation metadata, Node node, TreeElements elements);
-
- /// Evaluates [constant] and caches the result.
- // TODO(johnniwinther): Remove when all constants are evaluated.
- void evaluate(ConstantExpression constant);
}
/// A [BackendConstantEnvironment] provides access to constants needed for
/// backend implementation.
abstract class BackendConstantEnvironment extends ConstantEnvironment {
- /// Returns the compile-time constant value associated with [node].
- ///
- /// Depending on implementation, the constant might be stored in [elements].
- ConstantValue getConstantValueForNode(Node node, TreeElements elements);
-
- /// Returns the compile-time constant associated with [node].
- ///
- /// Depending on implementation, the constant might be stored in [elements].
- ConstantExpression getConstantForNode(Node node, TreeElements elements);
-
- /// Returns the compile-time constant value of [metadata].
- ConstantValue getConstantValueForMetadata(MetadataAnnotation metadata);
-
/// Register that [element] needs lazy initialization.
- void registerLazyStatic(FieldElement element);
+ void registerLazyStatic(FieldEntity element);
}
/// Interface for the task that compiles the constant environments for the
/// frontend and backend interpretation of compile-time constants.
abstract class ConstantCompilerTask extends CompilerTask
- implements ConstantCompiler {
+ implements ConstantEnvironment {
ConstantCompilerTask(Measurer measurer) : super(measurer);
-
- /// Copy all cached constant values from [task].
- ///
- /// This is a hack to support reuse cached compilers in memory_compiler.
- // TODO(johnniwinther): Remove this when values are computed from the
- // expressions.
- void copyConstantValues(ConstantCompilerTask task);
-}
-
-/**
- * The [ConstantCompilerBase] is provides base implementation for compilation of
- * compile-time constants for both the Dart and JavaScript interpretation of
- * constants. It keeps track of compile-time constants for initializations of
- * global and static fields, and default values of optional parameters.
- */
-abstract class ConstantCompilerBase implements ConstantCompiler {
- final Compiler compiler;
- final ConstantSystem constantSystem;
-
- /**
- * Contains the initial values of fields and default values of parameters.
- *
- * Must contain all static and global initializations of const fields.
- *
- * May contain eagerly compiled initial values for statics and instance
- * fields (if those are compile-time constants).
- *
- * May contain default parameter values of optional arguments.
- *
- * Invariant: The keys in this map are declarations.
- */
- // TODO(johnniwinther): Make this purely internal when no longer used by
- // poi/forget_element_test.
- final Map<VariableElement, ConstantExpression> initialVariableValues =
- new Map<VariableElement, ConstantExpression>();
-
- /** The set of variable elements that are in the process of being computed. */
- final Set<VariableElement> pendingVariables = new Set<VariableElement>();
-
- final Map<ConstantExpression, ConstantValue> constantValueMap =
- <ConstantExpression, ConstantValue>{};
-
- ConstantCompilerBase(this.compiler, this.constantSystem);
-
- DiagnosticReporter get reporter => compiler.reporter;
-
- CommonElements get commonElements => compiler.resolution.commonElements;
-
- @override
- @deprecated
- ConstantValue getConstantValueForVariable(VariableElement element) {
- ConstantExpression constant = initialVariableValues[element.declaration];
- // TODO(johnniwinther): Support eager evaluation of the constant.
- return constant != null ? getConstantValue(constant) : null;
- }
-
- ConstantExpression compileConstant(VariableElement element) {
- return internalCompileVariable(element, true, true);
- }
-
- @override
- void evaluate(ConstantExpression constant) {
- constantValueMap.putIfAbsent(constant, () {
- return constant.evaluate(
- new AstEvaluationEnvironment(compiler), constantSystem);
- });
- }
-
- ConstantExpression compileVariable(VariableElement element) {
- return internalCompileVariable(element, false, true);
- }
-
- /// Compile [element] into a constant expression. If [isConst] is true,
- /// then [element] is a constant variable. If [checkType] is true, then
- /// report an error if [element] does not typecheck.
- ConstantExpression internalCompileVariable(
- VariableElement element, bool isConst, bool checkType) {
- if (initialVariableValues.containsKey(element.declaration)) {
- ConstantExpression result = initialVariableValues[element.declaration];
- return result;
- }
- if (element.hasConstant) {
- if (element.constant != null) {
- assert(
- hasConstantValue(element.constant),
- failedAt(
- element,
- "Constant expression has not been evaluated: "
- "${element.constant.toStructuredText()}."));
- }
- return element.constant;
- }
- AstElement currentElement = element.analyzableElement;
- return reporter.withCurrentElement(element, () {
- // TODO(johnniwinther): Avoid this eager analysis.
- compiler.resolution.ensureResolved(currentElement.declaration);
-
- ConstantExpression constant = compileVariableWithDefinitions(
- element, currentElement.resolvedAst.elements,
- isConst: isConst, checkType: checkType);
- return constant;
- });
- }
-
- /**
- * Returns the a compile-time constant if the variable could be compiled
- * eagerly. If the variable needs to be initialized lazily returns `null`.
- * If the variable is `const` but cannot be compiled eagerly reports an
- * error.
- */
- ConstantExpression compileVariableWithDefinitions(
- ConstantVariableMixin element, TreeElements definitions,
- {bool isConst: false, bool checkType: true}) {
- Node node = element.node;
- if (pendingVariables.contains(element)) {
- if (isConst) {
- reporter.reportErrorMessage(
- node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS);
- ConstantExpression expression = new ErroneousConstantExpression();
- constantValueMap[expression] = constantSystem.createNull();
- return expression;
- }
- return null;
- }
- pendingVariables.add(element);
-
- Expression initializer = element.initializer;
- ConstantExpression expression;
- if (initializer == null) {
- // No initial value.
- expression = new NullConstantExpression();
- constantValueMap[expression] = constantSystem.createNull();
- } else {
- expression = compileNodeWithDefinitions(initializer, definitions,
- isConst: isConst);
- if (compiler.options.enableTypeAssertions &&
- checkType &&
- expression != null &&
- element.isField) {
- ResolutionDartType elementType = element.type;
- ConstantValue value = getConstantValue(expression);
- if (elementType.isMalformed && !value.isNull) {
- if (isConst) {
- // TODO(johnniwinther): Check that it is possible to reach this
- // point in a situation where `elementType is! MalformedType`.
- if (elementType is MalformedType) {
- ErroneousElement element = elementType.element;
- reporter.reportErrorMessage(
- node, element.messageKind, element.messageArguments);
- }
- } else {
- // We need to throw an exception at runtime.
- expression = null;
- }
- } else {
- ResolutionDartType constantType = value.getType(commonElements);
- if (!constantSystem.isSubtype(
- compiler.resolution.types, constantType, elementType)) {
- if (isConst) {
- reporter.reportErrorMessage(node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': constantType, 'toType': elementType});
- } else {
- // If the field cannot be lazily initialized, we will throw
- // the exception at runtime.
- expression = null;
- }
- }
- }
- }
- }
- if (expression != null) {
- element.constant = expression;
- initialVariableValues[element.declaration] = expression;
- } else {
- assert(
- !isConst,
- failedAt(
- element, "Variable $element does not compile to a constant."));
- }
- pendingVariables.remove(element);
- return expression;
- }
-
- void cacheConstantValue(ConstantExpression expression, ConstantValue value) {
- constantValueMap[expression] = value;
- }
-
- ConstantExpression compileNodeWithDefinitions(
- Node node, TreeElements definitions,
- {bool isConst: true}) {
- assert(node != null);
- CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
- this, definitions, compiler,
- isConst: isConst);
- AstConstant constant = evaluator.evaluate(node);
- if (constant != null) {
- cacheConstantValue(constant.expression, constant.value);
- return constant.expression;
- }
- return null;
- }
-
- bool hasConstantValue(ConstantExpression expression) {
- return constantValueMap.containsKey(expression);
- }
-
- @override
- ConstantValue getConstantValue(ConstantExpression expression) {
- assert(
- expression != null,
- failedAt(CURRENT_ELEMENT_SPANNABLE,
- "ConstantExpression is null in getConstantValue."));
- ConstantValue value = constantValueMap[expression];
- if (value == null &&
- expression != null &&
- expression.kind == ConstantExpressionKind.ERRONEOUS) {
- // TODO(johnniwinther): When the Dart constant system sees a constant
- // expression as erroneous but the JavaScript constant system finds it ok
- // we have store a constant value for the erroneous constant expression.
- // Ensure the computed constant expressions are always the same; that only
- // the constant values may be different.
- value = new NullConstantValue();
- }
- return value;
- }
-
- ConstantExpression compileNode(Node node, TreeElements elements,
- {bool enforceConst: true}) {
- return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
- }
-
- ConstantExpression compileMetadata(
- MetadataAnnotation metadata, Node node, TreeElements elements) {
- return compileNodeWithDefinitions(node, elements);
- }
-}
-
-/// [ConstantCompiler] that uses the Dart semantics for the compile-time
-/// constant evaluation.
-class DartConstantCompiler extends ConstantCompilerBase {
- DartConstantCompiler(Compiler compiler)
- : super(compiler, const DartConstantSystem());
-
- ConstantExpression getConstantForNode(Node node, TreeElements definitions) {
- return definitions.getConstant(node);
- }
-
- ConstantExpression compileNodeWithDefinitions(
- Node node, TreeElements definitions,
- {bool isConst: true}) {
- ConstantExpression constant = definitions.getConstant(node);
- if (constant != null && hasConstantValue(constant)) {
- return constant;
- }
- constant =
- super.compileNodeWithDefinitions(node, definitions, isConst: isConst);
- if (constant != null) {
- definitions.setConstant(node, constant);
- }
- return constant;
- }
-}
-
-// TODO(johnniwinther): Decouple the creation of [ConstExp] and [Constant] from
-// front-end AST in order to reuse the evaluation for the shared front-end.
-class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
- bool isEvaluatingConstant;
- final ConstantCompilerBase handler;
- final TreeElements elements;
- final Compiler compiler;
-
- Element get context => elements.analyzedElement;
-
- CompileTimeConstantEvaluator(this.handler, this.elements, this.compiler,
- {bool isConst: false})
- : this.isEvaluatingConstant = isConst;
-
- ConstantSystem get constantSystem => handler.constantSystem;
- Resolution get resolution => compiler.resolution;
- CommonElements get commonElements => resolution.commonElements;
- DiagnosticReporter get reporter => compiler.reporter;
-
- AstConstant evaluate(Node node) {
- // TODO(johnniwinther): should there be a visitErrorNode?
- if (node is ErrorNode) return new ErroneousAstConstant(context, node);
- AstConstant result = node.accept(this);
- assert(!isEvaluatingConstant || result != null,
- failedAt(node, "No AstConstant computed for the node."));
- return result;
- }
-
- AstConstant evaluateConstant(Node node) {
- bool oldIsEvaluatingConstant = isEvaluatingConstant;
- isEvaluatingConstant = true;
- AstConstant result = node.accept(this);
- isEvaluatingConstant = oldIsEvaluatingConstant;
- assert(result != null,
- failedAt(node, "No AstConstant computed for the node."));
- return result;
- }
-
- AstConstant visitNode(Node node) {
- return signalNotCompileTimeConstant(node);
- }
-
- AstConstant visitLiteralBool(LiteralBool node) {
- return new AstConstant(
- context,
- node,
- new BoolConstantExpression(node.value),
- constantSystem.createBool(node.value));
- }
-
- AstConstant visitLiteralDouble(LiteralDouble node) {
- return new AstConstant(
- context,
- node,
- new DoubleConstantExpression(node.value),
- constantSystem.createDouble(node.value));
- }
-
- AstConstant visitLiteralInt(LiteralInt node) {
- return new AstConstant(context, node, new IntConstantExpression(node.value),
- constantSystem.createInt(node.value));
- }
-
- AstConstant visitLiteralList(LiteralList node) {
- if (!node.isConst) {
- return signalNotCompileTimeConstant(node);
- }
- List<ConstantExpression> argumentExpressions = <ConstantExpression>[];
- List<ConstantValue> argumentValues = <ConstantValue>[];
- for (Link<Node> link = node.elements.nodes;
- !link.isEmpty;
- link = link.tail) {
- AstConstant argument = evaluateConstant(link.head);
- if (argument == null || argument.isError) {
- return argument;
- }
- argumentExpressions.add(argument.expression);
- argumentValues.add(argument.value);
- }
- ResolutionInterfaceType type = elements.getType(node);
- return new AstConstant(
- context,
- node,
- new ListConstantExpression(type, argumentExpressions),
- constantSystem.createList(type, argumentValues));
- }
-
- AstConstant visitLiteralMap(LiteralMap node) {
- if (!node.isConst) {
- return signalNotCompileTimeConstant(node);
- }
- List<ConstantExpression> keyExpressions = <ConstantExpression>[];
- List<ConstantExpression> valueExpressions = <ConstantExpression>[];
- List<ConstantValue> keyValues = <ConstantValue>[];
- Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{};
- for (Link<Node> link = node.entries.nodes;
- !link.isEmpty;
- link = link.tail) {
- LiteralMapEntry entry = link.head;
- AstConstant key = evaluateConstant(entry.key);
- if (key == null || key.isError) {
- return key;
- }
- AstConstant value = evaluateConstant(entry.value);
- if (value == null || value.isError) {
- return value;
- }
- if (!map.containsKey(key.value)) {
- keyValues.add(key.value);
- } else {
- reporter.reportWarningMessage(
- entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY);
- }
- keyExpressions.add(key.expression);
- valueExpressions.add(value.expression);
- map[key.value] = value.value;
- }
- ResolutionInterfaceType type = elements.getType(node);
- return new AstConstant(
- context,
- node,
- new MapConstantExpression(type, keyExpressions, valueExpressions),
- constantSystem.createMap(
- resolution.commonElements, type, keyValues, map.values.toList()));
- }
-
- AstConstant visitLiteralNull(LiteralNull node) {
- return new AstConstant(context, node, new NullConstantExpression(),
- constantSystem.createNull());
- }
-
- AstConstant visitLiteralString(LiteralString node) {
- String text = node.dartString.slowToString();
- return new AstConstant(context, node, new StringConstantExpression(text),
- constantSystem.createString(text));
- }
-
- AstConstant visitStringJuxtaposition(StringJuxtaposition node) {
- AstConstant left = evaluate(node.first);
- AstConstant right = evaluate(node.second);
- if (left == null || left.isError) {
- return left;
- }
- if (right == null || right.isError) {
- return right;
- }
- StringConstantValue leftValue = left.value;
- StringConstantValue rightValue = right.value;
- return new AstConstant(
- context,
- node,
- new ConcatenateConstantExpression([left.expression, right.expression]),
- constantSystem
- .createString(leftValue.stringValue + rightValue.stringValue));
- }
-
- AstConstant visitStringInterpolation(StringInterpolation node) {
- List<ConstantExpression> subexpressions = <ConstantExpression>[];
- AstConstant initialString = evaluate(node.string);
- if (initialString == null || initialString.isError) {
- return initialString;
- }
- subexpressions.add(initialString.expression);
- StringBuffer sb = new StringBuffer();
- StringConstantValue initialStringValue = initialString.value;
- sb.write(initialStringValue.stringValue);
- for (StringInterpolationPart part in node.parts) {
- AstConstant subexpression = evaluate(part.expression);
- if (subexpression == null || subexpression.isError) {
- return subexpression;
- }
- subexpressions.add(subexpression.expression);
- ConstantValue expression = subexpression.value;
- if (expression.isPrimitive) {
- if (expression is IntConstantValue) {
- sb.write(expression.intValue);
- } else if (expression is DoubleConstantValue) {
- sb.write(expression.doubleValue);
- } else if (expression is StringConstantValue) {
- sb.write(expression.stringValue);
- } else if (expression is BoolConstantValue) {
- sb.write(expression.boolValue);
- } else if (expression is NullConstantValue) {
- sb.write(null);
- }
- } else {
- // TODO(johnniwinther): Specialize message to indicated that the problem
- // is not constness but the types of the const expressions.
- return signalNotCompileTimeConstant(part.expression);
- }
- AstConstant partString = evaluate(part.string);
- if (partString == null) return null;
- subexpressions.add(partString.expression);
- StringConstantValue partStringValue = partString.value;
- sb.write(partStringValue.stringValue);
- }
- return new AstConstant(
- context,
- node,
- new ConcatenateConstantExpression(subexpressions),
- constantSystem.createString(sb.toString()));
- }
-
- AstConstant visitLiteralSymbol(LiteralSymbol node) {
- ResolutionInterfaceType type = commonElements.symbolImplementationType;
- String text = node.slowNameString;
- List<AstConstant> arguments = <AstConstant>[
- new AstConstant(context, node, new StringConstantExpression(text),
- constantSystem.createString(text))
- ];
- ConstructorElement constructor =
- resolution.commonElements.symbolConstructorTarget;
- AstConstant constant = createConstructorInvocation(
- node, type, constructor, CallStructure.ONE_ARG,
- normalizedArguments: arguments);
- return new AstConstant(
- context, node, new SymbolConstantExpression(text), constant.value);
- }
-
- ConstantValue makeTypeConstant(ResolutionDartType elementType) {
- return constantSystem.createType(resolution.commonElements, elementType);
- }
-
- /// Returns true if the prefix of the send resolves to a deferred import
- /// prefix.
- bool isDeferredUse(Send send) {
- if (send == null) return false;
- AstDeferredLoadTask deferredLoadTask = compiler.deferredLoadTask;
- return deferredLoadTask.deferredImportElement(send, elements) != null;
- }
-
- AstConstant visitIdentifier(Identifier node) {
- Element element = elements[node];
- if (Elements.isClass(element) || Elements.isTypedef(element)) {
- TypeDeclarationElement typeDeclarationElement = element;
- ResolutionDartType type = typeDeclarationElement.rawType;
- return new AstConstant(
- element,
- node,
- new TypeConstantExpression(type, typeDeclarationElement.name),
- makeTypeConstant(type));
- }
- return signalNotCompileTimeConstant(node);
- }
-
- // TODO(floitsch): provide better error-messages.
- AstConstant visitSend(Send send) {
- Element element = elements[send];
- if (send.isPropertyAccess) {
- AstConstant result;
- if (Elements.isStaticOrTopLevelFunction(element)) {
- MethodElement function = element;
- function.computeType(resolution);
- result = new AstConstant(
- context,
- send,
- new FunctionConstantExpression(function, function.type),
- new FunctionConstantValue(function, function.type));
- } else if (Elements.isStaticOrTopLevelField(element)) {
- ConstantExpression elementExpression;
- if (element.isConst) {
- elementExpression = handler.compileConstant(element);
- } else if (element.isFinal && !isEvaluatingConstant) {
- elementExpression = handler.compileVariable(element);
- }
- if (elementExpression != null) {
- FieldElement field = element;
- result = new AstConstant(
- context,
- send,
- new FieldConstantExpression(field),
- handler.getConstantValue(elementExpression));
- }
- } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
- assert(elements.isTypeLiteral(send));
- ResolutionDartType elementType = elements.getTypeLiteralType(send);
- result = new AstConstant(
- context,
- send,
- new TypeConstantExpression(elementType, element.name),
- makeTypeConstant(elementType));
- } else if (send.receiver != null) {
- if (send.selector.asIdentifier().source == "length") {
- AstConstant left = evaluate(send.receiver);
- if (left != null && left.value.isString) {
- StringConstantValue stringConstantValue = left.value;
- String string = stringConstantValue.stringValue;
- IntConstantValue length = constantSystem.createInt(string.length);
- result = new AstConstant(context, send,
- new StringLengthConstantExpression(left.expression), length);
- }
- }
- // Fall through to error handling.
- } else if (!Elements.isUnresolved(element) &&
- element.isVariable &&
- element.isConst) {
- LocalVariableElement local = element;
- ConstantExpression variableExpression = handler.compileConstant(local);
- if (variableExpression != null) {
- result = new AstConstant(
- context,
- send,
- new LocalVariableConstantExpression(local),
- handler.getConstantValue(variableExpression));
- }
- }
- if (result == null) {
- return signalNotCompileTimeConstant(send);
- }
- if (isDeferredUse(send)) {
- if (isEvaluatingConstant) {
- reporter.reportErrorMessage(
- send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT);
- }
- AstDeferredLoadTask deferredLoadTask = compiler.deferredLoadTask;
- ImportElement import =
- deferredLoadTask.deferredImportElement(send, elements);
- result = new AstConstant(
- context,
- send,
- new DeferredConstantExpression(result.expression, import),
- new DeferredConstantValue(result.value, import));
- compiler.deferredLoadTask
- .registerConstantDeferredUse(result.value, import);
- }
- return result;
- } else if (send.isCall) {
- if (element == resolution.commonElements.identicalFunction &&
- send.argumentCount() == 2) {
- AstConstant left = evaluate(send.argumentsNode.nodes.head);
- AstConstant right = evaluate(send.argumentsNode.nodes.tail.head);
- if (left == null || right == null) {
- return null;
- }
- ConstantValue result =
- constantSystem.identity.fold(left.value, right.value);
- if (result != null) {
- return new AstConstant(
- context,
- send,
- new IdenticalConstantExpression(
- left.expression, right.expression),
- result);
- }
- }
- return signalNotCompileTimeConstant(send);
- } else if (send.isPrefix) {
- assert(send.isOperator);
- AstConstant receiverConstant = evaluate(send.receiver);
- if (receiverConstant == null || receiverConstant.isError) {
- return receiverConstant;
- }
- Operator node = send.selector;
- UnaryOperator operator = UnaryOperator.parse(node.source);
- UnaryOperation operation = constantSystem.lookupUnary(operator);
- if (operation == null) {
- reporter.internalError(send.selector, "Unexpected operator.");
- }
- ConstantValue folded = operation.fold(receiverConstant.value);
- if (folded == null) {
- return signalNotCompileTimeConstant(send);
- }
- return new AstConstant(
- context,
- send,
- new UnaryConstantExpression(operator, receiverConstant.expression),
- folded);
- } else if (send.isOperator && !send.isPostfix) {
- assert(send.argumentCount() == 1);
- AstConstant left = evaluate(send.receiver);
- AstConstant right = evaluate(send.argumentsNode.nodes.head);
- if (left == null || left.isError) {
- return left;
- }
- if (right == null || right.isError) {
- return right;
- }
- ConstantValue leftValue = left.value;
- ConstantValue rightValue = right.value;
- Operator node = send.selector.asOperator();
- BinaryOperator operator = BinaryOperator.parse(node.source);
- ConstantValue folded = null;
- // operator is null when `node=="is"`
- if (operator != null) {
- switch (operator.kind) {
- case BinaryOperatorKind.EQ:
- if (leftValue.isPrimitive && rightValue.isPrimitive) {
- folded = constantSystem.equal.fold(leftValue, rightValue);
- }
- break;
- case BinaryOperatorKind.NOT_EQ:
- if (leftValue.isPrimitive && rightValue.isPrimitive) {
- BoolConstantValue areEquals =
- constantSystem.equal.fold(leftValue, rightValue);
- if (areEquals == null) {
- folded = null;
- } else {
- folded = areEquals.negate();
- }
- }
- break;
- default:
- BinaryOperation operation = constantSystem.lookupBinary(operator);
- if (operation != null) {
- folded = operation.fold(leftValue, rightValue);
- }
- }
- }
- if (folded == null) {
- return signalNotCompileTimeConstant(send);
- }
- return new AstConstant(
- context,
- send,
- new BinaryConstantExpression(
- left.expression, operator, right.expression),
- folded);
- }
- return signalNotCompileTimeConstant(send);
- }
-
- AstConstant visitConditional(Conditional node) {
- AstConstant condition = evaluate(node.condition);
- if (condition == null || condition.isError) {
- return condition;
- } else if (!condition.value.isBool) {
- ResolutionDartType conditionType =
- condition.value.getType(commonElements);
- if (isEvaluatingConstant) {
- reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE,
- {'fromType': conditionType, 'toType': commonElements.boolType});
- return new ErroneousAstConstant(context, node);
- }
- return null;
- }
- AstConstant thenExpression = evaluate(node.thenExpression);
- AstConstant elseExpression = evaluate(node.elseExpression);
- if (thenExpression == null || thenExpression.isError) {
- return thenExpression;
- }
- if (elseExpression == null || elseExpression.isError) {
- return elseExpression;
- }
- BoolConstantValue boolCondition = condition.value;
- return new AstConstant(
- context,
- node,
- new ConditionalConstantExpression(condition.expression,
- thenExpression.expression, elseExpression.expression),
- boolCondition.boolValue ? thenExpression.value : elseExpression.value);
- }
-
- AstConstant visitSendSet(SendSet node) {
- return signalNotCompileTimeConstant(node);
- }
-
- /**
- * Returns the normalized list of constant arguments that are passed to the
- * constructor including both the concrete arguments and default values for
- * omitted optional arguments.
- *
- * Invariant: [target] must be an implementation element.
- */
- List<AstConstant> evaluateArgumentsToConstructor(
- Node node,
- CallStructure callStructure,
- Link<Node> arguments,
- ConstructorElement target,
- {AstConstant compileArgument(Node node)}) {
- assert(target.isImplementation, failedAt(node));
-
- AstConstant compileDefaultValue(VariableElement element) {
- ConstantExpression constant = handler.compileConstant(element);
- return new AstConstant.fromDefaultValue(
- element, constant, handler.getConstantValue(constant));
- }
-
- target.computeType(resolution);
-
- if (!callStructure.signatureApplies(target.parameterStructure)) {
- String name = Elements.constructorNameForDiagnostics(
- target.enclosingClass.name, target.name);
- reporter.reportErrorMessage(node,
- MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, {'constructorName': name});
-
- return new List<AstConstant>.filled(
- target.functionSignature.parameterCount,
- new ErroneousAstConstant(context, node));
- }
- return Elements.makeArgumentsList<AstConstant>(
- callStructure, arguments, target, compileArgument, compileDefaultValue);
- }
-
- AstConstant visitNewExpression(NewExpression node) {
- if (!node.isConst) {
- return signalNotCompileTimeConstant(node);
- }
-
- Send send = node.send;
- ConstructorElement constructor = elements[send];
- if (Elements.isUnresolved(constructor)) {
- return signalNotCompileTimeConstant(node);
- }
-
- // Deferred types can not be used in const instance creation expressions.
- // Check if the constructor comes from a deferred library.
- if (isDeferredUse(node.send.selector.asSend())) {
- return signalNotCompileTimeConstant(node,
- message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION);
- }
-
- ResolutionInterfaceType type = elements.getType(node);
- CallStructure callStructure = elements.getSelector(send).callStructure;
-
- return createConstructorInvocation(node, type, constructor, callStructure,
- arguments: node.send.arguments);
- }
-
- AstConstant createConstructorInvocation(
- Node node,
- ResolutionInterfaceType type,
- ConstructorElement constructor,
- CallStructure callStructure,
- {Link<Node> arguments,
- List<AstConstant> normalizedArguments}) {
- // TODO(ahe): This is nasty: we must eagerly analyze the
- // constructor to ensure the redirectionTarget has been computed
- // correctly. Find a way to avoid this.
- resolution.ensureResolved(constructor.declaration);
-
- // The redirection chain of this element may not have been resolved through
- // a post-process action, so we have to make sure it is done here.
- compiler.resolver.resolveRedirectionChain(constructor, node);
-
- bool isInvalid = false;
- ResolutionInterfaceType constructedType = type;
- ConstructorElement implementation;
- if (constructor.isRedirectingFactory) {
- if (constructor.isEffectiveTargetMalformed) {
- isInvalid = true;
- } else {
- constructedType = constructor.computeEffectiveTargetType(type);
- ConstructorElement target = constructor.effectiveTarget;
- // The constructor must be an implementation to ensure that field
- // initializers are handled correctly.
- implementation = target.implementation;
- }
- } else {
- // The constructor must be an implementation to ensure that field
- // initializers are handled correctly.
- implementation = constructor.implementation;
- isInvalid = implementation.isMalformed;
- if (implementation.isGenerativeConstructor &&
- constructor.enclosingClass.isAbstract) {
- isInvalid = true;
- }
- }
- if (isInvalid) {
- return signalNotCompileTimeConstant(node);
- }
-
- List<AstConstant> concreteArguments;
- if (arguments != null) {
- Map<Node, AstConstant> concreteArgumentMap = <Node, AstConstant>{};
- for (Link<Node> link = arguments; !link.isEmpty; link = link.tail) {
- Node argument = link.head;
- NamedArgument namedArgument = argument.asNamedArgument();
- if (namedArgument != null) {
- argument = namedArgument.expression;
- }
- concreteArgumentMap[argument] = evaluateConstant(argument);
- }
-
- normalizedArguments = evaluateArgumentsToConstructor(
- node, callStructure, arguments, implementation,
- compileArgument: (node) => concreteArgumentMap[node]);
- concreteArguments = concreteArgumentMap.values.toList();
- } else {
- assert(normalizedArguments != null);
- concreteArguments = normalizedArguments;
- }
- if (constructor.isFromEnvironmentConstructor) {
- return createFromEnvironmentConstant(node, constructedType, constructor,
- callStructure, normalizedArguments, concreteArguments);
- } else {
- return makeConstructedConstant(
- compiler,
- handler,
- context,
- node,
- type,
- constructor,
- constructedType,
- implementation,
- callStructure,
- concreteArguments,
- normalizedArguments);
- }
- }
-
- AstConstant createFromEnvironmentConstant(
- Node node,
- ResolutionInterfaceType type,
- ConstructorElement constructor,
- CallStructure callStructure,
- List<AstConstant> normalizedArguments,
- List<AstConstant> concreteArguments) {
- dynamic firstArgument = normalizedArguments[0].value;
- ConstantValue defaultValue = normalizedArguments[1].value;
-
- if (firstArgument.isNull) {
- return reportNotCompileTimeConstant(
- normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED);
- }
-
- if (!firstArgument.isString) {
- ResolutionDartType type = defaultValue.getType(commonElements);
- return reportNotCompileTimeConstant(
- normalizedArguments[0].node,
- MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': commonElements.stringType});
- }
-
- if (constructor.isIntFromEnvironmentConstructor &&
- !(defaultValue.isNull || defaultValue.isInt)) {
- ResolutionDartType type = defaultValue.getType(commonElements);
- return reportNotCompileTimeConstant(
- normalizedArguments[1].node,
- MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': commonElements.intType});
- }
-
- if (constructor.isBoolFromEnvironmentConstructor &&
- !(defaultValue.isNull || defaultValue.isBool)) {
- ResolutionDartType type = defaultValue.getType(commonElements);
- return reportNotCompileTimeConstant(
- normalizedArguments[1].node,
- MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': commonElements.boolType});
- }
-
- if (constructor.isStringFromEnvironmentConstructor &&
- !(defaultValue.isNull || defaultValue.isString)) {
- ResolutionDartType type = defaultValue.getType(commonElements);
- return reportNotCompileTimeConstant(
- normalizedArguments[1].node,
- MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': commonElements.stringType});
- }
-
- String name = firstArgument.stringValue;
- String value = compiler.fromEnvironment(name);
-
- AstConstant createEvaluatedConstant(ConstantValue value) {
- ConstantExpression expression;
- ConstantExpression name = concreteArguments[0].expression;
- ConstantExpression defaultValue;
- if (concreteArguments.length > 1) {
- defaultValue = concreteArguments[1].expression;
- }
- if (constructor.isIntFromEnvironmentConstructor) {
- expression =
- new IntFromEnvironmentConstantExpression(name, defaultValue);
- } else if (constructor.isBoolFromEnvironmentConstructor) {
- expression =
- new BoolFromEnvironmentConstantExpression(name, defaultValue);
- } else if (constructor.isStringFromEnvironmentConstructor) {
- expression =
- new StringFromEnvironmentConstantExpression(name, defaultValue);
- }
- assert(expression != null);
- return new AstConstant(context, node, expression, value);
- }
-
- if (value == null) {
- return createEvaluatedConstant(defaultValue);
- } else if (constructor.isIntFromEnvironmentConstructor) {
- int number = int.parse(value, onError: (_) => null);
- return createEvaluatedConstant(
- (number == null) ? defaultValue : constantSystem.createInt(number));
- } else if (constructor.isBoolFromEnvironmentConstructor) {
- if (value == 'true') {
- return createEvaluatedConstant(constantSystem.createBool(true));
- } else if (value == 'false') {
- return createEvaluatedConstant(constantSystem.createBool(false));
- } else {
- return createEvaluatedConstant(defaultValue);
- }
- } else {
- assert(constructor.isStringFromEnvironmentConstructor);
- return createEvaluatedConstant(constantSystem.createString(value));
- }
- }
-
- static AstConstant makeConstructedConstant(
- Compiler compiler,
- ConstantCompilerBase handler,
- Element context,
- Node node,
- ResolutionInterfaceType type,
- ConstructorElement constructor,
- ResolutionInterfaceType constructedType,
- ConstructorElement target,
- CallStructure callStructure,
- List<AstConstant> concreteArguments,
- List<AstConstant> normalizedArguments) {
- if (target.isRedirectingFactory) {
- // This happens in case of cyclic redirection.
- assert(
- compiler.compilationFailed,
- failedAt(
- node,
- "makeConstructedConstant can only be called with the "
- "effective target: $constructor"));
- return new ErroneousAstConstant(context, node);
- }
- assert(
- callStructure.signatureApplies(constructor.parameterStructure) ||
- compiler.compilationFailed,
- failedAt(
- node,
- "Call structure $callStructure does not apply to constructor "
- "$constructor."));
-
- ConstructorEvaluator evaluator =
- new ConstructorEvaluator(constructedType, target, handler, compiler);
- evaluator.evaluateConstructorFieldValues(normalizedArguments);
- Map<FieldElement, AstConstant> fieldConstants =
- evaluator.buildFieldConstants(target.enclosingClass);
- Map<FieldElement, ConstantValue> fieldValues =
- <FieldElement, ConstantValue>{};
- fieldConstants.forEach((FieldElement field, AstConstant astConstant) {
- fieldValues[field] = astConstant.value;
- });
- for (AstConstant fieldValue in fieldConstants.values) {
- if (fieldValue.isError) {
- return fieldValue;
- }
- }
- return new AstConstant(
- context,
- node,
- new ConstructedConstantExpression(type, constructor, callStructure,
- concreteArguments.map((e) => e.expression).toList()),
- new ConstructedConstantValue(constructedType, fieldValues));
- }
-
- AstConstant visitParenthesizedExpression(ParenthesizedExpression node) {
- return node.expression.accept(this);
- }
-
- AstConstant reportNotCompileTimeConstant(Node node, MessageKind message,
- [Map arguments = const {}]) {
- reporter.reportErrorMessage(node, message, arguments);
- return new AstConstant(context, node, new ErroneousConstantExpression(),
- new NullConstantValue());
- }
-
- AstConstant signalNotCompileTimeConstant(Node node,
- {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT,
- Map arguments: const {}}) {
- if (isEvaluatingConstant) {
- return reportNotCompileTimeConstant(node, message, arguments);
- }
- // Else we don't need to do anything. The final handler is only
- // optimistically trying to compile constants. So it is normal that we
- // sometimes see non-compile time constants.
- // Simply return [:null:] which is used to propagate a failing
- // compile-time compilation.
- return null;
- }
-}
-
-class ConstructorEvaluator extends CompileTimeConstantEvaluator {
- final ResolutionInterfaceType constructedType;
- final ConstructorElement constructor;
- final Map<Element, AstConstant> definitions;
- final Map<Element, AstConstant> fieldValues;
- final ResolvedAst resolvedAst;
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [constructor] must be an implementation element.
- */
- ConstructorEvaluator(
- ResolutionInterfaceType this.constructedType,
- ConstructorElement constructor,
- ConstantCompiler handler,
- Compiler compiler)
- : this.constructor = constructor,
- this.definitions = new Map<Element, AstConstant>(),
- this.fieldValues = new Map<Element, AstConstant>(),
- this.resolvedAst =
- compiler.resolution.computeResolvedAst(constructor.declaration),
- super(handler, null, compiler, isConst: true) {
- assert(constructor.isImplementation, failedAt(constructor));
- }
-
- @override
- Element get context => resolvedAst.element;
-
- @override
- TreeElements get elements => resolvedAst.elements;
-
- AstConstant visitSend(Send send) {
- Element element = elements[send];
- if (Elements.isLocal(element)) {
- AstConstant constant = definitions[element];
- if (constant == null) {
- reporter.internalError(send, "Local variable without value.");
- }
- return constant;
- }
- return super.visitSend(send);
- }
-
- void potentiallyCheckType(TypedElement element, AstConstant constant) {
- if (compiler.options.enableTypeAssertions) {
- ResolutionDartType elementType =
- element.type.substByContext(constructedType);
- ResolutionDartType constantType = constant.value.getType(commonElements);
- if (!constantSystem.isSubtype(
- compiler.resolution.types, constantType, elementType)) {
- reporter.withCurrentElement(constant.element, () {
- reporter.reportErrorMessage(constant.node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': constantType, 'toType': elementType});
- });
- }
- }
- }
-
- void updateFieldValue(Node node, TypedElement element, AstConstant constant) {
- potentiallyCheckType(element, constant);
- fieldValues[element] = constant;
- }
-
- /**
- * Given the arguments (a list of constants) assigns them to the parameters,
- * updating the definitions map. If the constructor has field-initializer
- * parameters (like [:this.x:]), also updates the [fieldValues] map.
- */
- void assignArgumentsToParameters(List<AstConstant> arguments) {
- if (constructor.isMalformed) return;
- // Assign arguments to parameters.
- FunctionSignature signature = constructor.functionSignature;
- int index = 0;
- signature.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- AstConstant argument = arguments[index++];
- Node node = parameter.node;
- if (parameter.isInitializingFormal) {
- InitializingFormalElement initializingFormal = parameter;
- updateFieldValue(node, initializingFormal.fieldElement, argument);
- } else {
- potentiallyCheckType(parameter, argument);
- }
- definitions[parameter] = argument;
- });
- }
-
- void evaluateSuperOrRedirectSend(List<AstConstant> compiledArguments,
- CallStructure callStructure, ConstructorElement targetConstructor) {
- ResolutionInterfaceType type =
- constructedType.asInstanceOf(targetConstructor.enclosingClass);
- ConstructorEvaluator evaluator =
- new ConstructorEvaluator(type, targetConstructor, handler, compiler);
- evaluator.evaluateConstructorFieldValues(compiledArguments);
- // Copy over the fieldValues from the super/redirect-constructor.
- // No need to go through [updateFieldValue] because the
- // assignments have already been checked in checked mode.
- evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
- }
-
- /**
- * Runs through the initializers of the given [constructor] and updates
- * the [fieldValues] map.
- */
- void evaluateConstructorInitializers() {
- ResolvedAst resolvedAst = constructor.resolvedAst;
- if (resolvedAst.kind != ResolvedAstKind.PARSED) {
- List<AstConstant> compiledArguments = <AstConstant>[];
-
- Function compileArgument = (element) => definitions[element];
- Function compileConstant = handler.compileConstant;
- FunctionElement target = constructor.definingConstructor.implementation;
- Elements.addForwardingElementArgumentsToList(constructor,
- compiledArguments, target, compileArgument, compileConstant);
- CallStructure callStructure = new CallStructure(
- target.functionSignature.parameterCount, target.type.namedParameters);
- evaluateSuperOrRedirectSend(compiledArguments, callStructure, target);
- return;
- }
- FunctionExpression functionNode = resolvedAst.node;
- NodeList initializerList = functionNode.initializers;
-
- bool foundSuperOrRedirect = false;
-
- if (initializerList != null) {
- for (Link<Node> link = initializerList.nodes;
- !link.isEmpty;
- link = link.tail) {
- assert(link.head is Send);
- if (link.head is! SendSet) {
- // A super initializer or constructor redirection.
- Send call = link.head;
- FunctionElement target = elements[call];
- if (!target.isMalformed) {
- CallStructure callStructure =
- elements.getSelector(call).callStructure;
- List<AstConstant> compiledArguments =
- evaluateArgumentsToConstructor(
- call, callStructure, call.arguments, target,
- compileArgument: evaluateConstant);
- evaluateSuperOrRedirectSend(
- compiledArguments, callStructure, target);
- }
- foundSuperOrRedirect = true;
- } else {
- // A field initializer.
- SendSet init = link.head;
- Link<Node> initArguments = init.arguments;
- assert(!initArguments.isEmpty && initArguments.tail.isEmpty);
- AstConstant fieldValue = evaluate(initArguments.head);
- updateFieldValue(init, elements[init], fieldValue);
- }
- }
- }
-
- if (!foundSuperOrRedirect) {
- // No super initializer found. Try to find the default constructor if
- // the class is not Object.
- ClassElement enclosingClass = constructor.enclosingClass;
- ClassElement superClass = enclosingClass.superclass;
- if (!enclosingClass.isObject) {
- assert(superClass != null);
- assert(superClass.isResolved);
-
- FunctionElement targetConstructor =
- superClass.lookupDefaultConstructor();
- // If we do not find a default constructor, an error was reported
- // already and compilation will fail anyway. So just ignore that case.
- if (targetConstructor != null) {
- CallStructure callStructure = CallStructure.NO_ARGS;
- List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
- functionNode,
- callStructure,
- const Link<Node>(),
- targetConstructor);
- evaluateSuperOrRedirectSend(
- compiledArguments, callStructure, targetConstructor);
- }
- }
- }
- }
-
- /**
- * Simulates the execution of the [constructor] with the given
- * [arguments] to obtain the field values that need to be passed to the
- * native JavaScript constructor.
- */
- void evaluateConstructorFieldValues(List<AstConstant> arguments) {
- if (constructor.isMalformed) return;
- reporter.withCurrentElement(constructor, () {
- assignArgumentsToParameters(arguments);
- evaluateConstructorInitializers();
- });
- }
-
- /// Builds a normalized list of the constant values for each field in the
- /// inheritance chain of [classElement].
- Map<FieldElement, AstConstant> buildFieldConstants(
- ClassElement classElement) {
- Map<FieldElement, AstConstant> fieldConstants =
- <FieldElement, AstConstant>{};
- classElement.implementation.forEachInstanceField(
- (ClassElement enclosing, FieldElement field) {
- AstConstant fieldValue = fieldValues[field];
- if (fieldValue == null) {
- // Use the default value.
- ConstantExpression fieldExpression =
- handler.internalCompileVariable(field, true, false);
- fieldValue = new AstConstant.fromDefaultValue(
- field, fieldExpression, handler.getConstantValue(fieldExpression));
- // TODO(het): If the field value doesn't typecheck due to the type
- // variable in the constructor invocation, then report the error on the
- // invocation rather than the field.
- potentiallyCheckType(field, fieldValue);
- }
- fieldConstants[field] = fieldValue;
- }, includeSuperAndInjectedMembers: true);
- return fieldConstants;
- }
-}
-
-/// A constant created from the front-end AST.
-///
-/// [element] and [node] point to the source location of the constant.
-/// [expression] holds the symbolic constant expression and [value] its constant
-/// value.
-///
-/// This class differs from [ConstantExpression] in that it is coupled to the
-/// front-end AST whereas [ConstantExpression] is only coupled to the element
-/// model.
-class AstConstant {
- final Element element;
- final Node node;
- final ConstantExpression expression;
- final ConstantValue value;
-
- AstConstant(this.element, this.node, this.expression, this.value);
-
- factory AstConstant.fromDefaultValue(VariableElement element,
- ConstantExpression constant, ConstantValue value) {
- return new AstConstant(
- element,
- element.initializer != null ? element.initializer : element.node,
- constant,
- value);
- }
-
- bool get isError => expression.kind == ConstantExpressionKind.ERRONEOUS;
-
- String toString() => expression.toString();
-}
-
-/// A synthetic constant used to recover from errors.
-class ErroneousAstConstant extends AstConstant {
- ErroneousAstConstant(Element element, Node node)
- : super(
- element,
- node,
- // TODO(johnniwinther): Return a [NonConstantValue] instead.
- new ErroneousConstantExpression(),
- new NullConstantValue());
-}
-
-class AstEvaluationEnvironment extends EvaluationEnvironmentBase {
- final Compiler _compiler;
-
- AstEvaluationEnvironment(this._compiler, {bool constantRequired: true})
- : super(CURRENT_ELEMENT_SPANNABLE, constantRequired: constantRequired);
-
- @override
- CommonElements get commonElements => _compiler.resolution.commonElements;
-
- @override
- DartTypes get types => _compiler.resolution.types;
-
- @override
- String readFromEnvironment(String name) {
- return _compiler.fromEnvironment(name);
- }
-
- @override
- ResolutionDartType substByContext(
- ResolutionDartType base, ResolutionInterfaceType target) {
- return base.substByContext(target);
- }
-
- @override
- ConstantConstructor getConstructorConstant(ConstructorElement constructor) {
- return constructor.constantConstructor;
- }
-
- @override
- ConstantExpression getFieldConstant(FieldElement field) {
- return field.constant;
- }
-
- @override
- ConstantExpression getLocalConstant(LocalVariableElement local) {
- return local.constant;
- }
-
- @override
- DiagnosticReporter get reporter => _compiler.reporter;
-
- @override
- bool get enableAssertions => _compiler.options.enableUserAssertions;
}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index dde70dd..a62b1a9 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -10,59 +10,29 @@
import 'backend_strategy.dart';
import 'common/names.dart' show Selectors;
import 'common/names.dart' show Uris;
-import 'common/resolution.dart'
- show
- ParsingContext,
- Resolution,
- ResolutionWorkItem,
- ResolutionImpact,
- Target;
import 'common/tasks.dart' show CompilerTask, GenericTask, Measurer;
import 'common/work.dart' show WorkItem;
import 'common.dart';
import 'compile_time_constants.dart';
-import 'constants/values.dart';
-import 'common_elements.dart' show CommonElements, ElementEnvironment;
+import 'common_elements.dart' show ElementEnvironment;
import 'deferred_load.dart' show DeferredLoadTask, OutputUnitData;
import 'diagnostics/code_location.dart';
import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
-import 'diagnostics/invariant.dart' show REPORT_EXCESS_RESOLUTION;
import 'diagnostics/messages.dart' show Message, MessageTemplate;
import 'dump_info.dart' show DumpInfoTask;
-import 'elements/elements.dart';
import 'elements/entities.dart';
-import 'elements/resolution_types.dart' show ResolutionDartType, Types;
import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer;
import 'environment.dart';
import 'frontend_strategy.dart';
-import 'id_generator.dart';
import 'io/source_information.dart' show SourceInformation;
-import 'io/source_file.dart' show Binary;
import 'js_backend/backend.dart' show JavaScriptBackend;
import 'kernel/kernel_backend_strategy.dart';
import 'kernel/kernel_strategy.dart';
-import 'library_loader.dart'
- show
- ElementScanner,
- LibraryLoader,
- LibraryLoaderTask,
- LoadedLibraries,
- ScriptLoader;
-import 'mirrors_used.dart' show MirrorUsageAnalyzerTask;
+import 'library_loader.dart' show LibraryLoaderTask, LoadedLibraries;
import 'null_compiler_output.dart' show NullCompilerOutput, NullSink;
import 'options.dart' show CompilerOptions, DiagnosticOptions;
-import 'parser/diet_parser_task.dart' show DietParserTask;
-import 'parser/parser_task.dart' show ParserTask;
-import 'patch_parser.dart' show PatchParserTask;
-import 'resolution/resolution.dart' show ResolverTask;
-import 'resolution/resolution_strategy.dart';
-import 'resolved_uri_translator.dart';
-import 'scanner/scanner_task.dart' show ScannerTask;
-import 'script.dart' show Script;
import 'ssa/nodes.dart' show HInstruction;
-import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
-import 'tree/tree.dart' show Node, TypeAnnotation;
-import 'typechecker.dart' show TypeCheckerTask;
+import 'package:front_end/src/fasta/scanner.dart' show StringToken;
import 'types/types.dart' show GlobalTypeInferenceTask;
import 'universe/selector.dart' show Selector;
import 'universe/world_builder.dart'
@@ -70,7 +40,6 @@
import 'universe/use.dart' show StaticUse, TypeUse;
import 'universe/world_impact.dart'
show ImpactStrategy, WorldImpact, WorldImpactBuilderImpl;
-import 'util/util.dart' show Link;
import 'world.dart' show ClosedWorld, ClosedWorldRefiner;
typedef CompilerDiagnosticReporter MakeReporterFunction(
@@ -81,14 +50,11 @@
api.CompilerInput get provider;
- final IdGenerator idGenerator = new IdGenerator();
FrontendStrategy frontendStrategy;
BackendStrategy backendStrategy;
CompilerDiagnosticReporter _reporter;
- CompilerResolution _resolution;
Map<Entity, WorldImpact> _impactCache;
ImpactCacheDeleter _impactCacheDeleter;
- ParsingContext _parsingContext;
ImpactStrategy impactStrategy = const ImpactStrategy();
@@ -108,17 +74,13 @@
List<Uri> librariesToAnalyzeWhenRun;
- ResolvedUriTranslator get resolvedUriTranslator;
-
Uri mainLibraryUri;
ClosedWorld backendClosedWorldForTesting;
DiagnosticReporter get reporter => _reporter;
- Resolution get resolution => _resolution;
Map<Entity, WorldImpact> get impactCache => _impactCache;
ImpactCacheDeleter get impactCacheDeleter => _impactCacheDeleter;
- ParsingContext get parsingContext => _parsingContext;
// TODO(zarah): Remove this map and incorporate compile-time errors
// in the model.
@@ -135,13 +97,7 @@
Entity get currentElement => _reporter.currentElement;
List<CompilerTask> tasks;
- ScannerTask scanner;
- DietParserTask dietParser;
- ParserTask parser;
- PatchParserTask patchParser;
LibraryLoaderTask libraryLoader;
- ResolverTask resolver;
- TypeCheckerTask checker;
GlobalTypeInferenceTask globalInference;
JavaScriptBackend backend;
CodegenWorldBuilder _codegenWorldBuilder;
@@ -154,7 +110,6 @@
EnqueueTask enqueuer;
DeferredLoadTask deferredLoadTask;
- MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask;
DumpInfoTask dumpInfoTask;
bool get hasCrashed => _reporter.hasCrashed;
@@ -206,36 +161,18 @@
enqueuer = backend.makeEnqueuer();
tasks = [
- dietParser = new DietParserTask(idGenerator, backend, reporter, measurer),
- scanner = createScannerTask(),
- patchParser = new PatchParserTask(this),
- libraryLoader = frontendStrategy.createLibraryLoader(
- resolvedUriTranslator,
- new _ScriptLoader(this),
- provider,
- new _ElementScanner(scanner),
- resolvePatchUri,
- patchParser,
- environment,
- reporter,
- measurer),
- parser = new ParserTask(this),
- resolver = createResolverTask(),
- checker = new TypeCheckerTask(this),
+ libraryLoader =
+ frontendStrategy.createLibraryLoader(provider, reporter, measurer),
+ kernelFrontEndTask,
globalInference = new GlobalTypeInferenceTask(this),
constants = backend.constantCompilerTask,
deferredLoadTask = frontendStrategy.createDeferredLoadTask(this),
- mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
// [enqueuer] is created earlier because it contains the resolution world
// objects needed by other tasks.
enqueuer,
dumpInfoTask = new DumpInfoTask(this),
selfTask,
];
- tasks.add(kernelFrontEndTask);
-
- _parsingContext =
- new ParsingContext(reporter, parser, scanner, patchParser, backend);
tasks.addAll(backend.tasks);
}
@@ -251,26 +188,9 @@
useNewSourceInfo: options.useNewSourceInfo);
}
- /// Creates the scanner task.
- ///
- /// Override this to mock the scanner for testing.
- ScannerTask createScannerTask() =>
- new ScannerTask(dietParser, reporter, measurer);
-
- /// Creates the resolution object.
- ///
- /// Override this to mock resolution for testing.
- Resolution createResolution() => new CompilerResolution(this);
-
- /// Creates the resolver task.
- ///
- /// Override this to mock the resolver for testing.
- ResolverTask createResolverTask() {
- return new ResolverTask(resolution, backend.constantCompilerTask, measurer);
- }
-
ResolutionWorldBuilder get resolutionWorldBuilder =>
enqueuer.resolution.worldBuilder;
+
CodegenWorldBuilder get codegenWorldBuilder {
assert(
_codegenWorldBuilder != null,
@@ -302,63 +222,6 @@
});
});
- /// Compute the set of distinct import chains to the library at [uri] within
- /// [loadedLibraries].
- ///
- /// The chains are strings of the form
- ///
- /// <main-uri> => <intermediate-uri1> => <intermediate-uri2> => <uri>
- ///
- Set<String> computeImportChainsFor(LoadedLibraries loadedLibraries, Uri uri) {
- // TODO(johnniwinther): Move computation of dependencies to the library
- // loader.
- Set<String> importChains = new Set<String>();
- // The maximum number of full imports chains to process.
- final int chainLimit = 10000;
- // The maximum number of imports chains to show.
- final int compactChainLimit = options.verbose ? 20 : 10;
- int chainCount = 0;
- loadedLibraries.forEachImportChain(uri,
- callback: (Link<Uri> importChainReversed) {
- Link<CodeLocation> compactImportChain = const Link<CodeLocation>();
- CodeLocation currentCodeLocation =
- new UriLocation(importChainReversed.head);
- compactImportChain = compactImportChain.prepend(currentCodeLocation);
- for (Link<Uri> link = importChainReversed.tail;
- !link.isEmpty;
- link = link.tail) {
- Uri uri = link.head;
- if (!currentCodeLocation.inSameLocation(uri)) {
- currentCodeLocation =
- options.verbose ? new UriLocation(uri) : new CodeLocation(uri);
- compactImportChain = compactImportChain.prepend(currentCodeLocation);
- }
- }
- String importChain = compactImportChain.map((CodeLocation codeLocation) {
- return codeLocation.relativize(
- (loadedLibraries.rootLibrary as LibraryElement).canonicalUri);
- }).join(' => ');
-
- if (!importChains.contains(importChain)) {
- if (importChains.length > compactChainLimit) {
- importChains.add('...');
- return false;
- } else {
- importChains.add(importChain);
- }
- }
-
- chainCount++;
- if (chainCount > chainLimit) {
- // Assume there are more import chains.
- importChains.add('...');
- return false;
- }
- return true;
- });
- return importChains;
- }
-
/// This method is called when all new libraries loaded through
/// [LibraryLoader.loadLibrary] has been loaded and their imports/exports
/// have been computed.
@@ -384,12 +247,6 @@
return loadedLibraries;
}
- /**
- * Get an [Uri] pointing to a patch for the dart: library with
- * the given path. Returns null if there is no patch.
- */
- Uri resolvePatchUri(String dartLibraryPath);
-
Future runInternal(Uri uri) async {
mainLibraryUri = uri;
// TODO(ahe): This prevents memory leaks when invoking the compiler
@@ -433,30 +290,6 @@
compileLoadedLibraries(mainApp);
}
- /// Analyze all members of the library in [libraryUri].
- ///
- /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the
- /// library has a `part of` tag, assuming it is a part and not a library.
- ///
- /// This operation assumes an unclosed resolution queue and is only supported
- /// when the '--analyze-main' option is used.
- Future<LibraryElement> analyzeUri(Uri libraryUri,
- {bool skipLibraryWithPartOfTag: true}) async {
- phase = PHASE_RESOLVING;
- assert(options.analyzeMain);
- reporter.log('Analyzing $libraryUri (${options.buildId})');
- LoadedLibraries loadedLibraries = await libraryLoader
- .loadLibrary(libraryUri, skipFileWithPartOfTag: true);
- if (loadedLibraries == null) return null;
- processLoadedLibraries(loadedLibraries);
- LibraryElement library = loadedLibraries.rootLibrary;
- ResolutionEnqueuer resolutionEnqueuer = startResolution();
- resolutionEnqueuer.applyImpact(computeImpactForLibrary(library));
- emptyQueue(resolutionEnqueuer, onProgress: showResolutionProgress);
- resolutionEnqueuer.logSummary(reporter.log);
- return library;
- }
-
/// Starts the resolution phase, creating the [ResolutionEnqueuer] if not
/// already created.
///
@@ -609,66 +442,17 @@
impactBuilder.registerStaticUse(new StaticUse.directUse(element));
}
- void registerStaticElementUse(Element element) {
- MemberElement member = element;
- impactBuilder.registerStaticUse(new StaticUse.directUse(member));
- }
+ ElementEnvironment elementEnvironment = frontendStrategy.elementEnvironment;
- void registerElement(Element element) {
- if (element.isClass) {
- ClassElement cls = element;
- cls.ensureResolved(resolution);
- cls.forEachLocalMember(registerStaticElementUse);
- impactBuilder.registerTypeUse(new TypeUse.instantiation(cls.rawType));
- } else if (element.isTypedef) {
- TypedefElement typedef = element;
- typedef.ensureResolved(resolution);
- } else {
- registerStaticElementUse(element);
- }
- }
-
- if (library is LibraryElement) {
- library.implementation.forEachLocalMember(registerElement);
-
- library.imports.forEach((ImportElement import) {
- if (import.isDeferred) {
- // `import.prefix` and `loadLibrary` may be `null` when the deferred
- // import has compile-time errors.
- GetterElement loadLibrary = import.prefix?.loadLibrary;
- if (loadLibrary != null) {
- registerStaticUse(loadLibrary);
- }
- }
- });
- } else {
- ElementEnvironment elementEnvironment =
- frontendStrategy.elementEnvironment;
-
- elementEnvironment.forEachLibraryMember(library, registerStaticUse);
- elementEnvironment.forEachClass(library, (ClassEntity cls) {
- impactBuilder.registerTypeUse(
- new TypeUse.instantiation(elementEnvironment.getRawType(cls)));
- elementEnvironment.forEachLocalClassMember(cls, registerStaticUse);
- });
- }
+ elementEnvironment.forEachLibraryMember(library, registerStaticUse);
+ elementEnvironment.forEachClass(library, (ClassEntity cls) {
+ impactBuilder.registerTypeUse(
+ new TypeUse.instantiation(elementEnvironment.getRawType(cls)));
+ elementEnvironment.forEachLocalClassMember(cls, registerStaticUse);
+ });
return impactBuilder;
}
- // Resolves metadata on library elements. This is necessary in order to
- // resolve metadata classes referenced only from metadata on library tags.
- // TODO(ahe): Figure out how to do this lazily.
- void resolveLibraryMetadata() {
- assert(frontendStrategy.commonElements.mirrorsLibrary != null);
- for (LibraryElement library in libraryLoader.libraries) {
- if (library.metadata != null) {
- for (MetadataAnnotation metadata in library.metadata) {
- metadata.ensureResolved(resolution);
- }
- }
- }
- }
-
/**
* Empty the [enqueuer] queue.
*/
@@ -716,27 +500,6 @@
for (Enqueuer enqueuer in [resolutionEnqueuer, codegenEnqueuer]) {
enqueuer.checkQueueIsEmpty();
}
- if (!REPORT_EXCESS_RESOLUTION) return;
- var resolved = new Set.from(resolutionEnqueuer.processedEntities);
- for (MemberEntity e in codegenEnqueuer.processedEntities) {
- resolved.remove(e);
- }
- for (MemberEntity e in new Set.from(resolved)) {
- if (e.isField) {
- resolved.remove(e);
- }
- if (e.isConstructor && (e as ConstructorEntity).isGenerativeConstructor) {
- resolved.remove(e);
- }
- if (backend.isTargetSpecificLibrary(e.library)) {
- resolved.remove(e);
- }
- }
- reporter.log('Excess resolution work: ${resolved.length}.');
- for (MemberEntity e in resolved) {
- reporter.reportWarningMessage(e, MessageKind.GENERIC,
- {'text': 'Warning: $e resolved but not compiled.'});
- }
}
void showResolutionProgress(Enqueuer enqueuer) {
@@ -783,29 +546,6 @@
registerCompileTimeError(currentElement, message);
}
- /**
- * Reads the script specified by the [readableUri].
- *
- * See [LibraryLoader] for terminology on URIs.
- */
- Future<Script> readScript(Uri readableUri, [Spannable node]) {
- throw failedAt(node, 'Compiler.readScript not implemented.');
- }
-
- Future<Binary> readBinary(Uri readableUri, [Spannable node]) {
- throw failedAt(node, 'Compiler.readBinary not implemented.');
- }
-
- Element lookupElementIn(ScopeContainerElement container, String name) {
- Element element = container.localLookup(name);
- if (element == null) {
- throw 'Could not find $name in $container';
- }
- return element;
- }
-
- bool get isMockCompilation => false;
-
/// Helper for determining whether the current element is declared within
/// 'user code'.
///
@@ -883,8 +623,6 @@
return element.library.canonicalUri;
} else if (element is MemberEntity) {
return element.library.canonicalUri;
- } else if (element is Element) {
- return element.library.canonicalUri;
}
return null;
}
@@ -1123,22 +861,6 @@
}
}
- // TODO(johnniwinther): Move this to the parser listeners.
- @override
- SourceSpan spanFromToken(Token token) {
- if (compiler.frontendStrategy is ResolutionFrontEndStrategy) {
- ResolutionFrontEndStrategy strategy = compiler.frontendStrategy;
- return strategy.spanFromToken(currentElement, token);
- }
- throw 'No error location.';
- }
-
- Element _elementFromHInstruction(HInstruction instruction) {
- return instruction.sourceElement is Element
- ? instruction.sourceElement
- : null;
- }
-
internalError(Spannable spannable, reason) {
String message = tryToString(reason);
reportDiagnosticInternal(
@@ -1168,9 +890,7 @@
if (node is Entity) {
element = node;
} else if (node is HInstruction) {
- element = _elementFromHInstruction(node);
- } else if (node is MetadataAnnotation) {
- element = node.annotatedElement;
+ element = node.sourceElement;
}
return element != null ? element : currentElement;
}
@@ -1238,258 +958,6 @@
}
}
-// TODO(johnniwinther): Move [ResolverTask] here.
-class CompilerResolution implements Resolution, ImpactCacheDeleter {
- final Compiler _compiler;
- final Map<Element, ResolutionImpact> _resolutionImpactCache =
- <Element, ResolutionImpact>{};
- final Map<Entity, WorldImpact> _worldImpactCache = <Entity, WorldImpact>{};
- bool retainCachesForTesting = false;
- Types _types;
-
- CompilerResolution(this._compiler) {
- _types = new Types(this);
- }
-
- @override
- DiagnosticReporter get reporter => _compiler.reporter;
-
- @override
- ParsingContext get parsingContext => _compiler.parsingContext;
-
- @override
- ElementEnvironment get elementEnvironment =>
- _compiler.frontendStrategy.elementEnvironment;
-
- @override
- CommonElements get commonElements =>
- _compiler.frontendStrategy.commonElements;
-
- @override
- Types get types => _types;
-
- @override
- Target get target => _compiler.backend.target;
-
- @override
- ResolverTask get resolver => _compiler.resolver;
-
- @override
- ResolutionEnqueuer get enqueuer => _compiler.enqueuer.resolution;
-
- @override
- CompilerOptions get options => _compiler.options;
-
- @override
- IdGenerator get idGenerator => _compiler.idGenerator;
-
- @override
- ConstantEnvironment get constants => _compiler.constants;
-
- @override
- MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask =>
- _compiler.mirrorUsageAnalyzerTask;
-
- LibraryElement get coreLibrary =>
- _compiler.frontendStrategy.commonElements.coreLibrary;
-
- @override
- bool get wasProxyConstantComputedTestingOnly => _proxyConstant != null;
-
- @override
- void resolveClass(ClassElement cls) {
- _compiler.resolver.resolveClass(cls);
- }
-
- @override
- void resolveTypedef(TypedefElement typdef) {
- _compiler.resolver.resolve(typdef);
- }
-
- @override
- void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation) {
- _compiler.resolver.resolveMetadataAnnotation(metadataAnnotation);
- }
-
- @override
- FunctionSignature resolveSignature(FunctionElement function) {
- return _compiler.resolver.resolveSignature(function);
- }
-
- @override
- ResolutionDartType resolveTypeAnnotation(
- Element element, TypeAnnotation node) {
- return _compiler.resolver.resolveTypeAnnotation(element, node);
- }
-
- @override
- void ensureResolved(Element element) {
- computeWorldImpact(element);
- }
-
- @override
- void ensureClassMembers(ClassElement element) {
- _compiler.resolver.checkClass(element);
- }
-
- @override
- void registerCompileTimeError(Element element, DiagnosticMessage message) =>
- _compiler.registerCompileTimeError(element, message);
-
- @override
- bool hasResolvedAst(ExecutableElement element) {
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration."));
- return hasBeenResolved(element.memberContext.declaration) &&
- element.hasResolvedAst;
- }
-
- @override
- ResolvedAst getResolvedAst(ExecutableElement element) {
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration."));
- assert(hasResolvedAst(element),
- failedAt(element, "ResolvedAst not available for $element."));
- return element.resolvedAst;
- }
-
- @override
- ResolvedAst computeResolvedAst(Element element) {
- ensureResolved(element);
- return getResolvedAst(element);
- }
-
- @override
- bool hasResolutionImpact(Element element) {
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration."));
- return _resolutionImpactCache.containsKey(element);
- }
-
- @override
- ResolutionImpact getResolutionImpact(Element element) {
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration."));
- ResolutionImpact resolutionImpact = _resolutionImpactCache[element];
- assert(resolutionImpact != null,
- failedAt(element, "ResolutionImpact not available for $element."));
- return resolutionImpact;
- }
-
- @override
- WorldImpact getWorldImpact(Element element) {
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration."));
- WorldImpact worldImpact = _worldImpactCache[element];
- assert(worldImpact != null,
- failedAt(element, "WorldImpact not computed for $element."));
- return worldImpact;
- }
-
- @override
- WorldImpact computeWorldImpact(Element element) {
- return _compiler.selfTask.measureSubtask("Resolution.computeWorldImpact",
- () {
- assert(
- element.impliesType ||
- element.isField ||
- element.isFunction ||
- element.isConstructor ||
- element.isGetter ||
- element.isSetter,
- failedAt(element, 'Unexpected element kind: ${element.kind}'));
- // `true ==` prevents analyzer type inference from strengthening element
- // to AnalyzableElement which incompatible with some down-cast to ElementX
- // uses.
- // TODO(29712): Can this be made to work as we expect?
- assert(true == element is AnalyzableElement,
- failedAt(element, 'Element $element is not analyzable.'));
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration."));
- return _worldImpactCache.putIfAbsent(element, () {
- assert(_compiler.parser != null);
- Node tree = _compiler.parser.parse(element);
- assert(!element.isSynthesized || tree == null, failedAt(element));
- ResolutionImpact resolutionImpact = _compiler.resolver.resolve(element);
-
- if (retainCachesForTesting) {
- // [ResolutionImpact] is currently only used by serialization. The
- // enqueuer uses the [WorldImpact] which is always cached.
- // TODO(johnniwinther): Align these use cases better; maybe only
- // cache [ResolutionImpact] and let the enqueuer transform it into
- // a [WorldImpact].
- _resolutionImpactCache[element] = resolutionImpact;
- }
- if (tree != null && !_compiler.options.analyzeSignaturesOnly) {
- // TODO(het): don't do this if suppressWarnings is on, currently we
- // have to do it because the typechecker also sets types
- // Only analyze nodes with a corresponding [TreeElements].
- _compiler.checker.check(element);
- }
- return transformResolutionImpact(element, resolutionImpact);
- });
- });
- }
-
- @override
- WorldImpact transformResolutionImpact(
- Element element, ResolutionImpact resolutionImpact) {
- WorldImpact worldImpact = _compiler.backend.impactTransformer
- .transformResolutionImpact(resolutionImpact);
- _worldImpactCache[element] = worldImpact;
- return worldImpact;
- }
-
- @override
- void uncacheWorldImpact(covariant Element element) {
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration."));
- if (retainCachesForTesting) return;
- assert(_worldImpactCache[element] != null,
- failedAt(element, "WorldImpact not computed for $element."));
- _worldImpactCache[element] = const WorldImpact();
- _resolutionImpactCache.remove(element);
- }
-
- @override
- void emptyCache() {
- if (retainCachesForTesting) return;
- for (Element element in _worldImpactCache.keys) {
- _worldImpactCache[element] = const WorldImpact();
- }
- _resolutionImpactCache.clear();
- }
-
- @override
- bool hasBeenResolved(Element element) {
- return _worldImpactCache.containsKey(element);
- }
-
- @override
- ResolutionWorkItem createWorkItem(MemberElement element) {
- return new ResolutionWorkItem(this, element);
- }
-
- ConstantValue _proxyConstant;
-
- @override
- bool isProxyConstant(ConstantValue value) {
- FieldElement field = coreLibrary.find('proxy');
- if (field == null) return false;
- if (!hasBeenResolved(field)) return false;
- if (_proxyConstant == null) {
- _proxyConstant = constants
- .getConstantValue(resolver.constantCompiler.compileConstant(field));
- }
- return _proxyConstant == value;
- }
-
- @override
- void registerClass(ClassEntity cls) {
- enqueuer.worldBuilder.registerClass(cls);
- }
-}
-
class _MapImpactCacheDeleter implements ImpactCacheDeleter {
final Map<Entity, WorldImpact> _impactCache;
_MapImpactCacheDeleter(this._impactCache);
@@ -1507,24 +975,6 @@
}
}
-class _ScriptLoader implements ScriptLoader {
- Compiler compiler;
- _ScriptLoader(this.compiler);
-
- Future<Script> readScript(Uri uri, [Spannable spannable]) =>
- compiler.readScript(uri, spannable);
-
- Future<Binary> readBinary(Uri uri, [Spannable spannable]) =>
- compiler.readBinary(uri, spannable);
-}
-
-class _ElementScanner implements ElementScanner {
- ScannerTask scanner;
- _ElementScanner(this.scanner);
- void scanLibrary(LibraryElement library) => scanner.scanLibrary(library);
- void scanUnit(CompilationUnitElement unit) => scanner.scan(unit);
-}
-
class _EmptyEnvironment implements Environment {
const _EmptyEnvironment();
diff --git a/pkg/compiler/lib/src/constants/constant_constructors.dart b/pkg/compiler/lib/src/constants/constant_constructors.dart
deleted file mode 100644
index 288c063..0000000
--- a/pkg/compiler/lib/src/constants/constant_constructors.dart
+++ /dev/null
@@ -1,369 +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(johnniwinther): Remove this library when all constant constructors are
-// computed during resolution.
-library dart2js.constants.constant_constructors;
-
-import '../common.dart';
-import '../elements/elements.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show DeclarationResolverMixin;
-import '../resolution/send_structure.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import 'constructors.dart';
-import 'expressions.dart';
-
-ConstantConstructor computeConstantConstructor(ResolvedAst resolvedAst) {
- ConstantConstructorComputer visitor =
- new ConstantConstructorComputer(resolvedAst.elements);
- return resolvedAst.node.accept(visitor);
-}
-
-class ConstantConstructorComputer extends SemanticVisitor
- with
- SemanticDeclarationResolvedMixin,
- DeclarationResolverMixin,
- GetBulkMixin,
- SetBulkMixin,
- ErrorBulkMixin,
- InvokeBulkMixin,
- IndexSetBulkMixin,
- CompoundBulkMixin,
- SetIfNullBulkMixin,
- UnaryBulkMixin,
- BaseBulkMixin,
- BinaryBulkMixin,
- PrefixBulkMixin,
- PostfixBulkMixin,
- NewBulkMixin,
- InitializerBulkMixin,
- FunctionBulkMixin,
- VariableBulkMixin
- implements SemanticDeclarationVisitor, SemanticSendVisitor {
- final Map<FieldElement, ConstantExpression> fieldMap =
- <FieldElement, ConstantExpression>{};
- final Map<dynamic /*int|String*/, ConstantExpression> defaultValues =
- <dynamic /*int|String*/, ConstantExpression>{};
-
- ConstantConstructorComputer(TreeElements elements) : super(elements);
-
- SemanticDeclarationVisitor get declVisitor => this;
-
- SemanticSendVisitor get sendVisitor => this;
-
- ClassElement get currentClass => currentConstructor.enclosingClass;
-
- ConstructorElement get currentConstructor => elements.analyzedElement;
-
- apply(Node node, [_]) => node.accept(this);
-
- visitNode(Node node) {
- internalError(node, 'Unhandled node $node: ${node.toDebugString()}');
- }
-
- @override
- bulkHandleNode(Node node, String template, _) {
- internalError(node, template.replaceFirst('#', '$node'));
- }
-
- internalError(Spannable node, String message) {
- throw new UnsupportedError(message);
- }
-
- ConstantConstructor visitGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- Node body,
- _) {
- applyParameters(parameters, _);
- ConstructedConstantExpression constructorInvocation =
- applyInitializers(node, _);
- constructor.enclosingClass.forEachInstanceField((_, FieldElement field) {
- if (!fieldMap.containsKey(field)) {
- fieldMap[field] = field.constant;
- }
- });
- return new GenerativeConstantConstructor(
- currentClass.thisType,
- defaultValues,
- fieldMap,
- const <AssertConstantExpression>[],
- constructorInvocation);
- }
-
- ConstantConstructor visitRedirectingGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- _) {
- applyParameters(parameters, _);
- ConstructedConstantExpression constructorInvocation =
- applyInitializers(node, _);
- return new RedirectingGenerativeConstantConstructor(
- defaultValues, constructorInvocation);
- }
-
- ConstantConstructor visitRedirectingFactoryConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- ResolutionInterfaceType redirectionType,
- ConstructorElement redirectionTarget,
- _) {
- List<String> argumentNames = [];
- List<ConstantExpression> arguments = [];
- int index = 0;
- for (ParameterElement parameter in constructor.parameters) {
- if (parameter.isNamed) {
- String name = parameter.name;
- argumentNames.add(name);
- arguments.add(new NamedArgumentReference(name));
- } else {
- arguments.add(new PositionalArgumentReference(index));
- }
- index++;
- }
- CallStructure callStructure = new CallStructure(index, argumentNames);
-
- return new RedirectingFactoryConstantConstructor(
- new ConstructedConstantExpression(
- redirectionType, redirectionTarget, callStructure, arguments));
- }
-
- @override
- visitFactoryConstructorDeclaration(FunctionExpression node,
- ConstructorElement constructor, NodeList parameters, Node body, _) {
- // TODO(johnniwinther): Handle constant constructors with errors.
- internalError(node, "Factory constructor cannot be constant: $node.");
- }
-
- applyParameters(NodeList parameters, _) {
- computeParameterStructures(parameters).forEach((s) => s.dispatch(this, _));
- }
-
- visitParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, int index, _) {
- // Do nothing.
- }
-
- visitOptionalParameterDeclaration(
- VariableDefinitions node,
- Node definition,
- ParameterElement parameter,
- ConstantExpression defaultValue,
- int index,
- _) {
- assert(defaultValue != null, failedAt(node));
- defaultValues[index] = defaultValue;
- }
-
- visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, ConstantExpression defaultValue, _) {
- assert(defaultValue != null, failedAt(node));
- String name = parameter.name;
- defaultValues[name] = defaultValue;
- }
-
- visitInitializingFormalDeclaration(VariableDefinitions node, Node definition,
- InitializingFormalElement parameter, int index, _) {
- fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
- }
-
- visitOptionalInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement parameter,
- ConstantExpression defaultValue,
- int index,
- _) {
- assert(defaultValue != null, failedAt(node));
- defaultValues[index] = defaultValue;
- fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
- }
-
- visitNamedInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement parameter,
- ConstantExpression defaultValue,
- _) {
- assert(defaultValue != null, failedAt(node));
- String name = parameter.name;
- defaultValues[name] = defaultValue;
- fieldMap[parameter.fieldElement] = new NamedArgumentReference(name);
- }
-
- /// Apply this visitor to the constructor [initializers].
- ConstructedConstantExpression applyInitializers(
- FunctionExpression constructor, _) {
- ConstructedConstantExpression constructorInvocation;
- InitializersStructure initializers =
- computeInitializersStructure(constructor);
- for (InitializerStructure structure in initializers.initializers) {
- if (structure.isConstructorInvoke) {
- constructorInvocation = structure.dispatch(this, _);
- } else {
- structure.dispatch(this, _);
- }
- }
- return constructorInvocation;
- }
-
- visitFieldInitializer(SendSet node, FieldElement field, Node initializer, _) {
- fieldMap[field] = apply(initializer);
- }
-
- visitParameterGet(Send node, ParameterElement parameter, _) {
- if (parameter.isNamed) {
- return new NamedArgumentReference(parameter.name);
- } else {
- return new PositionalArgumentReference(
- parameter.functionDeclaration.parameters.indexOf(parameter));
- }
- }
-
- ConstructedConstantExpression visitSuperConstructorInvoke(
- Send node,
- ConstructorElement superConstructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- _) {
- List<ConstantExpression> argumentExpression =
- arguments.nodes.map((a) => apply(a)).toList();
- return new ConstructedConstantExpression(
- type, superConstructor, callStructure, argumentExpression);
- }
-
- ConstructedConstantExpression visitImplicitSuperConstructorInvoke(
- FunctionExpression node,
- ConstructorElement superConstructor,
- ResolutionInterfaceType type,
- _) {
- return new ConstructedConstantExpression(type, superConstructor,
- CallStructure.NO_ARGS, const <ConstantExpression>[]);
- }
-
- ConstructedConstantExpression visitThisConstructorInvoke(
- Send node,
- ConstructorElement thisConstructor,
- NodeList arguments,
- CallStructure callStructure,
- _) {
- List<ConstantExpression> argumentExpression =
- arguments.nodes.map((a) => apply(a)).toList();
- return new ConstructedConstantExpression(currentClass.thisType,
- thisConstructor, callStructure, argumentExpression);
- }
-
- @override
- ConstantExpression visitBinary(
- Send node, Node left, BinaryOperator operator, Node right, _) {
- return new BinaryConstantExpression(apply(left), operator, apply(right));
- }
-
- @override
- ConstantExpression visitEquals(Send node, Node left, Node right, _) {
- return new BinaryConstantExpression(
- apply(left), BinaryOperator.EQ, apply(right));
- }
-
- @override
- ConstantExpression visitNotEquals(Send node, Node left, Node right, _) {
- return new BinaryConstantExpression(
- apply(left), BinaryOperator.NOT_EQ, apply(right));
- }
-
- @override
- ConstantExpression visitUnary(
- Send node, UnaryOperator operator, Node expression, _) {
- return new UnaryConstantExpression(operator, apply(expression));
- }
-
- @override
- ConstantExpression visitStaticFieldGet(Send node, FieldElement field, _) {
- return new FieldConstantExpression(field);
- }
-
- @override
- ConstantExpression visitTopLevelFunctionGet(
- Send node, MethodElement method, _) {
- return new FunctionConstantExpression(method, method.type);
- }
-
- @override
- ConstantExpression visitTopLevelFieldGet(Send node, FieldElement field, _) {
- return new FieldConstantExpression(field);
- }
-
- @override
- ConstantExpression visitLiteralInt(LiteralInt node) {
- return new IntConstantExpression(node.value);
- }
-
- @override
- ConstantExpression visitLiteralDouble(LiteralDouble node) {
- return new DoubleConstantExpression(node.value);
- }
-
- @override
- ConstantExpression visitLiteralBool(LiteralBool node) {
- return new BoolConstantExpression(node.value);
- }
-
- @override
- ConstantExpression visitLiteralNull(LiteralNull node) {
- return new NullConstantExpression();
- }
-
- @override
- ConstantExpression visitLiteralString(LiteralString node) {
- return new StringConstantExpression(node.dartString.slowToString());
- }
-
- @override
- ConstantExpression visitConditional(Conditional node) {
- return new ConditionalConstantExpression(apply(node.condition),
- apply(node.thenExpression), apply(node.elseExpression));
- }
-
- @override
- ConstantExpression visitParenthesizedExpression(
- ParenthesizedExpression node) {
- return apply(node.expression);
- }
-
- @override
- ConstantExpression visitTopLevelFunctionInvoke(
- Send node,
- MethodElement function,
- NodeList arguments,
- CallStructure callStructure,
- _) {
- if (function.name != 'identical' || !function.library.isDartCore) {
- throw new UnsupportedError("Unexpected function call: $function");
- }
- return new IdenticalConstantExpression(
- apply(arguments.nodes.head), apply(arguments.nodes.tail.head));
- }
-
- @override
- ConstantExpression visitNamedArgument(NamedArgument node) {
- return apply(node.expression);
- }
-
- @override
- ConstantExpression visitIfNull(Send node, Node left, Node right, _) {
- return new BinaryConstantExpression(
- apply(left), BinaryOperator.IF_NULL, apply(right));
- }
-}
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 1ccd493..2064ae8 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -19,8 +19,6 @@
InstantiationConstantValue,
TypeConstantValue;
import 'elements/types.dart';
-import 'elements/elements.dart'
- show AstElement, ClassElement, Element, MethodElement, LocalFunctionElement;
import 'elements/entities.dart';
import 'kernel/kelements.dart' show KLocalFunction;
import 'universe/use.dart';
@@ -190,11 +188,6 @@
/// Adds the results to [elements] and [constants].
void _collectAllElementsAndConstantsResolvedFrom(Entity element,
Set<Entity> elements, Set<ConstantValue> constants, isMirrorUsage) {
- if (element is Element && element.isMalformed) {
- // Malformed elements are ignored.
- return;
- }
-
/// Collects all direct dependencies of [element].
///
/// The collected dependent elements and constants are are added to
@@ -206,19 +199,13 @@
return;
}
- // TODO(johnniwinther): Remove this when [AbstractFieldElement] has been
- // removed.
- if (element is Element && element is! AstElement) return;
- Entity analyzableElement =
- element is Element ? element.analyzableElement.declaration : element;
-
// TODO(sigurdm): We want to be more specific about this - need a better
// way to query "liveness".
- if (!compiler.resolutionWorldBuilder.isMemberUsed(analyzableElement)) {
+ if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) {
return;
}
- _collectDependenciesFromImpact(analyzableElement, elements);
- collectConstantsInBody(analyzableElement, constants);
+ _collectDependenciesFromImpact(element, elements);
+ collectConstantsInBody(element, constants);
}
if (element is FunctionEntity) {
@@ -238,13 +225,12 @@
collectDependencies(element);
}
- ClassEntity cls = element is ClassElement ? element.declaration : element;
- ClassEntity impl = cls is ClassElement ? cls.implementation : cls;
+ ClassEntity cls = element;
elementEnvironment.forEachLocalClassMember(cls, addLiveInstanceMember);
- elementEnvironment.forEachSupertype(impl, (InterfaceType type) {
+ elementEnvironment.forEachSupertype(cls, (InterfaceType type) {
_collectTypeDependencies(type, elements);
});
- elements.add(impl);
+ elements.add(cls);
} else if (element is MemberEntity &&
(element.isStatic || element.isTopLevel || element.isConstructor)) {
elements.add(element);
@@ -255,10 +241,8 @@
// constructor, not the class itself. We must add all the
// instance members of the constructor's class.
ClassEntity cls = element.enclosingClass;
- ClassEntity implementation =
- cls is ClassElement ? cls.implementation : cls;
_collectAllElementsAndConstantsResolvedFrom(
- implementation, elements, constants, isMirrorUsage);
+ cls, elements, constants, isMirrorUsage);
}
// Other elements, in particular instance members, are ignored as
@@ -474,8 +458,6 @@
} else if (element is KLocalFunction) {
// TODO(sigmund): consider adding `Local.library`
library = element.memberContext.library;
- } else if (element is LocalFunctionElement) {
- library = element.library;
} else {
assert(false, "Unexpected entity: ${element.runtimeType}");
}
@@ -691,12 +673,10 @@
// information.
for (MemberEntity element
in closedWorld.backendUsage.globalFunctionDependencies) {
- element = element is MethodElement ? element.implementation : element;
queue.addElement(element, importSets.mainSet);
}
for (ClassEntity element
in closedWorld.backendUsage.globalClassDependencies) {
- element = element is ClassElement ? element.implementation : element;
queue.addElement(element, importSets.mainSet);
}
@@ -1162,26 +1142,8 @@
// TODO(johnniwinther): Support use of entities by splitting maps by
// entity kind.
if (!isProgramSplit) return mainOutputUnit;
- entity = entity is Element ? entity.implementation : entity;
OutputUnit unit = _entityToUnit[entity];
if (unit != null) return unit;
- if (entity is Element) {
- Element element = entity;
- while (!_entityToUnit.containsKey(element)) {
- // TODO(21051): workaround: it looks like we output annotation constants
- // for classes that we don't include in the output. This seems to happen
- // when we have reflection but can see that some classes are not needed.
- // We still add the annotation but don't run through it below (where we
- // assign every element to its output unit).
- if (element.enclosingElement == null) {
- _entityToUnit[element] = mainOutputUnit;
- break;
- }
- element = element.enclosingElement.implementation;
- }
- return _entityToUnit[element];
- }
-
if (entity is MemberEntity && entity.isInstanceMember) {
return outputUnitForEntity(entity.enclosingClass);
}
diff --git a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
index 0e4d08d..e44df31 100644
--- a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
+++ b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
@@ -4,7 +4,6 @@
library dart2js.diagnostic_listener;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
import '../elements/entities.dart';
import '../options.dart' show DiagnosticOptions;
import 'messages.dart';
@@ -26,12 +25,6 @@
/// tokens can be found within the tokens of the current element.
SourceSpan spanFromSpannable(Spannable node);
- /// Creates a [SourceSpan] for [token] in scope of the current element.
- ///
- /// In checked mode we assert that the token can be found within the tokens
- /// of the current element.
- SourceSpan spanFromToken(Token token);
-
void reportErrorMessage(Spannable spannable, MessageKind messageKind,
[Map arguments = const {}]) {
reportError(createMessage(spannable, messageKind, arguments));
diff --git a/pkg/compiler/lib/src/diagnostics/invariant.dart b/pkg/compiler/lib/src/diagnostics/invariant.dart
index bdfc7f2..11b446c 100644
--- a/pkg/compiler/lib/src/diagnostics/invariant.dart
+++ b/pkg/compiler/lib/src/diagnostics/invariant.dart
@@ -6,12 +6,6 @@
import 'spannable.dart';
-/**
- * If true, print a warning for each method that was resolved, but not
- * compiled.
- */
-const bool REPORT_EXCESS_RESOLUTION = false;
-
/// Flag that can be used in assertions to assert that a code path is only
/// executed as part of development.
///
diff --git a/pkg/compiler/lib/src/diagnostics/source_span.dart b/pkg/compiler/lib/src/diagnostics/source_span.dart
index 638a923..3fffc29 100644
--- a/pkg/compiler/lib/src/diagnostics/source_span.dart
+++ b/pkg/compiler/lib/src/diagnostics/source_span.dart
@@ -4,8 +4,6 @@
library dart2js.diagnostics.source_span;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart' show Node;
import 'spannable.dart' show Spannable;
class SourceSpan implements Spannable {
@@ -15,21 +13,6 @@
const SourceSpan(this.uri, this.begin, this.end);
- factory SourceSpan.fromNode(Uri uri, Node node) {
- return new SourceSpan.fromTokens(
- uri, node.getBeginToken(), node.getPrefixEndToken());
- }
-
- factory SourceSpan.fromTokens(Uri uri, Token begin, Token end) {
- final beginOffset = begin.charOffset;
- final endOffset = end.charOffset + end.charCount;
-
- // [begin] and [end] might be the same for the same empty token. This
- // happens for instance when scanning '$$'.
- assert(endOffset >= beginOffset);
- return new SourceSpan(uri, beginOffset, endOffset);
- }
-
int get hashCode {
return 13 * uri.hashCode + 17 * begin.hashCode + 19 * end.hashCode;
}
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 251dacd..75010fd 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -17,15 +17,12 @@
import 'compiler.dart' show Compiler;
import 'constants/values.dart' show ConstantValue, InterceptorConstantValue;
import 'deferred_load.dart' show OutputUnit;
-import 'elements/elements.dart';
import 'elements/entities.dart';
import 'js/js.dart' as jsAst;
import 'js_backend/js_backend.dart' show JavaScriptBackend;
+import 'types/masks.dart';
import 'types/types.dart'
- show
- GlobalTypeInferenceElementResult,
- GlobalTypeInferenceMemberResult,
- TypeMask;
+ show GlobalTypeInferenceElementResult, GlobalTypeInferenceMemberResult;
import 'universe/world_builder.dart'
show CodegenWorldBuilder, ReceiverConstraint;
import 'universe/world_impact.dart'
@@ -179,8 +176,6 @@
ClassInfo visitClass(ClassEntity clazz) {
// Omit class if it is not needed.
- if (!_hasClassBeenResolved(clazz)) return null;
-
ClassInfo classInfo = new ClassInfo(
name: clazz.name,
isAbstract: clazz.isAbstract,
@@ -385,10 +380,6 @@
}
return _infoFromOutputUnit(outputUnit);
}
-
- bool _hasClassBeenResolved(ClassEntity cls) {
- return compiler.backend.mirrorsData.isClassResolved(cls);
- }
}
class Selection {
@@ -451,9 +442,6 @@
}
void reportInlined(FunctionEntity element, MemberEntity inlinedFrom) {
- assert(!(element is MethodElement && !element.isDeclaration));
- assert(!(inlinedFrom is MemberElement && !inlinedFrom.isDeclaration));
-
inlineCount.putIfAbsent(element, () => 0);
inlineCount[element] += 1;
inlineMap.putIfAbsent(inlinedFrom, () => new List<Entity>());
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
deleted file mode 100644
index 6990e6a..0000000
--- a/pkg/compiler/lib/src/elements/common.dart
+++ /dev/null
@@ -1,678 +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.
-
-/// Mixins that implement convenience methods on [Element] subclasses.
-
-library elements.common;
-
-import '../common/names.dart' show Identifiers, Names, Uris;
-import '../common_elements.dart' show CommonElements;
-import '../util/util.dart' show Link;
-import 'entities.dart';
-import 'elements.dart';
-import 'names.dart';
-import 'types.dart';
-import 'resolution_types.dart'
- show ResolutionDartType, ResolutionInterfaceType, ResolutionFunctionType;
-
-abstract class ElementCommon implements Element {
- @override
- bool get isLibrary => kind == ElementKind.LIBRARY;
-
- @override
- bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT;
-
- @override
- bool get isPrefix => kind == ElementKind.PREFIX;
-
- @override
- bool get isClass => kind == ElementKind.CLASS;
-
- @override
- bool get isTypeVariable => kind == ElementKind.TYPE_VARIABLE;
-
- @override
- bool get isTypedef => kind == ElementKind.TYPEDEF;
-
- @override
- bool get isFunction => kind == ElementKind.FUNCTION;
-
- @override
- bool get isAccessor => isGetter || isSetter;
-
- @override
- bool get isGetter => kind == ElementKind.GETTER;
-
- @override
- bool get isSetter => kind == ElementKind.SETTER;
-
- @override
- bool get isConstructor => isGenerativeConstructor || isFactoryConstructor;
-
- @override
- bool get isGenerativeConstructor =>
- kind == ElementKind.GENERATIVE_CONSTRUCTOR;
-
- @override
- bool get isGenerativeConstructorBody =>
- kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
-
- bool get isFactoryConstructor => kind == ElementKind.FACTORY_CONSTRUCTOR;
-
- @override
- bool get isVariable => kind == ElementKind.VARIABLE;
-
- @override
- bool get isField => kind == ElementKind.FIELD;
-
- @override
- bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD;
-
- @override
- bool get isRegularParameter => kind == ElementKind.PARAMETER;
-
- @override
- bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
-
- @override
- bool get isError => kind == ElementKind.ERROR;
-
- @override
- bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
-
- @override
- bool get isMalformed => false;
-
- @override
- bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
-
- @override
- bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
-
- @override
- bool get isAssignable {
- if (isFinal || isConst) return false;
- if (isFunction || isGetter || isConstructor) return false;
- return true;
- }
-
- @override
- Element get declaration => this;
-
- @override
- Element get implementation => this;
-
- @override
- bool get isDeclaration => true;
-
- @override
- bool get isPatched => false;
-
- @override
- bool get isPatch => false;
-
- @override
- bool get isImplementation => true;
-
- @override
- bool get isInjected => !isPatch && implementationLibrary.isPatch;
-
- @override
- Element get patch {
- throw new UnsupportedError('patch is not supported on $this');
- }
-
- @override
- Element get origin {
- throw new UnsupportedError('origin is not supported on $this');
- }
-
- @override
- ClassElement get contextClass {
- ClassElement cls;
- for (Element e = this; e != null; e = e.enclosingElement) {
- if (e.isClass) {
- // Record [e] instead of returning it directly. We need the last class
- // in the chain since the first classes might be closure classes.
- cls = e.declaration;
- }
- }
- return cls;
- }
-
- @override
- Element get outermostEnclosingMemberOrTopLevel {
- // TODO(lrn): Why is this called "Outermost"?
- // TODO(johnniwinther): Clean up this method: This method does not return
- // the outermost for elements in closure classes, but some call-sites rely
- // on that behavior.
- for (Element e = this; e != null; e = e.enclosingElement) {
- if (e.isClassMember || e.isTopLevel) {
- return e;
- }
- }
- return null;
- }
-
- Element get enclosingClassOrCompilationUnit {
- for (Element e = this; e != null; e = e.enclosingElement) {
- if (e.isClass || e.isCompilationUnit) return e;
- }
- return null;
- }
-}
-
-abstract class LibraryElementCommon implements LibraryElement {
- @override
- bool get isDartCore => canonicalUri == Uris.dart_core;
-
- @override
- bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
-
- @override
- bool get isPackageLibrary => canonicalUri.scheme == 'package';
-
- @override
- bool get isInternalLibrary =>
- isPlatformLibrary && canonicalUri.path.startsWith('_');
-
- String get name {
- if (hasLibraryName) {
- return libraryName;
- } else {
- // Use the file name as script name.
- String path = canonicalUri.path;
- return path.substring(path.lastIndexOf('/') + 1);
- }
- }
-}
-
-abstract class CompilationUnitElementCommon implements CompilationUnitElement {}
-
-abstract class ClassElementCommon implements ClassElement {
- @override
- Link<InterfaceType> get allSupertypes => allSupertypesAndSelf.supertypes;
-
- @override
- int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
-
- @override
- ResolutionInterfaceType asInstanceOf(ClassElement cls) {
- if (cls == this) return thisType;
- return allSupertypesAndSelf.asInstanceOf(cls, cls.hierarchyDepth);
- }
-
- @override
- ConstructorElement lookupConstructor(String name) {
- Element result = localLookup(name);
- return result != null && result.isConstructor ? result : null;
- }
-
- /**
- * Find the first member in the class chain with the given [memberName].
- *
- * This method is NOT to be used for resolving
- * unqualified sends because it does not implement the scoping
- * rules, where library scope comes before superclass scope.
- *
- * When called on the implementation element both members declared in the
- * origin and the patch class are returned.
- */
- MemberElement lookupByName(Name memberName, {ClassElement stopAt}) {
- return internalLookupByName(memberName,
- isSuperLookup: false, stopAtSuperclass: stopAt);
- }
-
- MemberElement lookupSuperByName(Name memberName) {
- return internalLookupByName(memberName, isSuperLookup: true);
- }
-
- MemberElement internalLookupByName(Name memberName,
- {bool isSuperLookup, ClassElement stopAtSuperclass}) {
- String name = memberName.text;
- bool isPrivate = memberName.isPrivate;
- LibraryElement library = memberName.library;
- for (ClassElement current = isSuperLookup ? superclass : this;
- current != null && current != stopAtSuperclass;
- current = current.superclass) {
- Element member = current.lookupLocalMember(name);
- if (member == null && current.isPatched) {
- // Doing lookups on selectors is done after resolution, so it
- // is safe to look in the patch class.
- member = current.patch.lookupLocalMember(name);
- }
- if (member == null) continue;
- // Private members from a different library are not visible.
- if (isPrivate && !identical(library, member.library)) continue;
- // Static members are not inherited.
- if (member.isStatic && !identical(this, current)) continue;
- // If we find an abstract field we have to make sure that it has
- // the getter or setter part we're actually looking
- // for. Otherwise, we continue up the superclass chain.
- if (member.isAbstractField) {
- AbstractFieldElement field = member;
- GetterElement getter = field.getter;
- SetterElement setter = field.setter;
- if (memberName.isSetter) {
- // Abstract members can be defined in a super class.
- if (setter != null && !setter.isAbstract) {
- return setter;
- }
- } else {
- if (getter != null && !getter.isAbstract) {
- return getter;
- }
- }
- // Abstract members can be defined in a super class.
- } else if (!member.isAbstract && !member.isMalformed) {
- return member;
- }
- }
- return null;
- }
-
- /**
- * Find the first member in the class chain with the given
- * [memberName]. This method is NOT to be used for resolving
- * unqualified sends because it does not implement the scoping
- * rules, where library scope comes before superclass scope.
- */
- @override
- Element lookupMember(String memberName) {
- Element localMember = lookupLocalMember(memberName);
- return localMember == null ? lookupSuperMember(memberName) : localMember;
- }
-
- @override
- Link<Element> get constructors {
- // TODO(ajohnsen): See if we can avoid this method at some point.
- Link<Element> result = const Link<Element>();
- // TODO(johnniwinther): Should we include injected constructors?
- forEachMember((_, Element member) {
- if (member.isConstructor) result = result.prepend(member);
- });
- return result;
- }
-
- /**
- * Lookup super members for the class. This will ignore constructors.
- */
- @override
- Element lookupSuperMember(String memberName) {
- return lookupSuperMemberInLibrary(memberName, library);
- }
-
- /**
- * Lookup super members for the class that is accessible in [library].
- * This will ignore constructors.
- */
- @override
- Element lookupSuperMemberInLibrary(
- String memberName, LibraryElement library) {
- bool isPrivate = Name.isPrivateName(memberName);
- for (ClassElement s = superclass; s != null; s = s.superclass) {
- // Private members from a different library are not visible.
- if (isPrivate && !identical(library, s.library)) continue;
- Element e = s.lookupLocalMember(memberName);
- if (e == null) continue;
- // Static members are not inherited.
- if (e.isStatic) continue;
- return e;
- }
- return null;
- }
-
- /**
- * Lookup local members in the class. This will ignore constructors.
- */
- @override
- Element lookupLocalMember(String memberName) {
- var result = localLookup(memberName);
- if (result != null && result.isConstructor) return null;
- return result;
- }
-
- /**
- * Runs through all members of this class.
- *
- * The enclosing class is passed to the callback. This is useful when
- * [includeSuperAndInjectedMembers] is [:true:].
- *
- * When called on an implementation element both the members in the origin
- * and patch class are included.
- */
- // TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
- @override
- void forEachMember(void f(ClassElement enclosingClass, Element member),
- {includeBackendMembers: false, includeSuperAndInjectedMembers: false}) {
- bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch;
- ClassElement classElement = declaration;
- do {
- // Iterate through the members in textual order, which requires
- // to reverse the data structure [localMembers] we created.
- // Textual order may be important for certain operations, for
- // example when emitting the initializers of fields.
- classElement.forEachLocalMember((e) => f(classElement, e));
- if (includeBackendMembers) {
- classElement.forEachConstructorBody((e) => f(classElement, e));
- }
- if (includeInjectedMembers) {
- if (classElement.isPatched) {
- classElement.patch.forEachLocalMember((e) {
- if (!e.isPatch) f(classElement, e);
- });
- }
- }
- classElement =
- includeSuperAndInjectedMembers ? classElement.superclass : null;
- } while (classElement != null);
- }
-
- /**
- * Runs through all instance-field members of this class.
- *
- * The enclosing class is passed to the callback. This is useful when
- * [includeSuperAndInjectedMembers] is [:true:].
- *
- * When called on the implementation element both the fields declared in the
- * origin and in the patch are included.
- */
- @override
- void forEachInstanceField(
- void f(ClassElement enclosingClass, FieldElement field),
- {bool includeSuperAndInjectedMembers: false}) {
- // Filters so that [f] is only invoked with instance fields.
- void fieldFilter(ClassElement enclosingClass, Element member) {
- if (member.isInstanceMember && member.kind == ElementKind.FIELD) {
- f(enclosingClass, member);
- }
- }
-
- forEachMember(fieldFilter,
- includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);
- }
-
- /// Similar to [forEachInstanceField] but visits static fields.
- @override
- void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {
- // Filters so that [f] is only invoked with static fields.
- void fieldFilter(ClassElement enclosingClass, Element member) {
- if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {
- f(enclosingClass, member);
- }
- }
-
- forEachMember(fieldFilter);
- }
-
- /**
- * Returns true if the [fieldMember] shadows another field. The given
- * [fieldMember] must be a member of this class, i.e. if there is a field of
- * the same name in the superclass chain.
- *
- * This method also works if the [fieldMember] is private.
- */
- @override
- bool hasFieldShadowedBy(FieldElement fieldMember) {
- assert(fieldMember.isField);
- String fieldName = fieldMember.name;
- bool isPrivate = Name.isPrivateName(fieldName);
- LibraryElement memberLibrary = fieldMember.library;
- ClassElement lookupClass = this.superclass;
- while (lookupClass != null) {
- Element foundMember = lookupClass.lookupLocalMember(fieldName);
- if (foundMember != null) {
- if (foundMember.isField) {
- if (!isPrivate || memberLibrary == foundMember.library) {
- // Private fields can only be shadowed by a field declared in the
- // same library.
- return true;
- }
- }
- }
- lookupClass = lookupClass.superclass;
- }
- return false;
- }
-
- @override
- bool implementsInterface(ClassElement interface) {
- return this != interface &&
- allSupertypesAndSelf.asInstanceOf(
- interface, interface.hierarchyDepth) !=
- null;
- }
-
- @override
- bool implementsFunction(CommonElements commonElements) {
- return asInstanceOf(commonElements.functionClass) != null ||
- callType != null;
- }
-
- @override
- bool isSubclassOf(ClassElement cls) {
- // Use [declaration] for both [this] and [cls], because
- // declaration classes hold the superclass hierarchy.
- cls = cls.declaration;
- for (ClassElement s = declaration; s != null; s = s.superclass) {
- if (identical(s, cls)) return true;
- }
- return false;
- }
-
- ResolutionFunctionType get callType {
- MemberSignature member = lookupInterfaceMember(Names.call);
- return member != null && member.isMethod ? member.type : null;
- }
-
- @override
- bool get isNamedMixinApplication {
- return isMixinApplication && !isUnnamedMixinApplication;
- }
-
- // backendMembers are members that have been added by the backend to simplify
- // compilation. They don't have any user-side counter-part.
- List<ConstructorBodyElement> constructorBodies = <ConstructorBodyElement>[];
-
- bool get hasConstructorBodies => !constructorBodies.isEmpty;
-
- void addConstructorBody(ConstructorBodyElement member) {
- // TODO(ngeoffray): Deprecate this method.
- assert(member.isGenerativeConstructorBody);
- constructorBodies.add(member);
- }
-
- /// Lookup a synthetic element created by the backend.
- ConstructorBodyElement lookupConstructorBody(String memberName) {
- for (ConstructorBodyElement element in constructorBodies) {
- if (element.name == memberName) {
- return element;
- }
- }
- return null;
- }
-
- void forEachConstructorBody(void f(ConstructorBodyElement member)) {
- constructorBodies.forEach(f);
- }
-}
-
-abstract class FunctionSignatureCommon implements FunctionSignature {
- ParameterStructure _parameterStructure;
-
- ResolutionDartType get returnType => type.returnType;
-
- void forEachRequiredParameter(void function(FormalElement parameter)) {
- requiredParameters.forEach(function);
- }
-
- void forEachOptionalParameter(void function(FormalElement parameter)) {
- optionalParameters.forEach(function);
- }
-
- void forEachParameter(void function(FormalElement parameter)) {
- forEachRequiredParameter(function);
- forEachOptionalParameter(function);
- }
-
- void orderedForEachParameter(void function(FormalElement parameter)) {
- forEachRequiredParameter(function);
- orderedOptionalParameters.forEach(function);
- }
-
- int get parameterCount => requiredParameterCount + optionalParameterCount;
-
- /**
- * Check whether a function with this signature can be used instead of a
- * function with signature [signature] without causing a `noSuchMethod`
- * exception/call.
- */
- bool isCompatibleWith(FunctionSignature signature) {
- if (optionalParametersAreNamed) {
- if (!signature.optionalParametersAreNamed) {
- return requiredParameterCount == signature.parameterCount;
- }
- // If both signatures have named parameters, then they must have
- // the same number of required parameters, and the names in
- // [signature] must all be in [:this:].
- if (requiredParameterCount != signature.requiredParameterCount) {
- return false;
- }
- Set<String> names =
- optionalParameters.map((Element element) => element.name).toSet();
- for (Element namedParameter in signature.optionalParameters) {
- if (!names.contains(namedParameter.name)) {
- return false;
- }
- }
- } else {
- if (signature.optionalParametersAreNamed) return false;
- // There must be at least as many arguments as in the other signature, but
- // this signature must not have more required parameters. Having more
- // optional parameters is not a problem, they simply are never provided
- // by call sites of a call to a method with the other signature.
- int otherTotalCount = signature.parameterCount;
- return requiredParameterCount <= otherTotalCount &&
- parameterCount >= otherTotalCount;
- }
- return true;
- }
-
- ParameterStructure get parameterStructure {
- if (_parameterStructure == null) {
- int requiredParameters = requiredParameterCount;
- int positionalParameters;
- List<String> namedParameters;
- if (optionalParametersAreNamed) {
- namedParameters = type.namedParameters;
- positionalParameters = requiredParameters;
- } else {
- namedParameters = const <String>[];
- positionalParameters = requiredParameters + optionalParameterCount;
- }
- _parameterStructure = new ParameterStructure(
- requiredParameters, positionalParameters, namedParameters, 0);
- }
- return _parameterStructure;
- }
-}
-
-abstract class MixinApplicationElementCommon
- implements MixinApplicationElement {
- Link<ConstructorElement> get constructors {
- throw new UnsupportedError('Unimplemented $this.constructors');
- }
-
- FunctionElement _lookupLocalConstructor(String name) {
- for (Link<Element> link = constructors; !link.isEmpty; link = link.tail) {
- if (link.head.name == name) return link.head;
- }
- return null;
- }
-
- @override
- Element localLookup(String name) {
- Element constructor = _lookupLocalConstructor(name);
- if (constructor != null) return constructor;
- if (mixin == null) return null;
- Element mixedInElement = mixin.localLookup(name);
- if (mixedInElement == null) return null;
- return mixedInElement.isInstanceMember ? mixedInElement : null;
- }
-
- @override
- void forEachLocalMember(void f(Element member)) {
- constructors.forEach(f);
- if (mixin != null)
- mixin.forEachLocalMember((Element mixedInElement) {
- if (mixedInElement.isInstanceMember) f(mixedInElement);
- });
- }
-}
-
-abstract class AbstractFieldElementCommon implements AbstractFieldElement {
- @override
- bool get isInstanceMember {
- return isClassMember && !isStatic;
- }
-
- @override
- bool get isAbstract {
- return getter != null && getter.isAbstract ||
- setter != null && setter.isAbstract;
- }
-}
-
-enum _FromEnvironmentState {
- NOT,
- BOOL,
- INT,
- STRING,
-}
-
-abstract class ConstructorElementCommon implements ConstructorElement {
- LibraryElement get library;
-
- _FromEnvironmentState _fromEnvironmentState;
-
- _FromEnvironmentState get fromEnvironmentState {
- if (_fromEnvironmentState == null) {
- _fromEnvironmentState = _FromEnvironmentState.NOT;
- if (name == Identifiers.fromEnvironment && library.isDartCore) {
- switch (enclosingClass.name) {
- case 'bool':
- _fromEnvironmentState = _FromEnvironmentState.BOOL;
- break;
- case 'int':
- _fromEnvironmentState = _FromEnvironmentState.INT;
- break;
- case 'String':
- _fromEnvironmentState = _FromEnvironmentState.STRING;
- break;
- }
- }
- }
- return _fromEnvironmentState;
- }
-
- @override
- bool get isFromEnvironmentConstructor {
- return fromEnvironmentState != _FromEnvironmentState.NOT;
- }
-
- @override
- bool get isIntFromEnvironmentConstructor {
- return fromEnvironmentState == _FromEnvironmentState.INT;
- }
-
- @override
- bool get isBoolFromEnvironmentConstructor {
- return fromEnvironmentState == _FromEnvironmentState.BOOL;
- }
-
- @override
- bool get isStringFromEnvironmentConstructor {
- return fromEnvironmentState == _FromEnvironmentState.STRING;
- }
-}
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
deleted file mode 100644
index c282f29..0000000
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ /dev/null
@@ -1,1931 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library elements;
-
-import 'package:front_end/src/fasta/scanner.dart'
- show Token, isUserDefinableOperator, isMinusOperator;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common_elements.dart' show CommonElements;
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../ordered_typeset.dart' show OrderedTypeSet;
-import '../resolution/scope.dart' show Scope;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../script.dart';
-import '../tree/tree.dart' hide AsyncModifier;
-import '../universe/call_structure.dart';
-import '../util/util.dart';
-import '../world.dart' show ClosedWorld;
-import 'entities.dart';
-import 'entity_utils.dart' as utils;
-import 'jumps.dart';
-import 'names.dart';
-import 'resolution_types.dart';
-import 'types.dart';
-import 'visitor.dart' show ElementVisitor;
-
-const int STATE_NOT_STARTED = 0;
-const int STATE_STARTED = 1;
-const int STATE_DONE = 2;
-
-class ElementCategory {
- /**
- * Represents things that we don't expect to find when looking in a
- * scope.
- */
- static const int NONE = 0;
-
- /** Field, parameter, or variable. */
- static const int VARIABLE = 1;
-
- /** Function, method, or foreign function. */
- static const int FUNCTION = 2;
-
- static const int CLASS = 4;
-
- static const int PREFIX = 8;
-
- /** Constructor or factory. */
- static const int FACTORY = 16;
-
- static const int ALIAS = 32;
-
- static const int SUPER = 64;
-
- /** Type variable */
- static const int TYPE_VARIABLE = 128;
-
- static const int IMPLIES_TYPE = CLASS | ALIAS | TYPE_VARIABLE;
-}
-
-class ElementKind {
- final String id;
- final int category;
-
- const ElementKind(String this.id, this.category);
-
- static const ElementKind VARIABLE =
- const ElementKind('variable', ElementCategory.VARIABLE);
- static const ElementKind PARAMETER =
- const ElementKind('parameter', ElementCategory.VARIABLE);
- // Parameters in constructors that directly initialize fields. For example:
- // [:A(this.field):].
- static const ElementKind INITIALIZING_FORMAL =
- const ElementKind('initializing_formal', ElementCategory.VARIABLE);
- static const ElementKind FUNCTION =
- const ElementKind('function', ElementCategory.FUNCTION);
- static const ElementKind CLASS =
- const ElementKind('class', ElementCategory.CLASS);
- static const ElementKind GENERATIVE_CONSTRUCTOR =
- const ElementKind('generative_constructor', ElementCategory.FACTORY);
- static const ElementKind FACTORY_CONSTRUCTOR =
- const ElementKind('factory_constructor', ElementCategory.FACTORY);
- static const ElementKind FIELD =
- const ElementKind('field', ElementCategory.VARIABLE);
- static const ElementKind GENERATIVE_CONSTRUCTOR_BODY =
- const ElementKind('generative_constructor_body', ElementCategory.NONE);
- static const ElementKind COMPILATION_UNIT =
- const ElementKind('compilation_unit', ElementCategory.NONE);
- static const ElementKind GETTER =
- const ElementKind('getter', ElementCategory.NONE);
- static const ElementKind SETTER =
- const ElementKind('setter', ElementCategory.NONE);
- static const ElementKind TYPE_VARIABLE =
- const ElementKind('type_variable', ElementCategory.TYPE_VARIABLE);
- static const ElementKind ABSTRACT_FIELD =
- const ElementKind('abstract_field', ElementCategory.VARIABLE);
- static const ElementKind LIBRARY =
- const ElementKind('library', ElementCategory.NONE);
- static const ElementKind IMPORT =
- const ElementKind('import', ElementCategory.NONE);
- static const ElementKind EXPORT =
- const ElementKind('export', ElementCategory.NONE);
- static const ElementKind PREFIX =
- const ElementKind('prefix', ElementCategory.PREFIX);
- static const ElementKind TYPEDEF =
- const ElementKind('typedef', ElementCategory.ALIAS);
-
- static const ElementKind AMBIGUOUS =
- const ElementKind('ambiguous', ElementCategory.NONE);
- static const ElementKind WARN_ON_USE =
- const ElementKind('warn_on_use', ElementCategory.NONE);
- static const ElementKind ERROR =
- const ElementKind('error', ElementCategory.NONE);
-
- toString() => id;
-}
-
-/**
- * A declared element of a program.
- *
- * The declared elements of a program include classes, methods,
- * fields, variables, parameters, etc.
- *
- * Sometimes it makes sense to construct "synthetic" elements that
- * have not been declared anywhere in a program, for example, there
- * are elements corresponding to "dynamic", "null", and unresolved
- * references.
- *
- * Elements are distinct from types ([ResolutionDartType]). For example, there
- * is one declaration of the class List, but several related types,
- * for example, List, List<int>, List<String>, etc.
- *
- * Elements are distinct from AST nodes ([Node]), and there normally is a
- * one-to-one correspondence between an AST node and an element
- * (except that not all kinds of AST nodes have an associated
- * element).
- *
- * AST nodes represent precisely what is written in source code, for
- * example, when a user writes "class MyClass {}", the corresponding
- * AST node does not have a superclass. On the other hand, the
- * corresponding element (once fully resolved) will record the
- * information about the implicit superclass as defined by the
- * language semantics.
- *
- * Generally, the contents of a method are represented as AST nodes
- * without additional elements, but things like local functions, local
- * variables, and labels have a corresponding element.
- *
- * We generally say that scanning, parsing, resolution, and type
- * checking comprise the "front-end" of the compiler. The "back-end"
- * includes things like SSA graph construction, optimizations, and
- * code generation.
- *
- * The front-end data structures are designed to be reusable by
- * several back-ends. For example, we may want to support emitting
- * minified Dart and JavaScript code in one go. Also, we're planning
- * on adding an incremental compilation server that should be able to
- * reuse elements between compilations. So to keep things simple, it
- * is best if the backends avoid setting state directly in elements.
- * It is better to keep such state in a table on the side.
- */
-abstract class Element implements Entity {
- String get name;
- ElementKind get kind;
- Element get enclosingElement;
- Iterable<MetadataAnnotation> get metadata;
-
- /// `true` if this element is a library.
- bool get isLibrary;
-
- /// `true` if this element is an import declaration.
- bool get isImport => kind == ElementKind.IMPORT;
-
- /// `true` if this element is an export declaration.
- bool get isExport => kind == ElementKind.EXPORT;
-
- /// `true` if this element is a compilation unit.
- bool get isCompilationUnit;
-
- /// `true` if this element is defines the scope of prefix used by one or
- /// more import declarations.
- bool get isPrefix;
-
- /// `true` if this element is a class declaration or a mixin application.
- bool get isClass;
-
- /// `true` if this element is a type variable declaration.
- bool get isTypeVariable;
-
- /// `true` if this element is a typedef declaration.
- bool get isTypedef;
-
- /// `true` if this element is a top level function, static or instance
- /// method, local function or closure defined by a function expression.
- ///
- /// This property is `true` for operator methods but `false` for getter and
- /// setter methods, and generative and factory constructors.
- ///
- /// See also [isConstructor], [isGenerativeConstructor], and
- /// [isFactoryConstructor] for constructor properties, and [isAccessor],
- /// [isGetter] and [isSetter] for getter/setter properties.
- bool get isFunction;
-
- /// `true` if this element is an operator method.
- bool get isOperator;
-
- /// `true` if this element is an accessor, that is either an explicit
- /// getter or an explicit setter.
- bool get isAccessor;
-
- /// `true` if this element is an explicit getter method.
- bool get isGetter;
-
- /// `true` if this element is an explicit setter method.
- bool get isSetter;
-
- /// `true` if this element is a generative or factory constructor.
- bool get isConstructor;
-
- /// `true` if this element is a generative constructor, potentially
- /// redirecting.
- bool get isGenerativeConstructor;
-
- /// `true` if this element is the body of a generative constructor.
- ///
- /// This is a synthetic element kind used only by the JavaScript backend.
- bool get isGenerativeConstructorBody;
-
- /// `true` if this element is a factory constructor,
- /// potentially redirecting.
- bool get isFactoryConstructor;
-
- /// `true` if this element is a local variable.
- bool get isVariable;
-
- /// `true` if this element is a top level variable, static or instance field.
- bool get isField;
-
- /// `true` if this element is the abstract field implicitly defined by an
- /// explicit getter and/or setter.
- bool get isAbstractField;
-
- /// `true` if this element is a formal parameter from a constructor,
- /// a method, a typedef declaration, or from an inlined function typed
- /// parameter.
- ///
- /// This property is `false` if this element is an initializing formal.
- /// See [isInitializingFormal].
- bool get isRegularParameter;
-
- /// `true` if this element is an initializing formal of constructor, that
- /// is a formal of the form `this.foo`.
- bool get isInitializingFormal;
-
- /// `true` if this element is a formal parameter, either regular or
- /// initializing.
- bool get isParameter => isRegularParameter || isInitializingFormal;
-
- /// `true` if this element represents a resolution error.
- bool get isError;
-
- /// `true` if this element represents an ambiguous name.
- ///
- /// Ambiguous names occur when two imports/exports contain different entities
- /// by the same name. If an ambiguous name is resolved an warning or error
- /// is produced.
- bool get isAmbiguous;
-
- /// True if there has been errors during resolution or parsing of this
- /// element.
- bool get isMalformed;
-
- /// `true` if this element represents an entity whose access causes one or
- /// more warnings.
- bool get isWarnOnUse;
-
- bool get isClosure;
-
- /// `true` if the element is a (static or instance) member of a class.
- ///
- /// Members are constructors, methods and fields.
- bool get isClassMember;
-
- /// `true` if the element is a nonstatic member of a class.
- ///
- /// Instance members are methods and fields but not constructors.
- bool get isInstanceMember;
-
- /// Returns true if this [Element] is a top level element.
- /// That is, if it is not defined within the scope of a class.
- ///
- /// This means whether the enclosing element is a compilation unit.
- /// With the exception of [ClosureClassElement] that is considered top level
- /// as all other classes.
- bool get isTopLevel;
- bool get isAssignable;
-
- bool get isDeferredLoaderGetter;
-
- /// True if the element is declared in a patch library but has no
- /// corresponding declaration in the origin library.
- bool get isInjected;
-
- /// `true` if this element is a constructor, top level or local variable,
- /// or static field that is declared `const`.
- bool get isConst;
-
- /// `true` if this element is a top level or local variable, static or
- /// instance field, or parameter that is declared `final`.
- bool get isFinal;
-
- /// `true` if this element is a method, getter, setter or field that
- /// is declared `static`.
- bool get isStatic;
-
- /// `true` if this element is local element, that is, a local variable,
- /// local function or parameter.
- bool get isLocal;
-
- bool get impliesType;
-
- /// The character offset of the declaration of this element within its
- /// compilation unit, if available.
- ///
- /// This is used to sort the elements.
- int get sourceOffset;
-
- // TODO(johnniwinther): Remove this.
- Token get position;
-
- /// The position of the declaration of this element, if available.
- SourceSpan get sourcePosition;
-
- CompilationUnitElement get compilationUnit;
- LibraryElement get library;
- LibraryElement get implementationLibrary;
- ClassElement get enclosingClass;
- Element get enclosingClassOrCompilationUnit;
- Element get outermostEnclosingMemberOrTopLevel;
-
- // TODO(johnniwinther): Replace uses of this with [enclosingClass] when
- // [ClosureClassElement] has been removed.
- /// The enclosing class that defines the type environment for this element.
- ClassElement get contextClass;
-
- FunctionElement asFunctionElement();
-
- /// Is [:true:] if this element has a corresponding patch.
- ///
- /// If [:true:] this element has a non-null [patch] field.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- bool get isPatched;
-
- /// Is [:true:] if this element is a patch.
- ///
- /// If [:true:] this element has a non-null [origin] field.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- bool get isPatch;
-
- /// Is [:true:] if this element defines the implementation for the entity of
- /// this element.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- bool get isImplementation;
-
- /// Is [:true:] if this element introduces the entity of this element.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- bool get isDeclaration;
-
- /// Returns the element which defines the implementation for the entity of
- /// this element.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- Element get implementation;
-
- /// Returns the element which introduces the entity of this element.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- Element get declaration;
-
- /// Returns the patch for this element if this element is patched.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- Element get patch;
-
- /// Returns the origin for this element if this element is a patch.
- ///
- /// See [:patch_parser.dart:] for a description of the terminology.
- Element get origin;
-
- bool get isSynthesized;
- bool get isMixinApplication;
-
- bool get isAbstract;
-
- Scope buildScope();
-
- // TODO(johnniwinther): Move this to [AstElement].
- /// Returns the [Element] that holds the [TreeElements] for this element.
- AnalyzableElement get analyzableElement;
-
- accept(ElementVisitor visitor, arg);
-}
-
-class Elements {
- static bool isUnresolved(Element e) {
- return e == null || e.isMalformed;
- }
-
- static bool isError(Element e) {
- return e != null && e.isError;
- }
-
- static bool isMalformed(Element e) {
- return e != null && e.isMalformed;
- }
-
- /// Unwraps [element] reporting any warnings attached to it, if any.
- static Element unwrap(
- Element element, DiagnosticReporter listener, Spannable spannable) {
- if (element != null && element.isWarnOnUse) {
- WarnOnUseElement wrappedElement = element;
- element = wrappedElement.unwrap(listener, spannable);
- }
- return element;
- }
-
- static bool isClass(Element e) => e != null && e.kind == ElementKind.CLASS;
- static bool isTypedef(Element e) {
- return e != null && e.kind == ElementKind.TYPEDEF;
- }
-
- static bool isLocal(Element element) {
- return !Elements.isUnresolved(element) && element.isLocal;
- }
-
- static bool isInstanceField(Element element) {
- return !Elements.isUnresolved(element) &&
- element.isInstanceMember &&
- (identical(element.kind, ElementKind.FIELD) ||
- identical(element.kind, ElementKind.GETTER) ||
- identical(element.kind, ElementKind.SETTER));
- }
-
- static bool isStaticOrTopLevel(Element element) {
- // TODO(johnniwinther): Clean this up. This currently returns true for a
- // PartialConstructorElement, SynthesizedConstructorElementX, and
- // TypeVariableElementX though neither `element.isStatic` nor
- // `element.isTopLevel` is true.
- if (Elements.isUnresolved(element)) return false;
- if (element.isStatic || element.isTopLevel) return true;
- return !element.isAmbiguous &&
- !element.isInstanceMember &&
- !element.isPrefix &&
- element.enclosingElement != null &&
- (element.enclosingElement.kind == ElementKind.CLASS ||
- element.enclosingElement.kind == ElementKind.COMPILATION_UNIT ||
- element.enclosingElement.kind == ElementKind.LIBRARY ||
- element.enclosingElement.kind == ElementKind.PREFIX);
- }
-
- static bool isInStaticContext(Element element) {
- if (isUnresolved(element)) return true;
- if (element.enclosingElement.isClosure) {
- dynamic closureClass = element.enclosingElement;
- // ignore: UNDEFINED_GETTER
- element = closureClass.methodElement;
- }
- Element outer = element.outermostEnclosingMemberOrTopLevel;
- if (isUnresolved(outer)) return true;
- if (outer.isTopLevel) return true;
- if (outer.isGenerativeConstructor) return false;
- if (outer.isInstanceMember) return false;
- return true;
- }
-
- static bool hasAccessToTypeVariable(
- Element element, TypeVariableElement typeVariable) {
- GenericElement declaration = typeVariable.typeDeclaration;
- if (declaration is FunctionElement || declaration is ParameterElement) {
- return true;
- }
- Element outer = element.outermostEnclosingMemberOrTopLevel;
- return (outer != null && outer.isFactoryConstructor) ||
- !isInStaticContext(element);
- }
-
- static bool isStaticOrTopLevelField(Element element) {
- return isStaticOrTopLevel(element) &&
- (identical(element.kind, ElementKind.FIELD) ||
- identical(element.kind, ElementKind.GETTER) ||
- identical(element.kind, ElementKind.SETTER));
- }
-
- static bool isStaticOrTopLevelFunction(Element element) {
- return isStaticOrTopLevel(element) && element.isFunction;
- }
-
- static bool isInstanceMethod(Element element) {
- return !Elements.isUnresolved(element) &&
- element.isInstanceMember &&
- (identical(element.kind, ElementKind.FUNCTION));
- }
-
- static bool isInstanceSend(Send send, TreeElements elements) {
- Element element = elements[send];
- if (element == null) return !isClosureSend(send, element);
- return isInstanceMethod(element) ||
- isInstanceField(element) ||
- (send.isConditional && !element.isStatic);
- }
-
- static bool isClosureSend(Send send, Element element) {
- if (send.isPropertyAccess) return false;
- if (send.receiver != null) return false;
- Node selector = send.selector;
- // this().
- if (selector.isThis()) return true;
- // (o)() or foo()().
- if (element == null && selector.asIdentifier() == null) return true;
- if (element == null) return false;
- // foo() with foo a local or a parameter.
- return isLocal(element);
- }
-
- static String reconstructConstructorNameSourceString(FunctionEntity element) {
- if (element.name == '') {
- return element.enclosingClass.name;
- } else {
- return utils.reconstructConstructorName(element);
- }
- }
-
- static String constructorNameForDiagnostics(
- String className, String constructorName) {
- String classNameString = className;
- String constructorNameString = constructorName;
- return (constructorName == '')
- ? classNameString
- : "$classNameString.$constructorNameString";
- }
-
- /// Returns `true` if [name] is the name of an operator method.
- static bool isOperatorName(String name) {
- return name == 'unary-' || isUserDefinableOperator(name);
- }
-
- /**
- * Map an operator-name to a valid JavaScript identifier.
- *
- * For non-operator names, this method just returns its input.
- *
- * The results returned from this method are guaranteed to be valid
- * JavaScript identifiers, except it may include reserved words for
- * non-operator names.
- */
- static String operatorNameToIdentifier(String name) {
- if (name == null) {
- return name;
- } else if (name == '==') {
- return r'operator$eq';
- } else if (name == '~') {
- return r'operator$not';
- } else if (name == '[]') {
- return r'operator$index';
- } else if (name == '[]=') {
- return r'operator$indexSet';
- } else if (name == '*') {
- return r'operator$mul';
- } else if (name == '/') {
- return r'operator$div';
- } else if (name == '%') {
- return r'operator$mod';
- } else if (name == '~/') {
- return r'operator$tdiv';
- } else if (name == '+') {
- return r'operator$add';
- } else if (name == '<<') {
- return r'operator$shl';
- } else if (name == '>>') {
- return r'operator$shr';
- } else if (name == '>=') {
- return r'operator$ge';
- } else if (name == '>') {
- return r'operator$gt';
- } else if (name == '<=') {
- return r'operator$le';
- } else if (name == '<') {
- return r'operator$lt';
- } else if (name == '&') {
- return r'operator$and';
- } else if (name == '^') {
- return r'operator$xor';
- } else if (name == '|') {
- return r'operator$or';
- } else if (name == '-') {
- return r'operator$sub';
- } else if (name == 'unary-') {
- return r'operator$negate';
- } else {
- return name;
- }
- }
-
- static String constructOperatorNameOrNull(String op, bool isUnary) {
- if (isMinusOperator(op)) {
- return isUnary ? 'unary-' : op;
- } else if (isUserDefinableOperator(op) || op == '??') {
- return op;
- } else {
- return null;
- }
- }
-
- static String constructOperatorName(String op, bool isUnary) {
- String operatorName = constructOperatorNameOrNull(op, isUnary);
- if (operatorName == null)
- throw 'Unhandled operator: $op';
- else
- return operatorName;
- }
-
- static String mapToUserOperatorOrNull(String op) {
- if (identical(op, '!=')) return '==';
- if (identical(op, '*=')) return '*';
- if (identical(op, '/=')) return '/';
- if (identical(op, '%=')) return '%';
- if (identical(op, '~/=')) return '~/';
- if (identical(op, '+=')) return '+';
- if (identical(op, '-=')) return '-';
- if (identical(op, '<<=')) return '<<';
- if (identical(op, '>>=')) return '>>';
- if (identical(op, '&=')) return '&';
- if (identical(op, '^=')) return '^';
- if (identical(op, '|=')) return '|';
- if (identical(op, '??=')) return '??';
-
- return null;
- }
-
- /// If `true`, members are sorted using their implementation fileUri.
- ///
- /// This is used for ensuring equivalent output order when testing against
- /// .dill.
- // TODO(johnniwinther): Remove this when patching correctly stores origin and
- // patch file uris (issue 31579)
- static bool useCFEOrder = false;
-
- /// A `compareTo` function that places [Element]s in a consistent order based
- /// on the source code order.
- static int compareByPosition(Element a, Element b) {
- if (identical(a, b)) return 0;
- if (useCFEOrder) {
- if (a is MethodElement) {
- a = a.implementation;
- }
- if (b is MethodElement) {
- b = b.implementation;
- }
- }
- int r = utils.compareLibrariesUris(
- a.library.canonicalUri, b.library.canonicalUri);
- if (r != 0) return r;
- Uri aUri = a.compilationUnit.script.readableUri;
- Uri bUri = b.compilationUnit.script.readableUri;
- r = utils.compareSourceUris(aUri, bUri);
- if (r != 0) return r;
- return utils.compareEntities(a, a.sourceOffset, -1, b, b.sourceOffset, -1);
- }
-
- static List<E> sortedByPosition<E extends Element>(Iterable<E> elements) {
- return elements.toList()..sort(compareByPosition);
- }
-
- static bool isFixedListConstructorCall(
- ConstructorEntity element, Send node, CommonElements commonElements) {
- return commonElements.isUnnamedListConstructor(element) &&
- node.isCall &&
- !node.arguments.isEmpty &&
- node.arguments.tail.isEmpty;
- }
-
- static bool isGrowableListConstructorCall(
- ConstructorEntity element, Send node, CommonElements commonElements) {
- return commonElements.isUnnamedListConstructor(element) &&
- node.isCall &&
- node.arguments.isEmpty;
- }
-
- static bool isFilledListConstructorCall(
- ConstructorEntity element, Send node, CommonElements commonElements) {
- return commonElements.isFilledListConstructor(element) &&
- node.isCall &&
- !node.arguments.isEmpty &&
- !node.arguments.tail.isEmpty &&
- node.arguments.tail.tail.isEmpty;
- }
-
- static bool isConstructorOfTypedArraySubclass(
- Element element, ClosedWorld closedWorld) {
- if (closedWorld.commonElements.typedDataLibrary == null) return false;
- if (!element.isConstructor) return false;
- ConstructorElement constructor = element.implementation;
- constructor = constructor.effectiveTarget;
- ClassElement cls = constructor.enclosingClass;
- return cls.library == closedWorld.commonElements.typedDataLibrary &&
- closedWorld.nativeData.isNativeClass(cls) &&
- closedWorld.isSubtypeOf(
- cls, closedWorld.commonElements.typedDataClass) &&
- closedWorld.isSubtypeOf(cls, closedWorld.commonElements.listClass) &&
- constructor.name == '';
- }
-
- static bool switchStatementHasContinue(
- SwitchStatement node, TreeElements elements) {
- for (SwitchCase switchCase in node.cases) {
- for (Node labelOrCase in switchCase.labelsAndCases) {
- Node label = labelOrCase.asLabel();
- if (label != null) {
- LabelDefinition labelElement = elements.getLabelDefinition(label);
- if (labelElement != null && labelElement.isContinueTarget) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- static bool isUnusedLabel(LabeledStatement node, TreeElements elements) {
- Node body = node.statement;
- JumpTarget element = elements.getTargetDefinition(body);
- // Labeled statements with no element on the body have no breaks.
- // A different target statement only happens if the body is itself
- // a break or continue for a different target. In that case, this
- // label is also always unused.
- return element == null || element.statement != body;
- }
-
- /**
- * Returns a `List` with the evaluated arguments in the normalized order.
- *
- * [compileDefaultValue] is a function that returns a compiled constant
- * of an optional argument that is not in [compiledArguments].
- *
- * Precondition: `callStructure.signatureApplies(element.type)`.
- *
- * Invariant: [element] must be the implementation element.
- */
- static List<T> makeArgumentsList<T>(
- CallStructure callStructure,
- Link<Node> arguments,
- FunctionElement element,
- T compileArgument(Node argument),
- T compileDefaultValue(ParameterElement element)) {
- assert(element.isImplementation, failedAt(element));
- List<T> result = <T>[];
-
- FunctionSignature parameters = element.functionSignature;
- parameters.forEachRequiredParameter((_) {
- result.add(compileArgument(arguments.head));
- arguments = arguments.tail;
- });
-
- if (!parameters.optionalParametersAreNamed) {
- parameters.forEachOptionalParameter((_element) {
- ParameterElement element = _element;
- if (!arguments.isEmpty) {
- result.add(compileArgument(arguments.head));
- arguments = arguments.tail;
- } else {
- result.add(compileDefaultValue(element));
- }
- });
- } else {
- // Visit named arguments and add them into a temporary list.
- List compiledNamedArguments = [];
- for (; !arguments.isEmpty; arguments = arguments.tail) {
- NamedArgument namedArgument = arguments.head;
- compiledNamedArguments.add(compileArgument(namedArgument.expression));
- }
- // 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.
- parameters.orderedOptionalParameters.forEach((_element) {
- ParameterElement element = _element;
- int foundIndex = callStructure.namedArguments.indexOf(element.name);
- if (foundIndex != -1) {
- result.add(compiledNamedArguments[foundIndex]);
- } else {
- result.add(compileDefaultValue(element));
- }
- });
- }
- return result;
- }
-
- /**
- * Fills [list] with the arguments in the order expected by
- * [callee], and where [caller] is a synthesized element
- *
- * [compileArgument] is a function that returns a compiled version
- * of a parameter of [callee].
- *
- * [compileConstant] is a function that returns a compiled constant
- * of an optional argument that is not in the parameters of [callee].
- *
- * Returns [:true:] if the signature of the [caller] matches the
- * signature of the [callee], [:false:] otherwise.
- */
- static bool addForwardingElementArgumentsToList<T>(
- ConstructorElement caller,
- List<T> list,
- ConstructorElement callee,
- T compileArgument(ParameterElement element),
- T compileConstant(ParameterElement element)) {
- assert(
- !callee.isMalformed,
- failedAt(
- caller,
- "Cannot compute arguments to malformed constructor: "
- "$caller calling $callee."));
-
- FunctionSignature signature = caller.functionSignature;
- Map<Node, ParameterElement> mapping = <Node, ParameterElement>{};
-
- // TODO(ngeoffray): This is a hack that fakes up AST nodes, so
- // that we can call [addArgumentsToList].
- Link<Node> computeCallNodesFromParameters() {
- LinkBuilder<Node> builder = new LinkBuilder<Node>();
- signature.forEachRequiredParameter((_element) {
- ParameterElement element = _element;
- Node node = element.node;
- mapping[node] = element;
- builder.addLast(node);
- });
- if (signature.optionalParametersAreNamed) {
- signature.forEachOptionalParameter((_element) {
- ParameterElement element = _element;
- mapping[element.initializer] = element;
- builder.addLast(new NamedArgument(null, null, element.initializer));
- });
- } else {
- signature.forEachOptionalParameter((_element) {
- ParameterElement element = _element;
- Node node = element.node;
- mapping[node] = element;
- builder.addLast(node);
- });
- }
- return builder.toLink();
- }
-
- T internalCompileArgument(Node node) {
- return compileArgument(mapping[node]);
- }
-
- Link<Node> nodes = computeCallNodesFromParameters();
-
- // Synthesize a structure for the call.
- // TODO(ngeoffray): Should the resolver do it instead?
- CallStructure callStructure = new CallStructure(
- signature.parameterCount, signature.type.namedParameters);
- if (!callStructure.signatureApplies(signature.parameterStructure)) {
- return false;
- }
- list.addAll(makeArgumentsList<T>(callStructure, nodes, callee,
- internalCompileArgument, compileConstant));
-
- return true;
- }
-}
-
-/// An element representing an erroneous resolution.
-///
-/// An [ErroneousElement] is used instead of `null` to provide additional
-/// information about the error that caused the element to be unresolvable
-/// or otherwise invalid.
-///
-/// Accessing any field or calling any method defined on [ErroneousElement]
-/// except [isError] will currently throw an exception. (This might
-/// change when we actually want more information on the erroneous element,
-/// e.g., the name of the element we were trying to resolve.)
-///
-/// Code that cannot not handle an [ErroneousElement] should use
-/// `Element.isUnresolved(element)` to check for unresolvable elements instead
-/// of `element == null`.
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class ErroneousElement extends Element implements ConstructorElement {
- MessageKind get messageKind;
- Map get messageArguments;
- String get message;
-}
-
-/// An [Element] whose usage should cause one or more warnings.
-abstract class WarnOnUseElement extends Element {
- /// The element whose usage cause a warning.
- Element get wrappedElement;
-
- /// Reports the attached warning and returns the wrapped element.
- /// [usageSpannable] is used to report messages on the reference of
- /// [wrappedElement].
- Element unwrap(DiagnosticReporter listener, Spannable usageSpannable);
-}
-
-/// An ambiguous element represents multiple elements accessible by the same
-/// name.
-///
-/// Ambiguous elements are created during handling of import/export scopes. If
-/// an ambiguous element is encountered during resolution a warning/error is
-/// reported.
-abstract class AmbiguousElement extends Element {
- MessageKind get messageKind;
- Map get messageArguments;
- Element get existingElement;
- Element get newElement;
-
- /// Compute the info messages associated with an error/warning on [context].
- List<DiagnosticMessage> computeInfos(
- Element context, DiagnosticReporter listener);
-}
-
-// TODO(kasperl): This probably shouldn't be called an element. It's
-// just an interface shared by classes and libraries.
-abstract class ScopeContainerElement implements Element {
- Element localLookup(String elementName);
-
- void forEachLocalMember(f(Element element));
-}
-
-abstract class CompilationUnitElement extends Element {
- /// Use [library] instead.
- @deprecated
- get enclosingElement;
-
- Script get script;
-
- void forEachLocalMember(f(Element element));
-}
-
-abstract class ImportElement extends Element implements ImportEntity {
- Uri get uri;
- LibraryElement get importedLibrary;
- LibraryElement get enclosingLibrary => library;
- bool get isDeferred;
- PrefixElement get prefix;
- String get name;
- // TODO(johnniwinther): Remove this when no longer needed in source mirrors.
- Import get node;
-}
-
-abstract class ExportElement extends Element {
- Uri get uri;
- LibraryElement get exportedLibrary;
- // TODO(johnniwinther): Remove this when no longer needed in source mirrors.
- Export get node;
-}
-
-abstract class LibraryElement extends Element
- implements ScopeContainerElement, AnalyzableElement, LibraryEntity {
- /**
- * The canonical uri for this library.
- *
- * For user libraries the canonical uri is the script uri. For platform
- * libraries the canonical uri is of the form [:dart:x:].
- */
- Uri get canonicalUri;
-
- /// Returns `true` if this library is 'dart:core'.
- bool get isDartCore;
-
- CompilationUnitElement get entryCompilationUnit;
- Link<CompilationUnitElement> get compilationUnits;
-
- /// The import declarations in this library, including the implicit import of
- /// 'dart:core', if present.
- Iterable<ImportElement> get imports;
-
- /// The export declarations in this library.
- Iterable<ExportElement> get exports;
-
- /**
- * [:true:] if this library is part of the platform, that is, its canonical
- * uri has the scheme 'dart'.
- */
- bool get isPlatformLibrary;
-
- /**
- * [:true:] if this library is from a package, that is, its canonical uri has
- * the scheme 'package'.
- */
- bool get isPackageLibrary;
-
- /**
- * [:true:] if this library is a platform library whose path starts with
- * an underscore.
- */
- bool get isInternalLibrary;
-
- bool get exportsHandled;
-
- LibraryElement get implementation;
-
- Element find(String elementName);
- Element findLocal(String elementName);
- Element findExported(String elementName);
- void forEachExport(f(Element element));
-
- /// Calls [f] for each [Element] imported into this library.
- void forEachImport(f(Element element));
-
- /// Returns the imports that import element into this library.
- Iterable<ImportElement> getImportsFor(Element element);
-
- /// `true` if this library has name as given through a library tag.
- bool get hasLibraryName;
-
- /// The library name, which is either the name given in the library tag
- /// or the empty string if there is no library tag.
- String get libraryName;
-
- /// Returns the library name (as defined by the library tag) or for scripts
- /// (which have no library tag) the script file name.
- ///
- /// Note: the returned filename is still escaped ("a%20b.dart" instead of
- /// "a b.dart").
- String get name;
-}
-
-/// The implicit scope defined by a import declaration with a prefix clause.
-abstract class PrefixElement extends Element {
- Element lookupLocalMember(String memberName);
-
- void forEachLocalMember(void f(Element member));
-
- /// Is true if this prefix belongs to a deferred import.
- bool get isDeferred;
-
- /// Import that declared this deferred prefix.
- ImportElement get deferredImport;
-
- /// The `loadLibrary` getter implicitly defined on deferred prefixes.
- GetterElement get loadLibrary;
-}
-
-/// A type alias definition.
-abstract class TypedefElement extends Element
- implements
- AstElement,
- TypeDeclarationElement,
- FunctionTypedElement,
- TypedefEntity {
- /// The type defined by this typedef with the type variables as its type
- /// arguments.
- ///
- /// For instance `F<T>` for `typedef void F<T>(T t)`.
- ResolutionTypedefType get thisType;
-
- /// The type defined by this typedef with `dynamic` as its type arguments.
- ///
- /// For instance `F<dynamic>` for `typedef void F<T>(T t)`.
- ResolutionTypedefType get rawType;
-
- /// The type, function type if well-defined, for which this typedef is an
- /// alias.
- ///
- /// For instance `(int)->void` for `typedef void F(int)`.
- ResolutionDartType get alias;
-
- void checkCyclicReference(Resolution resolution);
-}
-
-/// An executable element is an element that can hold code.
-///
-/// These elements variables (fields, parameters and locals), which can hold
-/// code in their initializer, and functions (including methods and
-/// constructors), which can hold code in their body.
-abstract class ExecutableElement extends Element
- implements TypedElement, AstElement {
- /// The outermost member that contains this element.
- ///
- /// For top level, static or instance members, the member context is the
- /// element itself. For parameters, local variables and nested closures, the
- /// member context is the top level, static or instance member in which it is
- /// defined.
- MemberElement get memberContext;
-}
-
-/// A top-level, static or instance field or method, or a constructor.
-///
-/// A [MemberElement] is the outermost executable element for any executable
-/// context.
-abstract class MemberElement extends Element
- implements ExecutableElement, MemberEntity {
- /// The local functions defined within this member.
- List<MethodElement> get nestedClosures;
-
- /// The name of this member, taking privacy into account.
- Name get memberName;
-}
-
-/// A local function, variable, parameter or synthesized local.
-abstract class LocalVariable implements Local {
- /// The context in which this local is defined.
- ExecutableElement get executableContext;
-
- /// The outermost member that contains this element.
- ///
- /// For top level, static or instance members, the member context is the
- /// element itself. For parameters, local variables and nested closures, the
- /// member context is the top level, static or instance member in which it is
- /// defined.
- MemberElement get memberContext;
-}
-
-/// A function, variable or parameter defined in an executable context.
-abstract class LocalElement extends Element
- implements AstElement, TypedElement, LocalVariable {
- ExecutableElement get executableContext;
-}
-
-/// A top level, static or instance field, a formal parameter or local variable.
-abstract class VariableElement extends ExecutableElement {
- @override
- VariableDefinitions get node;
-
- Expression get initializer;
-
- bool get hasConstant;
-
- /// The constant expression defining the (initial) value of the variable.
- ///
- /// If the variable is `const` the value is always non-null, possibly an
- /// [ErroneousConstantExpression], otherwise, the value is null when the
- /// initializer isn't a constant expression.
- ConstantExpression get constant;
-}
-
-/// A variable or parameter that is local to an executable context.
-///
-/// The executable context is the [ExecutableElement] in which this variable
-/// is defined.
-abstract class LocalVariableElement extends VariableElement
- implements LocalElement {}
-
-/// A top-level, static or instance field.
-abstract class FieldElement extends VariableElement
- implements MemberElement, FieldEntity {}
-
-/// A parameter-like element of a function signature.
-///
-/// If the function signature comes from a typedef or an inline function-typed
-/// parameter (e.g. the parameter 'f' in `method(void f())`), then its
-/// parameters are not real parameters in that they can take no argument and
-/// hold no value. Such parameter-like elements are modeled by [FormalElement].
-///
-/// If the function signature comes from a function or constructor, its
-/// parameters are real parameters and are modeled by [ParameterElement].
-abstract class FormalElement extends Element
- implements FunctionTypedElement, TypedElement, AstElement {
- /// Use [functionDeclaration] instead.
- @deprecated
- get enclosingElement;
-
- /// The function, typedef or inline function-typed parameter on which
- /// this parameter is declared.
- FunctionTypedElement get functionDeclaration;
-
- VariableDefinitions get node;
-
- /// Whether the parameter is unnamed in a function type.
- bool get isUnnamed;
-}
-
-/// A formal parameter of a function or constructor.
-///
-/// Normal parameter that introduce a local variable are modeled by
-/// [LocalParameterElement] whereas initializing formals, that is parameter of
-/// the form `this.x`, are modeled by [InitializingFormalElement].
-abstract class ParameterElement extends Element
- implements VariableElement, FormalElement, LocalElement {
- /// Use [functionDeclaration] instead.
- @deprecated
- get enclosingElement;
-
- /// The function on which this parameter is declared.
- FunctionElement get functionDeclaration;
-
- /// `true` if this parameter is named.
- bool get isNamed;
-
- /// `true` if this parameter is optional.
- bool get isOptional;
-}
-
-/// A formal parameter on a function or constructor that introduces a local
-/// variable in the scope of the function or constructor.
-abstract class LocalParameterElement extends ParameterElement
- implements LocalVariableElement {}
-
-/// A formal parameter in a constructor that directly initializes a field.
-///
-/// For example: `A(this.field)`.
-abstract class InitializingFormalElement extends LocalParameterElement {
- /// The field initialized by this initializing formal.
- FieldElement get fieldElement;
-
- /// The function on which this parameter is declared.
- ConstructorElement get functionDeclaration;
-}
-
-/**
- * A synthetic element which holds a getter and/or a setter.
- *
- * This element unifies handling of fields and getters/setters. When
- * looking at code like "foo.x", we don't have to look for both a
- * field named "x", a getter named "x", and a setter named "x=".
- */
-abstract class AbstractFieldElement extends Element {
- GetterElement get getter;
- SetterElement get setter;
-}
-
-abstract class FunctionSignature {
- ResolutionFunctionType get type;
- ResolutionDartType get returnType;
- List<ResolutionDartType> get typeVariables;
- List<FormalElement> get requiredParameters;
- List<FormalElement> get optionalParameters;
-
- int get requiredParameterCount;
- int get optionalParameterCount;
- bool get optionalParametersAreNamed;
- bool get hasOptionalParameters;
-
- int get parameterCount;
- List<FormalElement> get orderedOptionalParameters;
-
- void forEachParameter(void function(FormalElement parameter));
- void forEachRequiredParameter(void function(FormalElement parameter));
- void forEachOptionalParameter(void function(FormalElement parameter));
-
- void orderedForEachParameter(void function(FormalElement parameter));
-
- bool isCompatibleWith(FunctionSignature constructorSignature);
-
- ParameterStructure get parameterStructure;
-}
-
-/// A top level, static or instance method, constructor, local function, or
-/// closure (anonymous local function).
-abstract class FunctionElement extends Element
- implements
- AstElement,
- TypedElement,
- FunctionTypedElement,
- ExecutableElement,
- GenericElement {
- FunctionExpression get node;
-
- FunctionElement get patch;
- FunctionElement get origin;
-
- bool get hasFunctionSignature;
-
- /// The parameters of this function.
- List<ParameterElement> get parameters;
-
- /// The type of this function.
- ResolutionFunctionType get type;
-
- /// The synchronous/asynchronous marker on this function.
- AsyncMarker get asyncMarker;
-
- /// `true` if this function is external.
- ///
- /// Patched methods are _not_ external, but [isMarkedExternal] is `true`.
- bool get isExternal;
-
- /// `true` if this function is marked as external.
- ///
- /// If the function is implemented through a patch [isExternal] is `false`.
- bool get isMarkedExternal;
-
- /// The structure of the function parameters.
- ParameterStructure get parameterStructure;
-}
-
-/// A getter or setter.
-abstract class AccessorElement extends MethodElement {
- /// Used to retrieve a link to the abstract field element representing this
- /// element.
- AbstractFieldElement get abstractField;
-}
-
-/// A getter.
-abstract class GetterElement extends AccessorElement {
- /// The setter corresponding to this getter, if any.
- SetterElement get setter;
-}
-
-/// A setter.
-abstract class SetterElement extends AccessorElement {
- /// The getter corresponding to this setter, if any.
- GetterElement get getter;
-}
-
-/// A top level, static or instance function.
-abstract class MethodElement extends FunctionElement
- implements MemberElement, FunctionEntity {}
-
-/// A local function or closure (anonymous local function).
-abstract class LocalFunctionElement extends FunctionElement
- implements LocalElement {
- /// The synthesized 'call' method created for this local function during
- /// closure conversion.
- MethodElement callMethod;
-}
-
-/// A constructor.
-abstract class ConstructorElement extends MethodElement
- implements ConstructorEntity {
- /// Returns `true` if [effectiveTarget] has been computed for this
- /// constructor.
- bool get hasEffectiveTarget;
-
- /// The effective target of this constructor, that is the non-redirecting
- /// constructor that is called on invocation of this constructor.
- ///
- /// Consider for instance this hierarchy:
- ///
- /// class C { factory C.c() = D.d; }
- /// class D { factory D.d() = E.e2; }
- /// class E { E.e1();
- /// E.e2() : this.e1(); }
- ///
- /// The effective target of both `C.c`, `D.d`, and `E.e2` is `E.e2`, and the
- /// effective target of `E.e1` is `E.e1` itself.
- ConstructorElement get effectiveTarget;
-
- /// The immediate redirection target of a redirecting factory constructor.
- ///
- /// Consider for instance this hierarchy:
- ///
- /// class C { factory C() = D; }
- /// class D { factory D() = E; }
- /// class E { E(); }
- ///
- /// The immediate redirection target of `C` is `D` and the immediate
- /// redirection target of `D` is `E`. `E` is not a redirecting factory
- /// constructor so its immediate redirection target is `null`.
- ConstructorElement get immediateRedirectionTarget;
-
- /// The prefix of the immediateRedirectionTarget, if it is deferred.
- /// [null] if it is not deferred.
- PrefixElement get redirectionDeferredPrefix;
-
- /// Is `true` if this constructor is a redirecting generative constructor.
- bool get isRedirectingGenerative;
-
- /// Is `true` if this constructor is a redirecting factory constructor.
- bool get isRedirectingFactory;
-
- /// Is `true` if this constructor is a redirecting factory constructor that is
- /// part of a redirection cycle.
- bool get isCyclicRedirection;
-
- /// Is `true` if the effective target of this constructor is malformed.
- ///
- /// A constructor is considered malformed if any of the following applies:
- ///
- /// * the constructor is undefined,
- /// * the type of the constructor is undefined,
- /// * the constructor is a redirecting factory and either
- /// - it is part of a redirection cycle,
- /// - the effective target is a generative constructor on an abstract
- /// class, or
- /// - this constructor is constant but the effective target is not,
- /// - the arguments to this constructor are incompatible with the
- /// parameters of the effective target.
- bool get isEffectiveTargetMalformed;
-
- /// Compute the type of the effective target of this constructor for an
- /// instantiation site with type [:newType:].
- /// May return a malformed type.
- ResolutionDartType computeEffectiveTargetType(
- ResolutionInterfaceType newType);
-
- /// If this is a synthesized constructor [definingConstructor] points to
- /// the generative constructor from which this constructor was created.
- /// Otherwise [definingConstructor] is `null`.
- ///
- /// Consider for instance this hierarchy:
- ///
- /// class C { C.c(a, {b});
- /// class D {}
- /// class E = C with D;
- ///
- /// Class `E` has a synthesized constructor, `E.c`, whose defining constructor
- /// is `C.c`.
- ConstructorElement get definingConstructor;
-
- /// Returns `true` if this constructor is an implicit default constructor.
- bool get isDefaultConstructor;
-
- /// The constant constructor defining the binding of fields if `const`,
- /// `null` otherwise.
- ConstantConstructor get constantConstructor;
-
- /// `true` if this constructor is one of `bool.fromEnvironment`,
- /// `int.fromEnvironment`, or `String.fromEnvironment`.
- bool get isFromEnvironmentConstructor;
-
- /// `true` if this constructor is `int.fromEnvironment`.
- bool get isIntFromEnvironmentConstructor;
-
- /// `true` if this constructor is `bool.fromEnvironment`.
- bool get isBoolFromEnvironmentConstructor;
-
- /// `true` if this constructor is `String.fromEnvironment`.
- bool get isStringFromEnvironmentConstructor;
-
- /// Use [enclosingClass] instead.
- @deprecated
- get enclosingElement;
-}
-
-/// JavaScript backend specific element for the body of constructor.
-// TODO(johnniwinther): Remove this class from the element model.
-abstract class ConstructorBodyElement extends MethodElement
- implements ConstructorBodyEntity {
- ConstructorElement get constructor;
-}
-
-/// [GenericElement] defines the common interface for generic functions and
-/// [TypeDeclarationElement].
-abstract class GenericElement extends Element implements AstElement {
- /// Do not use [computeType] outside of the resolver.
- ///
- /// Trying to access a type that has not been computed in resolution is an
- /// error and calling [computeType] covers that error.
- /// This method will go away!
- @deprecated
- ResolutionDartType computeType(Resolution resolution);
-
- /**
- * The type variables declared on this declaration. The type variables are not
- * available until the type of the element has been computed through
- * [computeType].
- */
- List<ResolutionDartType> get typeVariables;
-}
-
-/// [TypeDeclarationElement] defines the common interface for class/interface
-/// declarations and typedefs.
-abstract class TypeDeclarationElement extends GenericElement {
- /// The name of this type declaration, taking privacy into account.
- Name get memberName;
-
- /// Do not use [computeType] outside of the resolver; instead retrieve the
- /// type from the [thisType] or [rawType], depending on the use case.
- ///
- /// Trying to access a type that has not been computed in resolution is an
- /// error and calling [computeType] covers that error.
- /// This method will go away!
- @deprecated
- GenericType computeType(Resolution resolution);
-
- /**
- * The `this type` for this type declaration.
- *
- * The type of [:this:] is the generic type based on this element in which
- * the type arguments are the declared type variables. For instance,
- * [:List<E>:] for [:List:] and [:Map<K,V>:] for [:Map:].
- *
- * For a class declaration this is the type of [:this:].
- */
- GenericType get thisType;
-
- /**
- * The raw type for this type declaration.
- *
- * The raw type is the generic type base on this element in which the type
- * arguments are all [dynamic]. For instance [:List<dynamic>:] for [:List:]
- * and [:Map<dynamic,dynamic>:] for [:Map:]. For non-generic classes [rawType]
- * is the same as [thisType].
- *
- * The [rawType] field is a canonicalization of the raw type and should be
- * used to distinguish explicit and implicit uses of the [dynamic]
- * type arguments. For instance should [:List:] be the [rawType] of the
- * [:List:] class element whereas [:List<dynamic>:] should be its own
- * instantiation of [ResolutionInterfaceType] with [:dynamic:] as type
- * argument. Using this distinction, we can print the raw type with type
- * arguments only when the input source has used explicit type arguments.
- */
- GenericType get rawType;
-
- bool get isResolved;
-
- void ensureResolved(Resolution resolution);
-}
-
-abstract class ClassElement extends TypeDeclarationElement
- implements ScopeContainerElement, ClassEntity {
- /// The length of the longest inheritance path from [:Object:].
- int get hierarchyDepth;
-
- ResolutionInterfaceType get rawType;
- ResolutionInterfaceType get thisType;
- ClassElement get superclass;
-
- /// The direct supertype of this class.
- ResolutionDartType get supertype;
-
- /// Ordered set of all supertypes of this class including the class itself.
- OrderedTypeSet get allSupertypesAndSelf;
-
- /// A list of all supertypes of this class excluding the class itself.
- Link<InterfaceType> get allSupertypes;
-
- /// Returns the this type of this class as an instance of [cls].
- ResolutionInterfaceType asInstanceOf(ClassElement cls);
-
- /// A list of all direct superinterfaces of this class.
- Link<ResolutionDartType> get interfaces;
-
- bool get hasConstructor;
- Link<Element> get constructors;
-
- ClassElement get patch;
- ClassElement get origin;
- ClassElement get declaration;
- ClassElement get implementation;
-
- /// `true` if this class is an enum declaration.
- bool get isEnumClass;
-
- /// `true` if this class is a mixin application, either named or unnamed.
- bool get isMixinApplication;
-
- /// `true` if this class is a named mixin application, e.g.
- ///
- /// class NamedMixinApplication = SuperClass with MixinClass;
- ///
- bool get isNamedMixinApplication;
-
- /// `true` if this class is an unnamed mixin application, e.g. the synthesized
- /// `SuperClass+MixinClass` mixin application class in:
- ///
- /// class Class extends SuperClass with MixinClass {}
- ///
- bool get isUnnamedMixinApplication;
-
- bool get hasConstructorBodies;
- bool get hasLocalScopeMembers;
-
- /// Returns `true` if this class is `Object` from dart:core.
- bool get isObject;
-
- /// Returns `true` if this class implements [Function] either by directly
- /// implementing the interface or by providing a [call] method.
- bool implementsFunction(CommonElements commonElements);
-
- /// Returns `true` if this class extends [cls] directly or indirectly.
- ///
- /// This method is not to be used for checking type hierarchy and assignments,
- /// because it does not take parameterized types into account.
- bool isSubclassOf(ClassElement cls);
-
- /// Returns `true` if this class explicitly implements [intrface].
- ///
- /// Note that, if [intrface] is the `Function` class, this method returns
- /// false for a class that has a `call` method but does not explicitly
- /// implement `Function`.
- bool implementsInterface(ClassElement intrface);
-
- bool hasFieldShadowedBy(FieldElement fieldMember);
-
- /// Returns `true` if this class has a @proxy annotation.
- bool get isProxy;
-
- /// Returns `true` if the class hierarchy for this class contains errors.
- bool get hasIncompleteHierarchy;
-
- void addConstructorBody(ConstructorBodyElement element);
-
- Element lookupMember(String memberName);
-
- /// Looks up a class instance member declared or inherited in this class
- /// using [memberName] to match the (private) name and getter/setter property.
- ///
- /// This method recursively visits superclasses until the member is found or
- /// [stopAt] is reached.
- MemberElement lookupByName(Name memberName, {ClassElement stopAt});
- MemberElement lookupSuperByName(Name memberName);
-
- Element lookupLocalMember(String memberName);
- ConstructorBodyElement lookupConstructorBody(String memberName);
- Element lookupSuperMember(String memberName);
-
- Element lookupSuperMemberInLibrary(String memberName, LibraryElement library);
-
- // TODO(johnniwinther): Clean up semantics. Can the default constructor take
- // optional arguments? Must it be resolved?
- ConstructorElement lookupDefaultConstructor();
- ConstructorElement lookupConstructor(String name);
-
- void forEachMember(void f(ClassElement enclosingClass, Element member),
- {bool includeBackendMembers: false,
- bool includeSuperAndInjectedMembers: false});
-
- void forEachInstanceField(
- void f(ClassElement enclosingClass, FieldElement field),
- {bool includeSuperAndInjectedMembers: false});
-
- /// Similar to [forEachInstanceField] but visits static fields.
- void forEachStaticField(void f(ClassElement enclosingClass, Element field));
-
- void forEachConstructorBody(void f(ConstructorBodyElement member));
-
- /// Looks up the member [name] in this class.
- Member lookupClassMember(Name name);
-
- /// Calls [f] with each member of this class.
- void forEachClassMember(f(Member member));
-
- /// Looks up the member [name] in the interface of this class.
- MemberSignature lookupInterfaceMember(Name name);
-
- /// Calls [f] with each member of the interface of this class.
- void forEachInterfaceMember(f(MemberSignature member));
-
- /// Returns the type of the 'call' method in the interface of this class, or
- /// `null` if the interface has no 'call' method.
- ResolutionFunctionType get callType;
-}
-
-abstract class MixinApplicationElement extends ClassElement {
- ClassElement get mixin;
- ResolutionInterfaceType get mixinType;
-
- /// If this is an unnamed mixin application [subclass] is the subclass for
- /// which this mixin application is created.
- ClassElement get subclass;
-}
-
-/// Enum declaration.
-abstract class EnumClassElement extends ClassElement {
- /// The static fields implied by the enum values.
- List<EnumConstantElement> get enumValues;
-}
-
-/// An enum constant value.
-abstract class EnumConstantElement extends FieldElement {
- /// The enum that declared this constant.
- EnumClassElement get enclosingClass;
-
- /// The index of this constant within the values of the enum.
- int get index;
-}
-
-/// The [Element] for a type variable declaration on a generic class or typedef.
-abstract class TypeVariableElement extends Element
- implements AstElement, TypedElement, TypeVariableEntity {
- /// The name of this type variable, taking privacy into account.
- Name get memberName;
-
- /// Use [typeDeclaration] instead.
- @deprecated
- get enclosingElement;
-
- /// The class, typedef, function, method, or function typed parameter on
- /// which this type variable is defined.
- GenericElement get typeDeclaration;
-
- /// The index of this type variable within its type declaration.
- int get index;
-
- /// The [type] defined by the type variable.
- ResolutionTypeVariableType get type;
-
- /// The upper bound on the type variable. If not explicitly declared, this is
- /// `Object`.
- ResolutionDartType get bound;
-}
-
-abstract class MetadataAnnotation implements Spannable {
- /// The front-end constant of this metadata annotation.
- ConstantExpression get constant;
- Element get annotatedElement;
- SourceSpan get sourcePosition;
-
- bool get hasNode;
- Node get node;
-
- MetadataAnnotation ensureResolved(Resolution resolution);
-}
-
-/// An [Element] that has a type.
-abstract class TypedElement extends Element {
- /// Do not use [computeType] outside of the resolver; instead retrieve the
- /// type from [type] property.
- ///
- /// Trying to access a type that has not been computed in resolution is an
- /// error and calling [computeType] covers that error.
- /// This method will go away!
- @deprecated
- ResolutionDartType computeType(Resolution resolution);
-
- ResolutionDartType get type;
-}
-
-/// An [Element] that can define a function type.
-abstract class FunctionTypedElement extends Element implements GenericElement {
- /// The function signature for the function type defined by this element,
- /// if any.
- FunctionSignature get functionSignature;
-}
-
-/// An [Element] that holds a [TreeElements] mapping.
-abstract class AnalyzableElement extends Element {
- /// Return `true` if [treeElements] have been (partially) computed for this
- /// element.
- bool get hasTreeElements;
-
- /// Returns the [TreeElements] that hold the resolution information for the
- /// AST nodes of this element.
- TreeElements get treeElements;
-}
-
-/// An [Element] that (potentially) has a node.
-///
-/// Synthesized elements may return `null` from [node].
-abstract class AstElement extends AnalyzableElement {
- /// `true` if [node] is available and non-null.
- bool get hasNode;
-
- /// The AST node of this element.
- Node get node;
-
- /// `true` if [resolvedAst] is available.
- bool get hasResolvedAst;
-
- /// The defining AST node of this element with is corresponding
- /// [TreeElements]. This is not available if [hasResolvedAst] is `false`.
- ResolvedAst get resolvedAst;
-}
-
-/// Enum values for different ways of defining semantics for an element.
-enum ResolvedAstKind {
- /// The semantics of the element is defined in terms of an AST with resolved
- /// data mapped in [TreeElements].
- PARSED,
-
- /// The element is an implicit default constructor. No AST or [TreeElements]
- /// are provided.
- DEFAULT_CONSTRUCTOR,
-
- /// The element is an implicit forwarding constructor on a mixin application.
- /// No AST or [TreeElements] are provided.
- FORWARDING_CONSTRUCTOR,
-
- /// The element is the `loadLibrary` getter implicitly defined on a deferred
- /// prefix.
- DEFERRED_LOAD_LIBRARY,
-}
-
-/// [ResolvedAst] contains info that define the semantics of an element.
-abstract class ResolvedAst {
- /// The element whose semantics is defined.
- Element get element;
-
- /// The kind of semantics definition used for this object.
- ResolvedAstKind get kind;
-
- /// The root AST node for the declaration of [element]. This only available if
- /// [kind] is `ResolvedAstKind.PARSED`.
- Node get node;
-
- /// The AST node for the 'body' of [element].
- ///
- /// For functions and constructors this is the root AST node of the method
- /// body, and for variables this is the root AST node of the initializer, if
- /// available.
- ///
- /// This only available if [kind] is `ResolvedAstKind.PARSED`.
- Node get body;
-
- /// The [TreeElements] containing the resolution data for [node]. This only
- /// available of [kind] is `ResolvedAstKind.PARSED`.
- TreeElements get elements;
-
- /// Returns the uri for the source file defining [node] and [body]. This
- /// only available if [kind] is `ResolvedAstKind.PARSED`.
- Uri get sourceUri;
-}
-
-/// [ResolvedAst] implementation used for elements whose semantics is defined in
-/// terms an AST and a [TreeElements].
-class ParsedResolvedAst implements ResolvedAst {
- final Element element;
- final Node node;
- final Node body;
- final TreeElements elements;
- final Uri sourceUri;
-
- ParsedResolvedAst(
- this.element, this.node, this.body, this.elements, this.sourceUri);
-
- ResolvedAstKind get kind => ResolvedAstKind.PARSED;
-
- String toString() => '$kind:$element:$node';
-}
-
-/// [ResolvedAst] implementation used for synthesized elements whose semantics
-/// is not defined in terms an AST and a [TreeElements].
-class SynthesizedResolvedAst implements ResolvedAst {
- final Element element;
- final ResolvedAstKind kind;
-
- SynthesizedResolvedAst(this.element, this.kind);
-
- @override
- TreeElements get elements {
- throw new UnsupportedError('$this does not provide a TreeElements');
- }
-
- @override
- Node get node {
- throw new UnsupportedError('$this does not have a root AST node');
- }
-
- @override
- Node get body {
- throw new UnsupportedError('$this does not have a body AST node');
- }
-
- @override
- Uri get sourceUri {
- throw new UnsupportedError('$this does not have a source URI');
- }
-
- String toString() => '$kind:$element';
-}
-
-/// A [MemberSignature] is a member of an interface.
-///
-/// A signature is either a method or a getter or setter, possibly implicitly
-/// defined by a field declarations. Fields themselves are not members of an
-/// interface.
-///
-/// A [MemberSignature] may be defined by a member declaration or may be
-/// synthetized from a set of declarations.
-abstract class MemberSignature {
- /// The name of this member.
- Name get name;
-
- /// The type of the member when accessed. For getters and setters this is the
- /// return type and argument type, respectively. For methods the type is the
- /// [functionType] defined by the return type and parameters.
- ResolutionDartType get type;
-
- /// The function type of the member. For a getter `Foo get foo` this is
- /// `() -> Foo`, for a setter `void set foo(Foo _)` this is `(Foo) -> void`.
- /// For methods the function type is defined by the return type and
- /// parameters.
- ResolutionFunctionType get functionType;
-
- /// Returns `true` if this member is a getter, possibly implicitly defined by a
- /// field declaration.
- bool get isGetter;
-
- /// Returns `true` if this member is a setter, possibly implicitly defined by a
- /// field declaration.
- bool get isSetter;
-
- /// Returns `true` if this member is a method, that is neither a getter nor
- /// setter.
- bool get isMethod;
-
- /// Returns an iterable of the declarations that define this member.
- Iterable<Member> get declarations;
-}
-
-/// A [Member] is a member of a class, that is either a method or a getter or
-/// setter, possibly implicitly defined by a field declarations. Fields
-/// themselves are not members of a class.
-///
-/// A [Member] of a class also defines a signature which is a member of the
-/// corresponding interface type.
-///
-/// A [Member] is implicitly concrete. An abstract declaration only declares
-/// a signature in the interface of its class.
-///
-/// A [Member] is always declared by an [Element] which is accessibly through
-/// the [element] getter.
-abstract class Member extends MemberSignature {
- /// The [Element] that declared this member, possibly implicitly in case of
- /// a getter or setter defined by a field.
- MemberElement get element;
-
- /// The instance of the class that declared this member.
- ///
- /// For instance:
- /// class A<T> { T m() {} }
- /// class B<S> extends A<S> {}
- /// The declarer of `m` in `A` is `A<T>` whereas the declarer of `m` in `B` is
- /// `A<S>`.
- ResolutionInterfaceType get declarer;
-
- /// Returns `true` if this member is static.
- bool get isStatic;
-
- /// Returns `true` if this member is a getter or setter implicitly declared
- /// by a field.
- bool get isDeclaredByField;
-
- /// Returns `true` if this member is abstract.
- bool get isAbstract;
-
- /// If abstract, [implementation] points to the overridden concrete member,
- /// if any. Otherwise [implementation] points to the member itself.
- Member get implementation;
-}
diff --git a/pkg/compiler/lib/src/elements/entity_utils.dart b/pkg/compiler/lib/src/elements/entity_utils.dart
index 03512a8..9b11b16 100644
--- a/pkg/compiler/lib/src/elements/entity_utils.dart
+++ b/pkg/compiler/lib/src/elements/entity_utils.dart
@@ -4,6 +4,9 @@
library entity_utils;
+import 'package:front_end/src/fasta/scanner.dart'
+ show isUserDefinableOperator, isMinusOperator;
+
import 'entities.dart';
// Somewhat stable ordering for libraries using [Uri]s
@@ -89,3 +92,86 @@
return '$className\$${element.name}';
}
}
+
+String reconstructConstructorNameSourceString(FunctionEntity element) {
+ if (element.name == '') {
+ return element.enclosingClass.name;
+ } else {
+ return reconstructConstructorName(element);
+ }
+}
+
+/**
+ * Map an operator-name to a valid JavaScript identifier.
+ *
+ * For non-operator names, this method just returns its input.
+ *
+ * The results returned from this method are guaranteed to be valid
+ * JavaScript identifiers, except it may include reserved words for
+ * non-operator names.
+ */
+String operatorNameToIdentifier(String name) {
+ if (name == null) {
+ return name;
+ } else if (name == '==') {
+ return r'operator$eq';
+ } else if (name == '~') {
+ return r'operator$not';
+ } else if (name == '[]') {
+ return r'operator$index';
+ } else if (name == '[]=') {
+ return r'operator$indexSet';
+ } else if (name == '*') {
+ return r'operator$mul';
+ } else if (name == '/') {
+ return r'operator$div';
+ } else if (name == '%') {
+ return r'operator$mod';
+ } else if (name == '~/') {
+ return r'operator$tdiv';
+ } else if (name == '+') {
+ return r'operator$add';
+ } else if (name == '<<') {
+ return r'operator$shl';
+ } else if (name == '>>') {
+ return r'operator$shr';
+ } else if (name == '>=') {
+ return r'operator$ge';
+ } else if (name == '>') {
+ return r'operator$gt';
+ } else if (name == '<=') {
+ return r'operator$le';
+ } else if (name == '<') {
+ return r'operator$lt';
+ } else if (name == '&') {
+ return r'operator$and';
+ } else if (name == '^') {
+ return r'operator$xor';
+ } else if (name == '|') {
+ return r'operator$or';
+ } else if (name == '-') {
+ return r'operator$sub';
+ } else if (name == 'unary-') {
+ return r'operator$negate';
+ } else {
+ return name;
+ }
+}
+
+String constructOperatorNameOrNull(String op, bool isUnary) {
+ if (isMinusOperator(op)) {
+ return isUnary ? 'unary-' : op;
+ } else if (isUserDefinableOperator(op) || op == '??') {
+ return op;
+ } else {
+ return null;
+ }
+}
+
+String constructOperatorName(String op, bool isUnary) {
+ String operatorName = constructOperatorNameOrNull(op, isUnary);
+ if (operatorName == null)
+ throw 'Unhandled operator: $op';
+ else
+ return operatorName;
+}
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
deleted file mode 100644
index 9d137e9..0000000
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ /dev/null
@@ -1,3637 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library elements.modelx;
-
-import '../common.dart';
-import '../common/names.dart' show Identifiers;
-import '../common/resolution.dart' show Resolution, ParsingContext;
-import '../compiler.dart' show Compiler;
-import '../constants/constant_constructors.dart';
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../diagnostics/messages.dart' show MessageTemplate;
-import '../ordered_typeset.dart' show OrderedTypeSet;
-import '../resolution/class_members.dart' show ClassMemberMixin;
-import '../resolution/resolution.dart' show AnalyzableElementX;
-import '../resolution/scope.dart'
- show ClassScope, LibraryScope, Scope, TypeDeclarationScope;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../resolution/typedefs.dart' show TypedefCyclicVisitor;
-import '../script.dart';
-import 'package:front_end/src/fasta/scanner.dart' show ErrorToken, Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import '../tree/tree.dart';
-import '../util/util.dart';
-import 'common.dart';
-import 'elements.dart';
-import 'entities.dart';
-import 'jumps.dart';
-import 'names.dart';
-import 'resolution_types.dart';
-import 'visitor.dart' show ElementVisitor;
-
-/// Object that identifies a declaration site.
-///
-/// For most elements, this is the element itself, but for variable declarations
-/// where multi-declarations like `var a, b, c` are allowed, the declaration
-/// site is a separate object.
-// TODO(johnniwinther): Add [beginToken] and [endToken] getters.
-abstract class DeclarationSite {}
-
-abstract class ElementX extends Element with ElementCommon {
- static int _elementHashCode = 0;
- static int newHashCode() =>
- _elementHashCode = (_elementHashCode + 1).toUnsigned(30);
-
- final String name;
- final ElementKind kind;
- final Element enclosingElement;
- final int hashCode = newHashCode();
- List<MetadataAnnotation> metadataInternal;
-
- ElementX(this.name, this.kind, this.enclosingElement) {
- assert(isError || implementationLibrary != null);
- }
-
- Modifiers get modifiers => Modifiers.EMPTY;
-
- Node parseNode(ParsingContext parsing) {
- parsing.reporter.internalError(this, 'parseNode not implemented on $this.');
- return null;
- }
-
- void set metadata(List<MetadataAnnotation> metadata) {
- assert(metadataInternal == null);
- for (MetadataAnnotationX annotation in metadata) {
- assert(annotation.annotatedElement == null);
- annotation.annotatedElement = this;
- }
- metadataInternal = metadata;
- }
-
- Iterable<MetadataAnnotation> get metadata {
- if (isPatch && metadataInternal != null) {
- if (origin.metadata.isEmpty) {
- return metadataInternal;
- } else {
- return <MetadataAnnotation>[]
- ..addAll(origin.metadata)
- ..addAll(metadataInternal);
- }
- }
- return metadataInternal != null
- ? metadataInternal
- : const <MetadataAnnotation>[];
- }
-
- bool get isClosure => false;
- bool get isClassMember {
- // Check that this element is defined in the scope of a Class.
- return enclosingElement != null && enclosingElement.isClass;
- }
-
- bool get isInstanceMember => false;
- bool get isDeferredLoaderGetter => false;
-
- bool get isConst => modifiers.isConst;
- bool get isFinal => modifiers.isFinal;
- bool get isStatic => modifiers.isStatic;
- bool get isOperator => Elements.isOperatorName(name);
-
- bool get isSynthesized => false;
-
- bool get isMixinApplication => false;
-
- bool get isLocal => false;
-
- // TODO(johnniwinther): This breaks for libraries (for which enclosing
- // elements are null) and is invalid for top level variable declarations for
- // which the enclosing element is a VariableDeclarations and not a compilation
- // unit.
- bool get isTopLevel {
- return enclosingElement != null && enclosingElement.isCompilationUnit;
- }
-
- @override
- int get sourceOffset => position?.charOffset;
-
- Token get position => null;
-
- SourceSpan get sourcePosition {
- if (position == null) return null;
- Uri uri = compilationUnit.script.resourceUri;
- return new SourceSpan(uri, position.charOffset, position.charEnd);
- }
-
- Token findMyName(Token token) {
- return findNameToken(token, isConstructor, name, enclosingElement.name);
- }
-
- static Token findNameToken(
- Token token, bool isConstructor, String name, String enclosingClassName) {
- // We search for the token that has the name of this element.
- // For constructors, that doesn't work because they may have
- // named formed out of multiple tokens (named constructors) so
- // for those we search for the class name instead.
- String needle = isConstructor ? enclosingClassName : name;
- // The unary '-' operator has a special element name (specified).
- if (needle == 'unary-') needle = '-';
- for (Token t = token; Tokens.EOF_TOKEN != t.kind; t = t.next) {
- if (t is! ErrorToken && needle == t.lexeme) return t;
- }
- return token;
- }
-
- CompilationUnitElement get compilationUnit {
- Element element = this;
- while (!element.isCompilationUnit) {
- element = element.enclosingElement;
- }
- return element;
- }
-
- LibraryElement get library => enclosingElement.library;
-
- Name get memberName => new Name(name, library);
-
- LibraryElement get implementationLibrary {
- Element element = this;
- while (!identical(element.kind, ElementKind.LIBRARY)) {
- element = element.enclosingElement;
- }
- return element;
- }
-
- ClassElement get enclosingClass {
- for (Element e = this; e != null; e = e.enclosingElement) {
- if (e.isClass) return e.declaration;
- }
- return null;
- }
-
- /**
- * Creates the scope for this element.
- */
- Scope buildScope() => enclosingElement.buildScope();
-
- String toString() {
- // TODO(johnniwinther): Test for nullness of name, or make non-nullness an
- // invariant for all element types?
- var nameText = name != null ? name : '?';
- if (enclosingElement != null && !isTopLevel) {
- String holderName = enclosingElement.name != null
- ? enclosingElement.name
- : '${enclosingElement.kind}?';
- return '$kind($holderName#${nameText})';
- } else {
- return '$kind(${nameText})';
- }
- }
-
- FunctionElement asFunctionElement() => null;
-
- bool get isAbstract => modifiers.isAbstract;
-
- bool get hasTreeElements => analyzableElement.hasTreeElements;
-
- TreeElements get treeElements => analyzableElement.treeElements;
-
- AnalyzableElement get analyzableElement {
- Element element = outermostEnclosingMemberOrTopLevel;
- if (element.isAbstractField || element.isPrefix) return element.library;
- return element;
- }
-
- DeclarationSite get declarationSite => null;
-
- void reuseElement() {
- throw "reuseElement isn't implemented on ${runtimeType}.";
- }
-}
-
-class ErroneousElementX extends ElementX
- with ConstructorElementCommon
- implements ErroneousElement {
- final MessageKind messageKind;
- final Map messageArguments;
-
- ErroneousElementX(
- this.messageKind, this.messageArguments, String name, Element enclosing)
- : super(name, ElementKind.ERROR, enclosing);
-
- bool get isTopLevel => false;
-
- bool get isSynthesized => true;
-
- bool get isCyclicRedirection => false;
-
- bool get isDefaultConstructor => false;
-
- bool get isMalformed => true;
-
- PrefixElement get redirectionDeferredPrefix => null;
-
- AbstractFieldElement abstractField;
-
- unsupported() {
- throw 'unsupported operation on erroneous element';
- }
-
- get asyncMarker => AsyncMarker.SYNC;
- Iterable<MetadataAnnotation> get metadata => unsupported();
- bool get hasNode => false;
- get node => unsupported();
- get hasResolvedAst => false;
- get resolvedAst => unsupported();
- get type => unsupported();
- get cachedNode => unsupported();
- get functionSignature => unsupported();
- get parameterStructure => unsupported();
- get parameters => unsupported();
- FunctionElement get patch => null;
- FunctionElement get origin => this;
- get immediateRedirectionTarget => unsupported();
- get nestedClosures => unsupported();
- get memberContext => unsupported();
- get executableContext => unsupported();
- get isExternal => unsupported();
- get isMarkedExternal => unsupported();
- get constantConstructor => null;
-
- bool get isRedirectingGenerative => unsupported();
- bool get isRedirectingFactory => unsupported();
-
- computeType(Resolution resolution) => unsupported();
-
- bool get hasFunctionSignature => false;
-
- bool get hasEffectiveTarget => true;
-
- get effectiveTarget => this;
-
- computeEffectiveTargetType(ResolutionInterfaceType newType) => unsupported();
-
- get definingConstructor => null;
-
- FunctionElement asFunctionElement() => this;
-
- String get message {
- return MessageTemplate.TEMPLATES[messageKind]
- .message(messageArguments)
- .toString();
- }
-
- String toString() => '<$name: $message>';
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitErroneousElement(this, arg);
- }
-
- @override
- get isEffectiveTargetMalformed {
- throw new UnsupportedError("isEffectiveTargetMalformed");
- }
-
- @override
- List<ResolutionDartType> get typeVariables => unsupported();
-}
-
-/// A constructor that was synthesized to recover from a compile-time error.
-class ErroneousConstructorElementX extends ErroneousElementX
- with
- PatchMixin<FunctionElement>,
- AnalyzableElementX,
- ConstantConstructorMixin
- implements ConstructorElementX {
- // TODO(ahe): Instead of subclassing [ErroneousElementX], this class should
- // be more like [ErroneousFieldElementX]. In particular, its kind should be
- // [ElementKind.GENERATIVE_CONSTRUCTOR], and it shouldn't throw as much.
-
- ErroneousConstructorElementX(MessageKind messageKind, Map messageArguments,
- String name, Element enclosing)
- : super(messageKind, messageArguments, name, enclosing);
-
- @override
- bool get isRedirectingGenerative => false;
-
- @override
- bool isRedirectingGenerativeInternal;
-
- void set isRedirectingGenerative(_) {
- throw new UnsupportedError("isRedirectingGenerative");
- }
-
- @override
- bool get isRedirectingFactory => false;
-
- @override
- get isMarkedNative {
- throw new UnsupportedError("isMarkedNative");
- }
-
- @override
- set isMarkedNative(_) {
- throw new UnsupportedError("isMarkedNative=");
- }
-
- @override
- get definingElement {
- throw new UnsupportedError("definingElement");
- }
-
- @override
- get asyncMarker {
- throw new UnsupportedError("asyncMarker");
- }
-
- @override
- set asyncMarker(_) {
- throw new UnsupportedError("asyncMarker=");
- }
-
- @override
- get _asyncMarker {
- throw new UnsupportedError("_asyncMarker");
- }
-
- @override
- set _asyncMarker(_) {
- throw new UnsupportedError("_asyncMarker=");
- }
-
- @override
- get effectiveTargetInternal {
- throw new UnsupportedError("effectiveTargetInternal");
- }
-
- @override
- set effectiveTargetInternal(_) {
- throw new UnsupportedError("effectiveTargetInternal=");
- }
-
- @override
- get _effectiveTargetType {
- throw new UnsupportedError("_effectiveTargetType");
- }
-
- @override
- set _effectiveTargetType(_) {
- throw new UnsupportedError("_effectiveTargetType=");
- }
-
- @override
- get effectiveTargetType {
- throw new UnsupportedError("effectiveTargetType");
- }
-
- @override
- get _isEffectiveTargetMalformed {
- throw new UnsupportedError("_isEffectiveTargetMalformed");
- }
-
- @override
- set _isEffectiveTargetMalformed(_) {
- throw new UnsupportedError("_isEffectiveTargetMalformed=");
- }
-
- @override
- get isEffectiveTargetMalformed {
- throw new UnsupportedError("isEffectiveTargetMalformed");
- }
-
- @override
- void setEffectiveTarget(ConstructorElement target, ResolutionDartType type,
- {bool isMalformed: false}) {
- throw new UnsupportedError("setEffectiveTarget");
- }
-
- @override
- void _computeSignature(Resolution resolution) {
- throw new UnsupportedError("_computeSignature");
- }
-
- @override
- get typeCache {
- throw new UnsupportedError("typeCache");
- }
-
- @override
- set typeCache(_) {
- throw new UnsupportedError("typeCache=");
- }
-
- @override
- get immediateRedirectionTarget {
- throw new UnsupportedError("immediateRedirectionTarget");
- }
-
- @override
- get _immediateRedirectionTarget {
- throw new UnsupportedError("_immediateRedirectionTarget");
- }
-
- @override
- set _immediateRedirectionTarget(_) {
- throw new UnsupportedError("_immediateRedirectionTarget=");
- }
-
- @override
- setImmediateRedirectionTarget(a, b) {
- throw new UnsupportedError("setImmediateRedirectionTarget");
- }
-
- @override
- get _functionSignatureCache {
- throw new UnsupportedError("functionSignatureCache");
- }
-
- @override
- set _functionSignatureCache(_) {
- throw new UnsupportedError("functionSignatureCache=");
- }
-
- @override
- set functionSignature(_) {
- throw new UnsupportedError("functionSignature=");
- }
-
- @override
- get parameterStructure {
- throw new UnsupportedError("parameterStructure");
- }
-
- @override
- get nestedClosures {
- throw new UnsupportedError("nestedClosures");
- }
-
- @override
- set nestedClosures(_) {
- throw new UnsupportedError("nestedClosures=");
- }
-
- @override
- get _redirectionDeferredPrefix {
- throw new UnsupportedError("_redirectionDeferredPrefix");
- }
-
- @override
- set _redirectionDeferredPrefix(_) {
- throw new UnsupportedError("_redirectionDeferredPrefix=");
- }
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get declaration => super.declaration;
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get implementation => super.implementation;
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get origin => super.origin;
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get patch => super.patch;
-
- ResolutionFunctionType computeType(Resolution resolution) =>
- super.computeType(resolution);
-}
-
-/// A message attached to a [WarnOnUseElementX].
-class WrappedMessage {
- /// The message position. If [:null:] the position of the reference to the
- /// [WarnOnUseElementX] is used.
- final SourceSpan sourceSpan;
-
- /**
- * The message to report on resolving a wrapped element.
- */
- final MessageKind messageKind;
-
- /**
- * The message arguments to report on resolving a wrapped element.
- */
- final Map messageArguments;
-
- WrappedMessage(this.sourceSpan, this.messageKind, this.messageArguments);
-}
-
-class WarnOnUseElementX extends ElementX implements WarnOnUseElement {
- /// Warning to report on resolving this element.
- final WrappedMessage warning;
-
- /// Info to report on resolving this element.
- final WrappedMessage info;
-
- /// The element whose usage cause a warning.
- final Element wrappedElement;
-
- WarnOnUseElementX(
- this.warning, this.info, Element enclosingElement, Element wrappedElement)
- : this.wrappedElement = wrappedElement,
- super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement);
-
- Element unwrap(DiagnosticReporter reporter, Spannable usageSpannable) {
- dynamic unwrapped = wrappedElement;
- if (warning != null) {
- Spannable spannable = warning.sourceSpan;
- if (spannable == null) spannable = usageSpannable;
- DiagnosticMessage warningMessage = reporter.createMessage(
- spannable, warning.messageKind, warning.messageArguments);
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- if (info != null) {
- Spannable spannable = info.sourceSpan;
- if (spannable == null) spannable = usageSpannable;
- infos.add(reporter.createMessage(
- spannable, info.messageKind, info.messageArguments));
- }
- reporter.reportWarning(warningMessage, infos);
- }
- if (unwrapped.isWarnOnUse) {
- unwrapped = unwrapped.unwrap(reporter, usageSpannable);
- }
- return unwrapped;
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitWarnOnUseElement(this, arg);
- }
-}
-
-abstract class AmbiguousElementX extends ElementX implements AmbiguousElement {
- /**
- * The message to report on resolving this element.
- */
- final MessageKind messageKind;
-
- /**
- * The message arguments to report on resolving this element.
- */
- final Map messageArguments;
-
- /**
- * The first element that this ambiguous element might refer to.
- */
- final Element existingElement;
-
- /**
- * The second element that this ambiguous element might refer to.
- */
- final Element newElement;
-
- AmbiguousElementX(this.messageKind, this.messageArguments,
- Element enclosingElement, Element existingElement, Element newElement)
- : this.existingElement = existingElement,
- this.newElement = newElement,
- super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement);
-
- Setlet flatten() {
- Element element = this;
- var set = new Setlet();
- while (element.isAmbiguous) {
- AmbiguousElement ambiguous = element;
- set.add(ambiguous.newElement);
- element = ambiguous.existingElement;
- }
- set.add(element);
- return set;
- }
-
- List<DiagnosticMessage> computeInfos(
- Element context, DiagnosticReporter reporter) {
- return const <DiagnosticMessage>[];
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitAmbiguousElement(this, arg);
- }
-
- bool get isTopLevel => false;
-
- ResolutionDynamicType get type => const ResolutionDynamicType();
-}
-
-/// Element synthesized to diagnose an ambiguous import.
-class AmbiguousImportX extends AmbiguousElementX {
- AmbiguousImportX(MessageKind messageKind, Map messageArguments,
- Element enclosingElement, Element existingElement, Element newElement)
- : super(messageKind, messageArguments, enclosingElement, existingElement,
- newElement);
-
- List<DiagnosticMessage> computeInfos(
- Element context, DiagnosticReporter reporter) {
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- Setlet ambiguousElements = flatten();
- MessageKind code = (ambiguousElements.length == 1)
- ? MessageKind.AMBIGUOUS_REEXPORT
- : MessageKind.AMBIGUOUS_LOCATION;
- LibraryElementX importer = context.library;
- for (Element element in ambiguousElements) {
- Map arguments = {'name': element.name};
- infos.add(reporter.createMessage(element, code, arguments));
- reporter.withCurrentElement(importer, () {
- for (ImportElement import in importer.importers.getImports(element)) {
- infos.add(reporter.createMessage(
- import, MessageKind.IMPORTED_HERE, arguments));
- }
- });
- }
- return infos;
- }
-}
-
-/// Element synthesized to recover from a duplicated member of an element.
-class DuplicatedElementX extends AmbiguousElementX {
- DuplicatedElementX(MessageKind messageKind, Map messageArguments,
- Element enclosingElement, Element existingElement, Element newElement)
- : super(messageKind, messageArguments, enclosingElement, existingElement,
- newElement);
-
- bool get isMalformed => true;
-}
-
-class ScopeX {
- final Map<String, Element> contents = new Map<String, Element>();
-
- bool get isEmpty => contents.isEmpty;
- Iterable<Element> get values => contents.values;
-
- Element lookup(String name) {
- return contents[name];
- }
-
- void add(Element element, DiagnosticReporter reporter) {
- String name = element.name;
- if (element.isAccessor) {
- addAccessor(element, contents[name], reporter);
- } else {
- Element existing = contents.putIfAbsent(name, () => element);
- if (!identical(existing, element)) {
- reporter.reportError(
- reporter.createMessage(
- element, MessageKind.DUPLICATE_DEFINITION, {'name': name}),
- <DiagnosticMessage>[
- reporter.createMessage(
- existing, MessageKind.EXISTING_DEFINITION, {'name': name}),
- ]);
- }
- }
- }
-
- /**
- * Adds a definition for an [accessor] (getter or setter) to a scope.
- * The definition binds to an abstract field that can hold both a getter
- * and a setter.
- *
- * The abstract field is added once, for the first getter or setter, and
- * reused if the other one is also added.
- * The abstract field should not be treated as a proper member of the
- * container, it's simply a way to return two results for one lookup.
- * That is, the getter or setter does not have the abstract field as enclosing
- * element, they are enclosed by the class or compilation unit, as is the
- * abstract field.
- */
- void addAccessor(AccessorElementX accessor, Element existing,
- DiagnosticReporter reporter) {
- void reportError(Element other) {
- reporter.reportError(
- reporter.createMessage(accessor, MessageKind.DUPLICATE_DEFINITION,
- {'name': accessor.name}),
- <DiagnosticMessage>[
- reporter.createMessage(other, MessageKind.EXISTING_DEFINITION,
- {'name': accessor.name}),
- ]);
-
- contents[accessor.name] = new DuplicatedElementX(
- MessageKind.DUPLICATE_DEFINITION,
- {'name': accessor.name},
- accessor.memberContext.enclosingElement,
- other,
- accessor);
- }
-
- if (existing != null) {
- if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) {
- reportError(existing);
- return;
- } else {
- AbstractFieldElementX field = existing;
- accessor.abstractField = field;
- if (accessor.isGetter) {
- if (field.getter != null && field.getter != accessor) {
- reportError(field.getter);
- return;
- }
- field.getter = accessor;
- } else {
- assert(accessor.isSetter);
- if (field.setter != null && field.setter != accessor) {
- reportError(field.setter);
- return;
- }
- field.setter = accessor;
- }
- }
- } else {
- Element container = accessor.enclosingClassOrCompilationUnit;
- AbstractFieldElementX field =
- new AbstractFieldElementX(accessor.name, container);
- accessor.abstractField = field;
- if (accessor.isGetter) {
- field.getter = accessor;
- } else {
- field.setter = accessor;
- }
- add(field, reporter);
- }
- }
-}
-
-class CompilationUnitElementX extends ElementX
- with CompilationUnitElementCommon
- implements CompilationUnitElement {
- final Script script;
- PartOf partTag;
- Link<Element> localMembers = const Link<Element>();
-
- CompilationUnitElementX(Script script, LibraryElementX library)
- : this.script = script,
- super(script.name, ElementKind.COMPILATION_UNIT, library) {
- library.addCompilationUnit(this);
- }
-
- @override
- LibraryElementX get library => enclosingElement.declaration;
-
- void set metadata(List<MetadataAnnotation> metadata) {
- for (MetadataAnnotationX annotation in metadata) {
- assert(annotation.annotatedElement == null);
- annotation.annotatedElement = this;
- }
- // TODO(johnniwinther): Remove this work-around when import, export,
- // part, and part-of declarations are elements.
- if (metadataInternal == null) {
- metadataInternal = <MetadataAnnotation>[];
- }
- metadataInternal.addAll(metadata);
- }
-
- void forEachLocalMember(f(Element element)) {
- localMembers.forEach(f);
- }
-
- void addMember(Element element, DiagnosticReporter reporter) {
- // Keep a list of top level members.
- localMembers = localMembers.prepend(element);
- // Provide the member to the library to build scope.
- if (enclosingElement.isPatch) {
- LibraryElementX library = implementationLibrary;
- library.addMember(element, reporter);
- } else {
- library.addMember(element, reporter);
- }
- }
-
- 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;
- return;
- }
- if (!localMembers.isEmpty) {
- reporter.reportErrorMessage(tag, MessageKind.BEFORE_TOP_LEVEL);
- return;
- }
- if (partTag != null) {
- reporter.reportWarningMessage(tag, MessageKind.DUPLICATED_PART_OF);
- return;
- }
- partTag = tag;
- LibraryName libraryTag = library.libraryTag;
-
- Expression libraryReference = tag.name;
- if (libraryReference is LiteralString) {
- // Name is a URI. Resolve and compare to library's URI.
- String content = libraryReference.dartString.slowToString();
- Uri uri = this.script.readableUri.resolve(content);
- Uri expectedUri = library.canonicalUri;
- // Also allow `string.dart` to refer to `dart:core` as `core.dart`.
- if (library.isPlatformLibrary && !uri.isScheme("dart")) {
- expectedUri = library.entryCompilationUnit.script.readableUri;
- }
- if (uri != expectedUri) {
- // Consider finding a relative URI reference for the error message.
- reporter.reportWarningMessage(tag.name,
- MessageKind.LIBRARY_URI_MISMATCH, {'libraryUri': expectedUri});
- }
- return;
- }
- String actualName = tag.name.toString();
- if (libraryTag != null) {
- String expectedName = libraryTag.name.toString();
- if (expectedName != actualName) {
- reporter.reportWarningMessage(tag.name,
- MessageKind.LIBRARY_NAME_MISMATCH, {'libraryName': expectedName});
- }
- } else {
- reporter.reportWarning(
- reporter.createMessage(library, MessageKind.MISSING_LIBRARY_NAME,
- {'libraryName': actualName}),
- <DiagnosticMessage>[
- reporter.createMessage(
- tag.name, MessageKind.THIS_IS_THE_PART_OF_TAG),
- ]);
- }
- }
-
- bool get hasMembers => !localMembers.isEmpty;
-
- AnalyzableElement get analyzableElement => library;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitCompilationUnitElement(this, arg);
- }
-}
-
-/// Map from [Element] to the [ImportElement]s throught which it was imported.
-///
-/// This is used for error reporting and deferred loading.
-class Importers {
- Map<Element, List<ImportElement>> importers =
- new Map<Element, List<ImportElement>>();
-
- /// Returns the list of [ImportElement]s through which [element] was
- /// imported.
- List<ImportElement> getImports(Element element) {
- List<ImportElement> imports = importers[element];
- return imports != null ? imports : const <ImportElement>[];
- }
-
- /// Returns the first [ImportElement] through which [element] was imported.
- ImportElement getImport(Element element) => getImports(element).first;
-
- /// Register [element] as imported through [import];
- void registerImport(Element element, ImportElement import) {
- importers.putIfAbsent(element, () => <ImportElement>[]).add(import);
- }
-}
-
-class ImportScope {
- /**
- * Map for elements imported through import declarations.
- *
- * Addition to the map is performed by [addImport]. Lookup is done trough
- * [find].
- */
- final Map<String, Element> importScope = new Map<String, Element>();
-
- /**
- * Adds [element] to the import scope of this library.
- *
- * If an element by the same name is already in the imported scope, an
- * [ErroneousElement] will be put in the imported scope, allowing for
- * detection of ambiguous uses of imported names.
- */
- void addImport(Element enclosingElement, Element element,
- ImportElement import, DiagnosticReporter reporter) {
- LibraryElementX library = enclosingElement.library;
- Importers importers = library.importers;
-
- String name = element.name;
-
- // The loadLibrary function always shadows existing bindings to that name.
- if (element.isDeferredLoaderGetter) {
- importScope.remove(name);
- // TODO(sigurdm): Print a hint.
- }
- Element existing = importScope.putIfAbsent(name, () => element);
- importers.registerImport(element, import);
-
- void registerWarnOnUseElement(ImportElement import, MessageKind messageKind,
- Element hidingElement, Element hiddenElement) {
- Uri hiddenUri = hiddenElement.library.canonicalUri;
- Uri hidingUri = hidingElement.library.canonicalUri;
- Element element = new WarnOnUseElementX(
- new WrappedMessage(
- null, // Report on reference to [hidingElement].
- messageKind,
- {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}),
- new WrappedMessage(reporter.spanFromSpannable(import),
- MessageKind.IMPORTED_HERE, {'name': name}),
- enclosingElement,
- hidingElement);
- importScope[name] = element;
- importers.registerImport(element, import);
- }
-
- if (existing != element) {
- ImportElement existingImport = importers.getImport(existing);
- if (existing.library.isPlatformLibrary &&
- !element.library.isPlatformLibrary) {
- // [existing] is implicitly hidden.
- registerWarnOnUseElement(
- import, MessageKind.HIDDEN_IMPORT, element, existing);
- } else if (!existing.library.isPlatformLibrary &&
- element.library.isPlatformLibrary) {
- // [element] is implicitly hidden.
- if (import.isSynthesized) {
- // [element] is imported implicitly (probably through dart:core).
- registerWarnOnUseElement(existingImport,
- MessageKind.HIDDEN_IMPLICIT_IMPORT, existing, element);
- } else {
- registerWarnOnUseElement(
- import, MessageKind.HIDDEN_IMPORT, existing, element);
- }
- } else {
- Element ambiguousElement = new AmbiguousImportX(
- MessageKind.DUPLICATE_IMPORT,
- {'name': name},
- enclosingElement,
- existing,
- element);
- importScope[name] = ambiguousElement;
- importers.registerImport(ambiguousElement, import);
- importers.registerImport(ambiguousElement, existingImport);
- }
- }
- }
-
- Element operator [](String name) => importScope[name];
-
- void forEach(f(Element element)) => importScope.values.forEach(f);
-}
-
-abstract class LibraryDependencyElementX extends ElementX {
- final LibraryDependency node;
- final Uri uri;
- LibraryElement libraryDependency;
-
- LibraryDependencyElementX(CompilationUnitElement enclosingElement,
- ElementKind kind, this.node, this.uri)
- : super('', kind, enclosingElement);
-
- @override
- List<MetadataAnnotation> get metadata => node.metadata;
-
- void set metadata(value) {
- // The metadata is stored on [libraryDependency].
- failedAt(this, 'Cannot set metadata on a import/export.');
- }
-
- @override
- Token get position => node.getBeginToken();
-
- SourceSpan get sourcePosition {
- return new SourceSpan.fromNode(compilationUnit.script.resourceUri, node);
- }
-
- String toString() => '$kind($uri)';
-}
-
-class ImportElementX extends LibraryDependencyElementX
- implements ImportElement {
- PrefixElementX prefix;
-
- ImportElementX(CompilationUnitElement enclosingElement, Import node, Uri uri)
- : super(enclosingElement, ElementKind.IMPORT, node, uri);
-
- @override
- Import get node => super.node;
-
- @override
- LibraryElement get enclosingLibrary => library;
-
- @override
- LibraryElement get importedLibrary => libraryDependency;
-
- @override
- accept(ElementVisitor visitor, arg) => visitor.visitImportElement(this, arg);
-
- @override
- bool get isDeferred => node.isDeferred;
-
- @override
- String get name => prefix?.name;
-}
-
-class SyntheticImportElement extends ImportElementX {
- SyntheticImportElement(CompilationUnitElement enclosingElement, Uri uri,
- LibraryElement libraryDependency)
- : super(enclosingElement, null, uri) {
- this.libraryDependency = libraryDependency;
- }
-
- @override
- Token get position => library.position;
-
- @override
- bool get isSynthesized => true;
-
- @override
- bool get isDeferred => false;
-
- @override
- List<MetadataAnnotation> get metadata => const <MetadataAnnotation>[];
-
- @override
- SourceSpan get sourcePosition => library.sourcePosition;
-}
-
-class ExportElementX extends LibraryDependencyElementX
- implements ExportElement {
- ExportElementX(CompilationUnitElement enclosingElement, Export node, Uri uri)
- : super(enclosingElement, ElementKind.EXPORT, node, uri);
-
- Export get node => super.node;
-
- @override
- LibraryElement get exportedLibrary => libraryDependency;
-
- @override
- accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg);
-}
-
-class LibraryElementX extends ElementX
- with LibraryElementCommon, AnalyzableElementX, PatchMixin<LibraryElementX>
- implements LibraryElement {
- final Uri canonicalUri;
-
- /// True if the constructing script was synthesized.
- final bool isSynthesized;
-
- CompilationUnitElement entryCompilationUnit;
- Link<CompilationUnitElement> compilationUnits =
- const Link<CompilationUnitElement>();
- LinkBuilder<LibraryTag> tagsBuilder = new LinkBuilder<LibraryTag>();
- List<LibraryTag> tagsCache;
- LibraryName libraryTag;
- Link<Element> localMembers = const Link<Element>();
- final ScopeX localScope = new ScopeX();
- final ImportScope importScope = new ImportScope();
-
- /// A mapping from an imported element to the "import" tag.
- final Importers importers = new Importers();
-
- /**
- * Link for elements exported either through export declarations or through
- * declaration. This field should not be accessed directly but instead through
- * the [exports] getter.
- *
- * [LibraryDependencyHandler] sets this field through [setExports] when the
- * library is loaded.
- */
- Link<Element> slotForExports;
-
- List<ImportElement> _imports = <ImportElement>[];
- List<ExportElement> _exports = <ExportElement>[];
-
- final Map<LibraryDependency, LibraryElement> tagMapping =
- new Map<LibraryDependency, LibraryElement>();
-
- final Map<String, MixinApplicationElementX> mixinApplicationCache =
- <String, MixinApplicationElementX>{};
-
- LibraryElementX(Script script, [Uri canonicalUri, LibraryElementX origin])
- : this.canonicalUri =
- ((canonicalUri == null) ? script.readableUri : canonicalUri),
- this.isSynthesized = script.isSynthesized,
- super(script.name, ElementKind.LIBRARY, null) {
- entryCompilationUnit = new CompilationUnitElementX(script, this);
- if (origin != null) {
- origin.applyPatch(this);
- }
- }
-
- Iterable<MetadataAnnotation> get metadata {
- if (libraryTag != null) {
- return libraryTag.metadata;
- }
- return const <MetadataAnnotation>[];
- }
-
- void set metadata(value) {
- // The metadata is stored on [libraryTag].
- failedAt(this, 'Cannot set metadata on Library');
- }
-
- CompilationUnitElement get compilationUnit => entryCompilationUnit;
-
- AnalyzableElement get analyzableElement => this;
-
- void addCompilationUnit(CompilationUnitElement element) {
- compilationUnits = compilationUnits.prepend(element);
- }
-
- void addTag(LibraryTag tag, DiagnosticReporter reporter) {
- if (tagsCache != null) {
- reporter.internalError(
- tag, "Library tags for $this have already been computed.");
- }
- tagsBuilder.addLast(tag);
- }
-
- Iterable<LibraryTag> get tags {
- if (tagsCache == null) {
- tagsCache = tagsBuilder.toList();
- tagsBuilder = null;
- }
- return tagsCache;
- }
-
- void addImportDeclaration(ImportElement import) {
- _imports.add(import);
- }
-
- Iterable<ImportElement> get imports => _imports;
-
- void addExportDeclaration(ExportElement export) {
- _exports.add(export);
- }
-
- Iterable<ExportElement> get exports => _exports;
-
- /**
- * Adds [element] to the import scope of this library.
- *
- * If an element by the same name is already in the imported scope, an
- * [ErroneousElement] will be put in the imported scope, allowing for
- * detection of ambiguous uses of imported names.
- */
- void addImport(
- Element element, ImportElement import, DiagnosticReporter reporter) {
- importScope.addImport(this, element, import, reporter);
- }
-
- void addMember(Element element, DiagnosticReporter reporter) {
- localMembers = localMembers.prepend(element);
- addToScope(element, reporter);
- }
-
- void addToScope(Element element, DiagnosticReporter reporter) {
- localScope.add(element, reporter);
- }
-
- Element localLookup(String elementName) {
- Element result = localScope.lookup(elementName);
- if (result == null && isPatch) {
- result = origin.localLookup(elementName);
- }
- return result;
- }
-
- /**
- * Returns [:true:] if the export scope has already been computed for this
- * library.
- */
- bool get exportsHandled => slotForExports != null;
-
- /**
- * Sets the export scope of this library. This method can only be called once.
- */
- void setExports(Iterable<Element> exportedElements) {
- assert(!exportsHandled,
- failedAt(this, 'Exports already set to $slotForExports on $this'));
- assert(exportedElements != null, failedAt(this));
- var builder = new LinkBuilder<Element>();
- for (Element export in exportedElements) {
- builder.addLast(export);
- }
- slotForExports = builder.toLink();
- }
-
- LibraryElement get library => isPatch ? origin : this;
-
- /**
- * Look up a top-level element in this library. The element could
- * potentially have been imported from another library. Returns
- * null if no such element exist and an [ErroneousElement] if multiple
- * elements have been imported.
- */
- Element find(String elementName) {
- Element result = localScope.lookup(elementName);
- if (result != null) return result;
- if (origin != null) {
- result = origin.localScope.lookup(elementName);
- if (result != null) return result;
- }
- result = importScope[elementName];
- if (result != null) return result;
- if (origin != null) {
- result = origin.importScope[elementName];
- if (result != null) return result;
- }
- return null;
- }
-
- /** Look up a top-level element in this library, but only look for
- * non-imported elements. Returns null if no such element exist. */
- Element findLocal(String elementName) {
- // TODO((johnniwinther): How to handle injected elements in the patch
- // library?
- Element result = localScope.lookup(elementName);
- if (result == null && isPatch) {
- return origin.findLocal(elementName);
- }
- return result;
- }
-
- Element findExported(String elementName) {
- assert(exportsHandled, failedAt(this, 'Exports not handled on $this'));
- for (Link link = slotForExports; !link.isEmpty; link = link.tail) {
- Element element = link.head;
- if (element.name == elementName) return element;
- }
- return null;
- }
-
- void forEachExport(f(Element element)) {
- assert(exportsHandled, failedAt(this, 'Exports not handled on $this'));
- slotForExports.forEach((Element e) => f(e));
- }
-
- Iterable<ImportElement> getImportsFor(Element element) {
- return importers.getImports(element);
- }
-
- void forEachImport(f(Element element)) => importScope.forEach(f);
-
- void forEachLocalMember(f(Element element)) {
- if (isPatch) {
- // Patch libraries traverse both origin and injected members.
- origin.localMembers.forEach(f);
-
- void filterPatch(Element element) {
- if (!element.isPatch) {
- // Do not traverse the patch members.
- f(element);
- }
- }
-
- localMembers.forEach(filterPatch);
- } else {
- localMembers.forEach(f);
- }
- }
-
- Iterable<Element> getNonPrivateElementsInScope() {
- return localScope.values.where((Element element) {
- // At this point [localScope] only contains members so we don't need
- // to check for foreign or prefix elements.
- return !Name.isPrivateName(element.name);
- });
- }
-
- bool get hasLibraryName => libraryTag != null;
-
- String get libraryName {
- if (libraryTag == null) return '';
- return libraryTag.name.toString();
- }
-
- Scope buildScope() => new LibraryScope(this);
-
- String toString() {
- if (origin != null) {
- return 'patch library(${canonicalUri})';
- } else if (patch != null) {
- return 'origin library(${canonicalUri})';
- } else {
- return 'library(${canonicalUri})';
- }
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitLibraryElement(this, arg);
- }
-
- // TODO(johnniwinther): Remove this.
- LibraryElementX get declaration => super.declaration;
-
- // TODO(johnniwinther): Remove this.
- LibraryElementX get implementation => super.implementation;
-
- // TODO(johnniwinther): Remove this.
- LibraryElementX get origin => super.origin;
-
- // TODO(johnniwinther): Remove this.
- LibraryElementX get patch => super.patch;
-}
-
-class PrefixElementX extends ElementX implements PrefixElement {
- Token firstPosition;
-
- final ImportScope importScope = new ImportScope();
-
- bool get isDeferred => deferredImport != null;
-
- // Only needed for deferred imports.
- final ImportElement deferredImport;
-
- PrefixElementX(
- String prefix, Element enclosing, this.firstPosition, this.deferredImport)
- : super(prefix, ElementKind.PREFIX, enclosing);
-
- bool get isTopLevel => false;
-
- Element lookupLocalMember(String memberName) => importScope[memberName];
-
- void forEachLocalMember(f(Element member)) => importScope.forEach(f);
-
- ResolutionDartType computeType(Resolution resolution) =>
- const ResolutionDynamicType();
-
- Token get position => firstPosition;
-
- void addImport(
- Element element, ImportElement import, DiagnosticReporter reporter) {
- importScope.addImport(this, element, import, reporter);
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitPrefixElement(this, arg);
- }
-
- @override
- GetterElement get loadLibrary {
- return isDeferred ? lookupLocalMember(Identifiers.loadLibrary) : null;
- }
-
- String toString() => '$kind($name)';
-}
-
-class TypedefElementX extends ElementX
- with AstElementMixin, AnalyzableElementX, TypeDeclarationElementX
- implements TypedefElement {
- Typedef cachedNode;
-
- /**
- * The type annotation which defines this typedef.
- */
- ResolutionDartType aliasCache;
-
- ResolutionDartType get alias {
- assert(hasBeenCheckedForCycles,
- failedAt(this, "$this has not been checked for cycles."));
- return aliasCache;
- }
-
- /// [:true:] if the typedef has been checked for cyclic reference.
- bool hasBeenCheckedForCycles = false;
-
- int resolutionState = STATE_NOT_STARTED;
-
- TypedefElementX(String name, Element enclosing)
- : super(name, ElementKind.TYPEDEF, enclosing);
-
- bool get hasNode => cachedNode != null;
-
- Typedef get node {
- assert(cachedNode != null,
- failedAt(this, "Node has not been computed for $this."));
- return cachedNode;
- }
-
- /**
- * Function signature for a typedef of a function type. The signature is
- * kept to provide full information about parameter names through the mirror
- * system.
- *
- * The [functionSignature] is not available until the typedef element has been
- * resolved.
- */
- FunctionSignature functionSignature;
-
- ResolutionTypedefType computeType(Resolution resolution) {
- if (thisTypeCache != null) return thisTypeCache;
- Typedef node = parseNode(resolution.parsingContext);
- setThisAndRawTypes(createTypeVariables(node.templateParameters));
- ensureResolved(resolution);
- return thisTypeCache;
- }
-
- void ensureResolved(Resolution resolution) {
- if (resolutionState == STATE_NOT_STARTED) {
- resolution.resolveTypedef(this);
- }
- }
-
- ResolutionTypedefType createType(List<ResolutionDartType> typeArguments) {
- return new ResolutionTypedefType(this, typeArguments);
- }
-
- Scope buildScope() {
- return new TypeDeclarationScope(enclosingElement.buildScope(), this);
- }
-
- void checkCyclicReference(Resolution resolution) {
- if (hasBeenCheckedForCycles) return;
- TypedefCyclicVisitor visitor =
- new TypedefCyclicVisitor(resolution.reporter, this);
- computeType(resolution).accept(visitor, null);
- hasBeenCheckedForCycles = true;
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitTypedefElement(this, arg);
- }
-
- // A typedef cannot be patched therefore defines itself.
- AstElement get definingElement => this;
-
- ResolutionTypedefType get thisType => super.thisType;
-
- ResolutionTypedefType get rawType => super.rawType;
-}
-
-// This class holds common information for a list of variable or field
-// declarations. It contains the node, and the type. A [VariableElementX]
-// forwards its [computeType] and [parseNode] methods to this class.
-class VariableList implements DeclarationSite {
- VariableDefinitions definitions;
- ResolutionDartType type;
- final Modifiers modifiers;
- List<MetadataAnnotation> metadataInternal;
-
- VariableList(Modifiers this.modifiers);
-
- VariableList.node(VariableDefinitions node, this.type)
- : this.definitions = node,
- this.modifiers = node.modifiers {
- assert(modifiers != null);
- }
-
- Iterable<MetadataAnnotation> get metadata {
- return metadataInternal != null
- ? metadataInternal
- : const <MetadataAnnotation>[];
- }
-
- void set metadata(List<MetadataAnnotation> metadata) {
- if (metadata.isEmpty) {
- // For a multi declaration like:
- //
- // @foo @bar var a, b, c
- //
- // the metadata list is reported through the declaration of `a`, and `b`
- // and `c` report an empty list of metadata.
- return;
- }
- assert(metadataInternal == null);
- metadataInternal = metadata;
- }
-
- VariableDefinitions parseNode(Element element, ParsingContext parsing) {
- return definitions;
- }
-
- ResolutionDartType computeType(Element element, Resolution resolution) =>
- type;
-}
-
-abstract class ConstantVariableMixin implements VariableElement {
- ConstantExpression constantCache;
-
- // TODO(johnniwinther): Update the on `constant = ...` when evaluation of
- // constant expression can handle references to unanalyzed constant variables.
- @override
- bool get hasConstant => false;
-
- ConstantExpression get constant {
- if (isPatch) {
- ConstantVariableMixin originVariable = origin;
- return originVariable.constant;
- }
- assert(!isConst || constantCache != null,
- failedAt(this, "Constant has not been computed for $this."));
- return constantCache;
- }
-
- void set constant(ConstantExpression value) {
- if (isPatch) {
- ConstantVariableMixin originVariable = origin;
- originVariable.constant = value;
- return;
- }
- if (constantCache != null &&
- constantCache.kind == ConstantExpressionKind.ERRONEOUS) {
- // TODO(johnniwinther): Find out why we sometimes compute a non-erroneous
- // constant for a variable already known to be erroneous.
- return;
- }
- if (constantCache != null && constantCache != value) {
- // Allow setting the constant as erroneous. Constants computed during
- // resolution are locally valid but might be effectively erroneous. For
- // instance `a ? true : false` where a is `const a = m()`. Since `a` is
- // declared to be constant, the conditional is assumed valid, but when
- // computing the value we see that it isn't.
- // TODO(johnniwinther): Remove this exception when all constant
- // expressions are computed during resolution.
- assert(
- value == null || value.kind == ConstantExpressionKind.ERRONEOUS,
- failedAt(
- this,
- "Constant has already been computed for $this. "
- "Existing constant: "
- "${constantCache != null ? constantCache.toStructuredText() : ''}"
- ", New constant: "
- "${value != null ? value.toStructuredText() : ''}."));
- }
- constantCache = value;
- }
-}
-
-abstract class VariableElementX extends ElementX
- with AstElementMixin, ConstantVariableMixin
- implements VariableElement {
- final Token token;
- final VariableList variables;
- VariableDefinitions definitionsCache;
- Expression definitionCache;
- Expression initializerCache;
-
- Modifiers get modifiers => variables.modifiers;
-
- VariableElementX(String name, ElementKind kind, Element enclosingElement,
- VariableList variables, this.token)
- : this.variables = variables,
- super(name, kind, enclosingElement);
-
- // TODO(johnniwinther): Ensure that the [TreeElements] for this variable hold
- // the mappings for all its metadata.
- Iterable<MetadataAnnotation> get metadata => variables.metadata;
-
- void set metadata(List<MetadataAnnotation> metadata) {
- for (MetadataAnnotationX annotation in metadata) {
- assert(annotation.annotatedElement == null);
- annotation.annotatedElement = this;
- }
- variables.metadata = metadata;
- }
-
- // A variable cannot be patched therefore defines itself.
- AstElement get definingElement => this;
-
- bool get hasNode => definitionsCache != null;
-
- VariableDefinitions get node {
- assert(definitionsCache != null,
- failedAt(this, "Node has not been computed for $this."));
- return definitionsCache;
- }
-
- /// Returns the node that defines this field.
- ///
- /// For instance in `var a, b = true`, the definitions nodes for fields 'a'
- /// and 'b' are the nodes for `a` and `b = true`, respectively.
- Expression get definition {
- assert(definitionCache != null,
- failedAt(this, "Definition node has not been computed for $this."));
- return definitionCache;
- }
-
- Expression get initializer {
- assert(definitionsCache != null,
- failedAt(this, "Initializer has not been computed for $this."));
- return initializerCache;
- }
-
- Node parseNode(ParsingContext parsing) {
- if (definitionsCache != null) return definitionsCache;
-
- VariableDefinitions definitions = variables.parseNode(this, parsing);
- createDefinitions(definitions);
- return definitionsCache;
- }
-
- void createDefinitions(VariableDefinitions definitions) {
- assert(
- definitionsCache == null,
- failedAt(
- this, "VariableDefinitions has already been computed for $this."));
- for (Link<Node> link = definitions.definitions.nodes;
- !link.isEmpty;
- link = link.tail) {
- Expression initializedIdentifier = link.head;
- Identifier identifier = initializedIdentifier.asIdentifier();
- if (identifier == null) {
- SendSet sendSet = initializedIdentifier.asSendSet();
- identifier = sendSet.selector.asIdentifier();
- if (identical(name, identifier.source)) {
- definitionCache = initializedIdentifier;
- initializerCache = sendSet.arguments.first;
- }
- } else if (identical(name, identifier.source)) {
- definitionCache = initializedIdentifier;
- }
- }
- if (definitionCache == null) {
- failedAt(definitionCache, "Could not find '$name'.");
- }
- definitionsCache = definitions;
- }
-
- ResolutionDartType computeType(Resolution resolution) {
- if (variables.type != null) return variables.type;
- // Call [parseNode] to ensure that [definitionsCache] and [initializerCache]
- // are set as a consequence of calling [computeType].
- parseNode(resolution.parsingContext);
- return variables.computeType(this, resolution);
- }
-
- ResolutionDartType get type {
- assert(variables.type != null,
- failedAt(this, "Type has not been computed for $this."));
- return variables.type;
- }
-
- bool get isInstanceMember => isClassMember && !isStatic;
-
- // Note: cachedNode.beginToken will not be correct in all
- // cases, for example, for function typed parameters.
- Token get position => token;
-
- DeclarationSite get declarationSite => variables;
-}
-
-class LocalVariableElementX extends VariableElementX
- implements LocalVariableElement {
- LocalVariableElementX(String name, ExecutableElement enclosingElement,
- VariableList variables, Token token)
- : super(name, ElementKind.VARIABLE, enclosingElement, variables, token) {
- createDefinitions(variables.definitions);
- }
-
- ExecutableElement get executableContext => enclosingElement;
-
- MemberElement get memberContext => executableContext.memberContext;
-
- bool get isLocal => true;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitLocalVariableElement(this, arg);
- }
-}
-
-class FieldElementX extends VariableElementX
- with AnalyzableElementX
- implements FieldElement {
- List<MethodElement> nestedClosures = new List<MethodElement>();
-
- FieldElementX(
- Identifier name, Element enclosingElement, VariableList variables)
- : super(name.source, ElementKind.FIELD, enclosingElement, variables,
- name.token);
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitFieldElement(this, arg);
- }
-
- MemberElement get memberContext => this;
-
- void reuseElement() {
- super.reuseElement();
- nestedClosures.clear();
- }
-
- FieldElementX copyWithEnclosing(Element enclosingElement) {
- return new FieldElementX(
- new Identifier(token), enclosingElement, variables);
- }
-}
-
-/// A field that was synthesized to recover from a compile-time error.
-class ErroneousFieldElementX extends ElementX
- with ConstantVariableMixin
- implements FieldElementX {
- final VariableList variables;
-
- ErroneousFieldElementX(Identifier name, Element enclosingElement)
- : variables = new VariableList(Modifiers.EMPTY)
- ..definitions = new VariableDefinitions(
- null, Modifiers.EMPTY, new NodeList.singleton(name))
- ..type = const ResolutionDynamicType(),
- super(name.source, ElementKind.FIELD, enclosingElement);
-
- VariableDefinitions get definitionsCache => variables.definitions;
-
- set definitionsCache(VariableDefinitions _) {
- throw new UnsupportedError("definitionsCache=");
- }
-
- bool get hasNode => true;
-
- VariableDefinitions get node => definitionsCache;
-
- bool get hasResolvedAst => false;
-
- ResolvedAst get resolvedAst {
- throw new UnsupportedError("resolvedAst");
- }
-
- ResolutionDynamicType get type => const ResolutionDynamicType();
-
- Token get token => node.getBeginToken();
-
- get definitionCache {
- throw new UnsupportedError("definitionCache");
- }
-
- set definitionCache(_) {
- throw new UnsupportedError("definitionCache=");
- }
-
- get initializerCache {
- throw new UnsupportedError("initializerCache");
- }
-
- set initializerCache(_) {
- throw new UnsupportedError("initializerCache=");
- }
-
- void createDefinitions(VariableDefinitions definitions) {
- throw new UnsupportedError("createDefinitions");
- }
-
- get initializer => null;
-
- get definition => null;
-
- bool get isMalformed => true;
-
- get nestedClosures {
- throw new UnsupportedError("nestedClosures");
- }
-
- set nestedClosures(_) {
- throw new UnsupportedError("nestedClosures=");
- }
-
- // TODO(ahe): Should this throw or do nothing?
- accept(ElementVisitor visitor, arg) {
- return visitor.visitFieldElement(this, arg);
- }
-
- // TODO(ahe): Should return the context of the error site?
- MemberElement get memberContext => this;
-
- // TODO(ahe): Should return the definingElement of the error site?
- AstElement get definingElement => this;
-
- void reuseElement() {
- throw new UnsupportedError("reuseElement");
- }
-
- FieldElementX copyWithEnclosing(Element enclosingElement) {
- throw new UnsupportedError("copyWithEnclosing");
- }
-
- ResolutionDartType computeType(Resolution resolution) => type;
-}
-
-/// [Element] for a parameter-like element.
-class FormalElementX extends ElementX
- with AstElementMixin
- implements FormalElement {
- final VariableDefinitions definitions;
- final Identifier identifier;
- ResolutionDartType typeCache;
-
- @override
- List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-
- /**
- * Function signature for a variable with a function type. The signature is
- * kept to provide full information about parameter names through the mirror
- * system.
- */
- FunctionSignature _functionSignatureCache;
-
- FormalElementX(ElementKind elementKind, FunctionTypedElement enclosingElement,
- this.definitions, Identifier identifier)
- : this.identifier = identifier,
- super(identifier.source, elementKind, enclosingElement);
-
- FormalElementX.unnamed(ElementKind elementKind,
- FunctionTypedElement enclosingElement, this.definitions)
- : this.identifier = null,
- super("<unnamed>", elementKind, enclosingElement);
-
- /// Whether this is an unnamed parameter in a Function type.
- bool get isUnnamed => identifier == null;
-
- FunctionTypedElement get functionDeclaration => enclosingElement;
-
- Modifiers get modifiers => definitions.modifiers;
-
- Token get position => identifier.getBeginToken();
-
- Node parseNode(ParsingContext parsing) => definitions;
-
- ResolutionDartType computeType(Resolution resolution) {
- assert(type != null,
- failedAt(this, "Parameter type has not been set for $this."));
- return type;
- }
-
- ResolutionDartType get type {
- assert(typeCache != null,
- failedAt(this, "Parameter type has not been set for $this."));
- return typeCache;
- }
-
- FunctionSignature get functionSignature {
- assert(_functionSignatureCache != null,
- failedAt(this, "Parameter signature has not been computed for $this."));
- return _functionSignatureCache;
- }
-
- void set functionSignature(FunctionSignature value) {
- assert(
- _functionSignatureCache == null,
- failedAt(
- this, "Parameter signature has already been computed for $this."));
- _functionSignatureCache = value;
- typeCache = _functionSignatureCache.type;
- }
-
- bool get hasNode => true;
-
- VariableDefinitions get node => definitions;
-
- ResolutionFunctionType get functionType => type;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitFormalElement(this, arg);
- }
-
- // A parameter is defined by the declaration element.
- AstElement get definingElement => declaration;
-}
-
-/// [Element] for a formal parameter.
-///
-/// A [ParameterElementX] can be patched. A parameter of an external method is
-/// patched with the corresponding parameter of the patch method. This is done
-/// to ensure that default values on parameters are computed once (on the
-/// origin parameter) but can be found through both the origin and the patch.
-abstract class ParameterElementX extends FormalElementX
- with PatchMixin<ParameterElement>, ConstantVariableMixin
- implements ParameterElement {
- final Expression initializer;
- final bool isOptional;
- final bool isNamed;
-
- ParameterElementX(
- ElementKind elementKind,
- FunctionElement functionDeclaration,
- VariableDefinitions definitions,
- Identifier identifier,
- this.initializer,
- {this.isOptional: false,
- this.isNamed: false})
- : super(elementKind, functionDeclaration, definitions, identifier);
-
- FunctionElement get functionDeclaration => enclosingElement;
-
- ExecutableElement get executableContext => enclosingElement;
-
- MemberElement get memberContext => executableContext.memberContext;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitParameterElement(this, arg);
- }
-
- bool get isLocal => true;
-
- String toString() {
- if (isPatched) {
- return 'origin ${super.toString()}';
- } else if (isPatch) {
- return 'patch ${super.toString()}';
- }
- return super.toString();
- }
-}
-
-class LocalParameterElementX extends ParameterElementX
- implements LocalParameterElement {
- LocalParameterElementX(
- FunctionElement functionDeclaration,
- VariableDefinitions definitions,
- Identifier identifier,
- Expression initializer,
- {bool isOptional: false,
- bool isNamed: false})
- : super(ElementKind.PARAMETER, functionDeclaration, definitions,
- identifier, initializer,
- isOptional: isOptional, isNamed: isNamed);
-}
-
-/// Parameters in constructors that directly initialize fields. For example:
-/// `A(this.field)`.
-class InitializingFormalElementX extends ParameterElementX
- implements InitializingFormalElement {
- final FieldElement fieldElement;
-
- InitializingFormalElementX(
- ConstructorElement constructorDeclaration,
- VariableDefinitions variables,
- Identifier identifier,
- Expression initializer,
- this.fieldElement,
- {bool isOptional: false,
- bool isNamed: false})
- : super(ElementKind.INITIALIZING_FORMAL, constructorDeclaration,
- variables, identifier, initializer,
- isOptional: isOptional, isNamed: isNamed);
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitFieldParameterElement(this, arg);
- }
-
- MemberElement get memberContext => enclosingElement;
-
- @override
- bool get isFinal => true;
-
- @override
- bool get isLocal => true;
-
- ConstructorElement get functionDeclaration => super.functionDeclaration;
-}
-
-// ignore: strong_mode_invalid_method_override_from_base
-class ErroneousInitializingFormalElementX extends ParameterElementX
- implements InitializingFormalElementX {
- final ErroneousFieldElementX fieldElement;
-
- ErroneousInitializingFormalElementX(
- Identifier identifier, Element enclosingElement)
- : this.fieldElement =
- new ErroneousFieldElementX(identifier, enclosingElement),
- super(ElementKind.INITIALIZING_FORMAL, enclosingElement, null,
- identifier, null);
-
- VariableDefinitions get definitions => fieldElement.node;
-
- MemberElement get memberContext => enclosingElement;
-
- bool get isLocal => false;
-
- bool get isMalformed => true;
-
- ResolutionDynamicType get type => const ResolutionDynamicType();
-
- ConstructorElement get functionDeclaration => super.functionDeclaration;
-}
-
-class AbstractFieldElementX extends ElementX
- with AbstractFieldElementCommon
- implements AbstractFieldElement {
- GetterElementX getter;
- SetterElementX setter;
-
- AbstractFieldElementX(String name, Element enclosing)
- : super(name, ElementKind.ABSTRACT_FIELD, enclosing);
-
- ResolutionDartType computeType(Compiler compiler) {
- throw "internal error: AbstractFieldElement has no type";
- }
-
- Node parseNode(ParsingContext parsing) {
- throw "internal error: AbstractFieldElement has no node";
- }
-
- Token get position {
- // The getter and setter may be defined in two different
- // compilation units. However, we know that one of them is
- // non-null and defined in the same compilation unit as the
- // abstract element.
- // TODO(lrn): No we don't know that if the element from the same
- // compilation unit is patched.
- //
- // We need to make sure that the position returned is relative to
- // the compilation unit of the abstract element.
- if (getter != null && identical(getter.compilationUnit, compilationUnit)) {
- return getter.position;
- } else {
- return setter.position;
- }
- }
-
- Modifiers get modifiers {
- // The resolver ensures that the flags match (ignoring abstract).
- if (getter != null) {
- return new Modifiers.withFlags(getter.modifiers.nodes,
- getter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
- } else {
- return new Modifiers.withFlags(setter.modifiers.nodes,
- setter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
- }
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitAbstractFieldElement(this, arg);
- }
-}
-
-// TODO(johnniwinther): [FunctionSignature] should be merged with
-// [FunctionType].
-class FunctionSignatureX extends FunctionSignatureCommon
- implements FunctionSignature {
- final List<ResolutionDartType> typeVariables;
- final List<FormalElement> requiredParameters;
- final List<FormalElement> optionalParameters;
- final int requiredParameterCount;
- final int optionalParameterCount;
- final bool optionalParametersAreNamed;
- final List<FormalElement> orderedOptionalParameters;
- final ResolutionFunctionType type;
- final bool hasOptionalParameters;
-
- FunctionSignatureX(
- {this.typeVariables: const <ResolutionDartType>[],
- this.requiredParameters: const <FormalElement>[],
- this.requiredParameterCount: 0,
- List<Element> optionalParameters: const <FormalElement>[],
- this.optionalParameterCount: 0,
- this.optionalParametersAreNamed: false,
- this.orderedOptionalParameters: const <FormalElement>[],
- this.type})
- : optionalParameters = optionalParameters,
- hasOptionalParameters = !optionalParameters.isEmpty;
-}
-
-abstract class BaseFunctionElementX extends ElementX
- with PatchMixin<FunctionElement>, AstElementMixin
- implements FunctionElement {
- ResolutionDartType typeCache;
- final Modifiers modifiers;
- bool isMarkedNative = false;
-
- List<MethodElement> nestedClosures = new List<MethodElement>();
-
- FunctionSignature _functionSignatureCache;
-
- AsyncMarker _asyncMarker = AsyncMarker.SYNC;
-
- BaseFunctionElementX(String name, ElementKind kind, Modifiers this.modifiers,
- Element enclosing)
- : super(name, kind, enclosing) {
- assert(modifiers != null);
- }
-
- AsyncMarker get asyncMarker {
- if (isPatched) {
- return patch.asyncMarker;
- }
- return _asyncMarker;
- }
-
- void set asyncMarker(AsyncMarker value) {
- if (isPatched) {
- BaseFunctionElementX function = patch;
- function.asyncMarker = value;
- } else {
- _asyncMarker = value;
- }
- }
-
- bool get isMarkedExternal => modifiers.isExternal;
-
- bool get isExternal => (isMarkedExternal && !isPatched) || isMarkedNative;
-
- bool get isInstanceMember {
- return isClassMember && !isConstructor && !isStatic;
- }
-
- ParameterStructure get parameterStructure =>
- functionSignature.parameterStructure;
-
- bool get hasFunctionSignature => _functionSignatureCache != null;
-
- void _computeSignature(Resolution resolution) {
- if (hasFunctionSignature) return;
- functionSignature = resolution.resolveSignature(this);
- }
-
- FunctionSignature get functionSignature {
- assert(hasFunctionSignature,
- failedAt(this, "Function signature has not been computed for $this."));
- return _functionSignatureCache;
- }
-
- void set functionSignature(FunctionSignature value) {
- // TODO(johnniwinther): Strengthen the invariant to `!hasFunctionSignature`
- // when checked mode checks are not enqueued eagerly.
- assert(
- !hasFunctionSignature || type == value.type,
- failedAt(
- this, "Function signature has already been computed for $this."));
- _functionSignatureCache = value;
- typeCache = _functionSignatureCache.type;
- }
-
- List<ParameterElement> get parameters {
- // TODO(johnniwinther): Store the list directly, possibly by using List
- // instead of Link in FunctionSignature.
- List<ParameterElement> list = <ParameterElement>[];
- functionSignature.forEachParameter((e) => list.add(e));
- return list;
- }
-
- ResolutionFunctionType computeType(Resolution resolution) {
- if (typeCache != null) return typeCache;
- _computeSignature(resolution);
- assert(typeCache != null,
- failedAt(this, "Type cache expected to be set on $this."));
- return typeCache;
- }
-
- ResolutionFunctionType get type {
- assert(typeCache != null,
- failedAt(this, "Type has not been computed for $this."));
- return typeCache;
- }
-
- FunctionElement asFunctionElement() => this;
-
- @override
- Scope buildScope() => new TypeDeclarationScope(super.buildScope(), this);
-
- String toString() {
- if (isPatch) {
- return 'patch ${super.toString()}';
- } else if (isPatched) {
- return 'origin ${super.toString()}';
- } else {
- return super.toString();
- }
- }
-
- bool get isAbstract => false;
-
- // A function is defined by the implementation element.
- AstElement get definingElement => implementation;
-
- @override
- List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-
- // TODO(johnniwinther): Remove this.
- FunctionElement get declaration => super.declaration;
-
- // TODO(johnniwinther): Remove this.
- FunctionElement get implementation => super.implementation;
-
- // TODO(johnniwinther): Remove this.
- FunctionElement get origin => super.origin;
-
- // TODO(johnniwinther): Remove this.
- FunctionElement get patch => super.patch;
-}
-
-abstract class FunctionElementX extends BaseFunctionElementX
- with AnalyzableElementX
- implements MethodElement {
- FunctionElementX(
- String name, ElementKind kind, Modifiers modifiers, Element enclosing)
- : super(name, kind, modifiers, enclosing);
-
- MemberElement get memberContext => this;
-
- @override
- SourceSpan get sourcePosition {
- SourceSpan span = super.sourcePosition;
- if (span != null && hasNode) {
- FunctionExpression functionExpression = node.asFunctionExpression();
- if (functionExpression != null) {
- span = new SourceSpan.fromNode(span.uri, functionExpression);
- }
- }
- return span;
- }
-
- void reuseElement() {
- super.reuseElement();
- nestedClosures.clear();
- _functionSignatureCache = null;
- typeCache = null;
- }
-}
-
-abstract class MethodElementX extends FunctionElementX {
- final bool hasBody;
-
- MethodElementX(
- String name,
- ElementKind kind,
- Modifiers modifiers,
- Element enclosing,
- // TODO(15101): Make this a named parameter.
- this.hasBody)
- : super(name, kind, modifiers, enclosing);
-
- @override
- bool get isAbstract {
- return !modifiers.isExternal && !hasBody;
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitMethodElement(this, arg);
- }
-}
-
-abstract class AccessorElementX extends MethodElementX
- implements AccessorElement {
- AbstractFieldElement abstractField;
-
- AccessorElementX(String name, ElementKind kind, Modifiers modifiers,
- Element enclosing, bool hasBody)
- : super(name, kind, modifiers, enclosing, hasBody);
-}
-
-abstract class GetterElementX extends AccessorElementX
- implements GetterElement {
- GetterElementX(
- String name, Modifiers modifiers, Element enclosing, bool hasBody)
- : super(name, ElementKind.GETTER, modifiers, enclosing, hasBody);
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitGetterElement(this, arg);
- }
-}
-
-abstract class SetterElementX extends AccessorElementX
- implements SetterElement {
- SetterElementX(
- String name, Modifiers modifiers, Element enclosing, bool hasBody)
- : super(name, ElementKind.SETTER, modifiers, enclosing, hasBody);
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitSetterElement(this, arg);
- }
-}
-
-class LocalFunctionElementX extends BaseFunctionElementX
- implements LocalFunctionElement {
- final FunctionExpression node;
-
- MethodElement callMethod;
-
- LocalFunctionElementX(String name, FunctionExpression this.node,
- ElementKind kind, Modifiers modifiers, ExecutableElement enclosing)
- : super(name, kind, modifiers, enclosing);
-
- ExecutableElement get executableContext => enclosingElement;
-
- MemberElement get memberContext => executableContext.memberContext;
-
- bool get hasNode => true;
-
- FunctionExpression parseNode(ParsingContext parsing) => node;
-
- Token get position {
- // Use the name as position if this is not an unnamed closure.
- if (node.name != null) {
- return node.name.getBeginToken();
- } else {
- return node.getBeginToken();
- }
- }
-
- bool get isLocal => true;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitLocalFunctionElement(this, arg);
- }
-}
-
-abstract class ConstantConstructorMixin implements ConstructorElement {
- ConstantConstructor _constantConstructor;
-
- ConstantConstructor get constantConstructor {
- if (isPatch) {
- ConstructorElement originConstructor = origin;
- return originConstructor.constantConstructor;
- }
- if (!isConst || isFromEnvironmentConstructor) return null;
- if (_constantConstructor == null) {
- _constantConstructor = computeConstantConstructor(resolvedAst);
- }
- return _constantConstructor;
- }
-
- void set constantConstructor(ConstantConstructor value) {
- if (isPatch) {
- ConstantConstructorMixin originConstructor = origin;
- originConstructor.constantConstructor = value;
- } else {
- assert(
- isConst,
- failedAt(
- this,
- "Constant constructor set on non-constant "
- "constructor $this."));
- assert(
- !isFromEnvironmentConstructor,
- failedAt(
- this,
- "Constant constructor set on fromEnvironment "
- "constructor: $this."));
- assert(
- _constantConstructor == null || _constantConstructor == value,
- failedAt(
- this,
- "Constant constructor already computed for $this:"
- "Existing: $_constantConstructor, new: $value"));
- _constantConstructor = value;
- }
- }
-
- /// Returns the empty list of type variables by default.
- @override
- List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-}
-
-abstract class ConstructorElementX extends FunctionElementX
- with ConstantConstructorMixin, ConstructorElementCommon
- implements ConstructorElement {
- bool isRedirectingGenerativeInternal = false;
-
- ConstructorElementX(
- String name, ElementKind kind, Modifiers modifiers, Element enclosing)
- : super(name, kind, modifiers, enclosing);
-
- ConstructorElement _immediateRedirectionTarget;
- PrefixElement _redirectionDeferredPrefix;
-
- bool get isRedirectingGenerative {
- if (isPatched) return patch.isRedirectingGenerative;
- return isRedirectingGenerativeInternal;
- }
-
- bool get isRedirectingFactory => immediateRedirectionTarget != null;
-
- // TODO(johnniwinther): This should also return true for cyclic redirecting
- // generative constructors.
- bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory;
-
- bool get isDefaultConstructor => false;
-
- /// These fields are set by the post process queue when checking for cycles.
- ConstructorElement effectiveTargetInternal;
- ResolutionDartType _effectiveTargetType;
- bool _isEffectiveTargetMalformed;
-
- bool get hasEffectiveTarget {
- if (isPatched) {
- return patch.hasEffectiveTarget;
- }
- return effectiveTargetInternal != null;
- }
-
- void setImmediateRedirectionTarget(
- ConstructorElement target, PrefixElement prefix) {
- if (isPatched) {
- patch.setImmediateRedirectionTarget(target, prefix);
- } else {
- assert(
- _immediateRedirectionTarget == null,
- failedAt(this,
- "Immediate redirection target has already been set on $this."));
- _immediateRedirectionTarget = target;
- _redirectionDeferredPrefix = prefix;
- }
- }
-
- ConstructorElement get immediateRedirectionTarget {
- if (isPatched) {
- return patch.immediateRedirectionTarget;
- }
- return _immediateRedirectionTarget;
- }
-
- PrefixElement get redirectionDeferredPrefix {
- if (isPatched) {
- return patch.redirectionDeferredPrefix;
- }
- return _redirectionDeferredPrefix;
- }
-
- void setEffectiveTarget(ConstructorElement target, ResolutionDartType type,
- {bool isMalformed: false}) {
- if (isPatched) {
- patch.setEffectiveTarget(target, type, isMalformed: isMalformed);
- } else {
- assert(target != null,
- failedAt(this, 'No effective target provided for $this.'));
- assert(
- effectiveTargetInternal == null,
- failedAt(
- this, 'Effective target has already been computed for $this.'));
- assert(
- !target.isMalformed || isMalformed,
- failedAt(
- this,
- 'Effective target is not marked as malformed for $this: '
- 'target=$target, type=$type, isMalformed: $isMalformed'));
- assert(
- isMalformed || type.isInterfaceType,
- failedAt(
- this,
- 'Effective target type is not an interface type for $this: '
- 'target=$target, type=$type, isMalformed: $isMalformed'));
- effectiveTargetInternal = target;
- _effectiveTargetType = type;
- _isEffectiveTargetMalformed = isMalformed;
- }
- }
-
- ConstructorElement get effectiveTarget {
- if (isPatched) {
- return patch.effectiveTarget;
- }
- if (isRedirectingFactory) {
- assert(effectiveTargetInternal != null);
- return effectiveTargetInternal;
- }
- return this;
- }
-
- ResolutionDartType get effectiveTargetType {
- if (isPatched) {
- return patch.effectiveTargetType;
- }
- assert(
- _effectiveTargetType != null,
- failedAt(this,
- 'Effective target type has not yet been computed for $this.'));
- return _effectiveTargetType;
- }
-
- ResolutionDartType computeEffectiveTargetType(
- ResolutionInterfaceType newType) {
- if (isPatched) {
- return patch.computeEffectiveTargetType(newType);
- }
- if (!isRedirectingFactory) return newType;
- return effectiveTargetType.substByContext(newType);
- }
-
- bool get isEffectiveTargetMalformed {
- if (isPatched) {
- return patch.isEffectiveTargetMalformed;
- }
- if (!isRedirectingFactory) return false;
- assert(_isEffectiveTargetMalformed != null,
- failedAt(this, 'Malformedness has not yet been computed for $this.'));
- return _isEffectiveTargetMalformed == true;
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitConstructorElement(this, arg);
- }
-
- ConstructorElement get definingConstructor => null;
-
- ClassElement get enclosingClass => enclosingElement.declaration;
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get declaration => super.declaration;
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get implementation => super.implementation;
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get origin => super.origin;
-
- // TODO(johnniwinther): Remove this.
- ConstructorElementX get patch => super.patch;
-}
-
-class DeferredLoaderGetterElementX extends GetterElementX {
- final PrefixElement prefix;
-
- DeferredLoaderGetterElementX(PrefixElement prefix)
- : this.prefix = prefix,
- super(Identifiers.loadLibrary, Modifiers.EMPTY, prefix, false) {
- functionSignature =
- new FunctionSignatureX(type: new ResolutionFunctionType(this));
- }
-
- bool get isClassMember => false;
-
- bool get isSynthesized => true;
-
- bool get isDeferredLoaderGetter => true;
-
- bool get isTopLevel => true;
-
- // By having position null, the enclosing elements location is printed in
- // error messages.
- Token get position => null;
-
- FunctionExpression parseNode(ParsingContext parsing) => null;
-
- bool get hasNode => false;
-
- FunctionExpression get node => null;
-
- bool get hasResolvedAst => true;
-
- ResolvedAst get resolvedAst {
- return new SynthesizedResolvedAst(
- this, ResolvedAstKind.DEFERRED_LOAD_LIBRARY);
- }
-
- @override
- SetterElement get setter => null;
-}
-
-class ConstructorBodyElementX extends BaseFunctionElementX
- implements ConstructorBodyElement {
- final ResolvedAst _resolvedAst;
- final ConstructorElement constructor;
-
- ConstructorBodyElementX(
- ResolvedAst resolvedAst, ConstructorElement constructor)
- : this._resolvedAst = resolvedAst,
- this.constructor = constructor,
- super(constructor.name, ElementKind.GENERATIVE_CONSTRUCTOR_BODY,
- Modifiers.EMPTY, constructor.enclosingElement) {
- functionSignature = constructor.functionSignature;
- }
-
- /// Returns the constructor body associated with the given constructor or
- /// creates a new constructor body, if none can be found.
- ///
- /// Returns `null` if the constructor does not have a body.
- static ConstructorBodyElementX createFromResolvedAst(
- ResolvedAst constructorResolvedAst) {
- ConstructorElement constructor =
- constructorResolvedAst.element.implementation;
- assert(constructor.isGenerativeConstructor);
- if (constructorResolvedAst.kind != ResolvedAstKind.PARSED) return null;
-
- FunctionExpression node = constructorResolvedAst.node;
- // If we know the body doesn't have any code, we don't generate it.
- if (!node.hasBody) return null;
- if (node.hasEmptyBody) return null;
- ClassElement classElement = constructor.enclosingClass;
- ConstructorBodyElement bodyElement;
- classElement.forEachConstructorBody((ConstructorBodyElement body) {
- if (body.constructor == constructor) {
- // TODO(kasperl): Find a way of stopping the iteration
- // through the backend members.
- bodyElement = body;
- }
- });
- if (bodyElement == null) {
- bodyElement =
- new ConstructorBodyElementX(constructorResolvedAst, constructor);
- classElement.addConstructorBody(bodyElement);
-
- if (constructor.isPatch) {
- // Create origin body element for patched constructors.
- ConstructorBodyElementX patch = bodyElement;
- ConstructorBodyElementX origin = new ConstructorBodyElementX(
- constructorResolvedAst, constructor.origin);
- origin.applyPatch(patch);
- classElement.origin.addConstructorBody(bodyElement.origin);
- }
- }
- assert(bodyElement.isGenerativeConstructorBody);
- return bodyElement;
- }
-
- bool get hasNode => _resolvedAst.kind == ResolvedAstKind.PARSED;
-
- FunctionExpression get node => _resolvedAst.node;
-
- bool get hasResolvedAst => true;
-
- ResolvedAst get resolvedAst {
- if (_resolvedAst.kind == ResolvedAstKind.PARSED) {
- return new ParsedResolvedAst(declaration, _resolvedAst.node,
- _resolvedAst.body, _resolvedAst.elements, _resolvedAst.sourceUri);
- } else {
- return new SynthesizedResolvedAst(declaration, _resolvedAst.kind);
- }
- }
-
- List<MetadataAnnotation> get metadata => constructor.metadata;
-
- bool get isInstanceMember => true;
-
- ResolutionFunctionType computeType(Resolution resolution) {
- DiagnosticReporter reporter = resolution.reporter;
- reporter.internalError(this, '$this.computeType.');
- return null;
- }
-
- int get sourceOffset => constructor.sourceOffset;
-
- Token get position => constructor.position;
-
- Element get outermostEnclosingMemberOrTopLevel => constructor;
-
- AnalyzableElement get analyzableElement => constructor.analyzableElement;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitConstructorBodyElement(this, arg);
- }
-
- MemberElement get memberContext => constructor;
-}
-
-/**
- * A constructor that is not defined in the source code but rather implied by
- * the language semantics.
- *
- * This class is used to represent default constructors and forwarding
- * constructors for mixin applications.
- */
-class SynthesizedConstructorElementX extends ConstructorElementX {
- final ConstructorElement definingConstructor;
- ResolvedAst _resolvedAst;
-
- SynthesizedConstructorElementX.notForDefault(
- String name, this.definingConstructor, Element enclosing)
- : super(name, ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY,
- enclosing) {
- _resolvedAst = new SynthesizedResolvedAst(
- this, ResolvedAstKind.FORWARDING_CONSTRUCTOR);
- }
-
- SynthesizedConstructorElementX.forDefault(
- this.definingConstructor, Element enclosing)
- : super('', ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY,
- enclosing) {
- functionSignature = new FunctionSignatureX(
- type: new ResolutionFunctionType.synthesized(
- const ResolutionDynamicType()));
- _resolvedAst =
- new SynthesizedResolvedAst(this, ResolvedAstKind.DEFAULT_CONSTRUCTOR);
- }
-
- bool get isDefaultConstructor {
- return _resolvedAst.kind == ResolvedAstKind.DEFAULT_CONSTRUCTOR;
- }
-
- FunctionExpression parseNode(ParsingContext parsing) => null;
-
- bool get hasNode => false;
-
- FunctionExpression get node => null;
-
- Token get position => enclosingElement.position;
-
- bool get isSynthesized => true;
-
- bool get hasResolvedAst => true;
-
- ResolvedAst get resolvedAst => _resolvedAst;
-
- ResolutionFunctionType get type {
- if (isDefaultConstructor) {
- return super.type;
- } else {
- // TODO(johnniwinther): Ensure that the function type substitutes type
- // variables correctly.
- return definingConstructor.type;
- }
- }
-
- void _computeSignature(Resolution resolution) {
- if (hasFunctionSignature) return;
- if (definingConstructor.isMalformed) {
- functionSignature = new FunctionSignatureX(
- type:
- new ResolutionFunctionType.synthesized(enclosingClass.thisType));
- }
- // TODO(johnniwinther): Ensure that the function signature (and with it the
- // function type) substitutes type variables correctly.
- definingConstructor.computeType(resolution);
- functionSignature = definingConstructor.functionSignature;
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitConstructorElement(this, arg);
- }
-}
-
-abstract class TypeDeclarationElementX implements TypeDeclarationElement {
- /**
- * The `this type` for this type declaration.
- *
- * The type of [:this:] is the generic type based on this element in which
- * the type arguments are the declared type variables. For instance,
- * [:List<E>:] for [:List:] and [:Map<K,V>:] for [:Map:].
- *
- * For a class declaration this is the type of [:this:].
- *
- * This type is computed in [computeType].
- */
- GenericType thisTypeCache;
-
- /**
- * The raw type for this type declaration.
- *
- * The raw type is the generic type base on this element in which the type
- * arguments are all [dynamic]. For instance [:List<dynamic>:] for [:List:]
- * and [:Map<dynamic,dynamic>:] for [:Map:]. For non-generic classes [rawType]
- * is the same as [thisType].
- *
- * The [rawType] field is a canonicalization of the raw type and should be
- * used to distinguish explicit and implicit uses of the [dynamic]
- * type arguments. For instance should [:List:] be the [rawType] of the
- * [:List:] class element whereas [:List<dynamic>:] should be its own
- * instantiation of [ResolutionInterfaceType] with [:dynamic:] as type
- * argument. Using this distinction, we can print the raw type with type
- * arguments only when the input source has used explicit type arguments.
- *
- * This type is computed together with [thisType] in [computeType].
- */
- GenericType rawTypeCache;
-
- GenericType get thisType {
- assert(thisTypeCache != null,
- failedAt(this, 'This type has not been computed for $this'));
- return thisTypeCache;
- }
-
- GenericType get rawType {
- assert(rawTypeCache != null,
- failedAt(this, 'Raw type has not been computed for $this'));
- return rawTypeCache;
- }
-
- GenericType createType(List<ResolutionDartType> typeArguments);
-
- void setThisAndRawTypes(List<ResolutionDartType> typeParameters) {
- assert(thisTypeCache == null,
- failedAt(this, "This type has already been set on $this."));
- assert(rawTypeCache == null,
- failedAt(this, "Raw type has already been set on $this."));
- thisTypeCache = createType(typeParameters);
- if (typeParameters.isEmpty) {
- rawTypeCache = thisTypeCache;
- } else {
- List<ResolutionDartType> dynamicParameters =
- new List.filled(typeParameters.length, const ResolutionDynamicType());
- rawTypeCache = createType(dynamicParameters);
- }
- }
-
- List<ResolutionDartType> get typeVariables => thisType.typeArguments;
-
- /**
- * Creates the type variables, their type and corresponding element, for the
- * type variables declared in [parameter] on [element]. The bounds of the type
- * variables are not set until [element] has been resolved.
- */
- List<ResolutionDartType> createTypeVariables(NodeList parameters) {
- if (parameters == null) return const <ResolutionDartType>[];
-
- // Create types and elements for type variable.
- Link<Node> nodes = parameters.nodes;
- List<ResolutionDartType> arguments =
- new List.generate(nodes.slowLength(), (int index) {
- TypeVariable node = nodes.head;
- String variableName = node.name.source;
- nodes = nodes.tail;
- TypeVariableElementX variableElement =
- new TypeVariableElementX(variableName, this, index, node);
- ResolutionTypeVariableType variableType =
- new ResolutionTypeVariableType(variableElement);
- variableElement.typeCache = variableType;
- return variableType;
- }, growable: false);
- return arguments;
- }
-
- bool get isResolved => resolutionState == STATE_DONE;
-
- int get resolutionState;
-}
-
-abstract class BaseClassElementX extends ElementX
- with
- AstElementMixin,
- AnalyzableElementX,
- ClassElementCommon,
- TypeDeclarationElementX,
- PatchMixin<ClassElement>,
- ClassMemberMixin
- implements ClassElement {
- final int id;
-
- ResolutionInterfaceType supertype;
- Link<ResolutionDartType> interfaces;
- int supertypeLoadState;
- int resolutionState;
- bool isProxy = false;
- bool hasIncompleteHierarchy = false;
-
- OrderedTypeSet allSupertypesAndSelf;
-
- BaseClassElementX(String name, Element enclosing, this.id, int initialState)
- : supertypeLoadState = initialState,
- resolutionState = initialState,
- super(name, ElementKind.CLASS, enclosing);
-
- int get hashCode => id;
-
- bool get isUnnamedMixinApplication => false;
-
- @override
- bool get isEnumClass => false;
-
- ResolutionInterfaceType computeType(Resolution resolution) {
- if (isPatch) {
- origin.computeType(resolution);
- thisTypeCache = origin.thisType;
- rawTypeCache = origin.rawType;
- } else if (thisTypeCache == null) {
- computeThisAndRawType(
- resolution, computeTypeParameters(resolution.parsingContext));
- }
- return thisTypeCache;
- }
-
- void computeThisAndRawType(
- Resolution resolution, List<ResolutionDartType> typeVariables) {
- if (thisTypeCache == null) {
- if (origin == null) {
- setThisAndRawTypes(typeVariables);
- } else {
- thisTypeCache = origin.computeType(resolution);
- rawTypeCache = origin.rawType;
- }
- }
- }
-
- @override
- ResolutionInterfaceType createType(List<ResolutionDartType> typeArguments) {
- return new ResolutionInterfaceType(this, typeArguments);
- }
-
- List<ResolutionDartType> computeTypeParameters(ParsingContext parsing);
-
- bool get isObject {
- assert(isResolved,
- failedAt(this, "isObject has not been computed for $this."));
- return supertype == null;
- }
-
- void ensureResolved(Resolution resolution) {
- if (resolutionState == STATE_NOT_STARTED) {
- resolution.resolveClass(this);
- resolution.registerClass(this);
- }
- }
-
- void setDefaultConstructor(
- FunctionElement constructor, DiagnosticReporter reporter);
-
- ConstructorElement lookupDefaultConstructor() {
- ConstructorElement constructor = lookupConstructor("");
- // This method might be called on constructors that have not been
- // resolved. As we query the live world, we return `null` in such cases
- // as no default constructor exists in the live world.
- if (constructor != null &&
- constructor.hasFunctionSignature &&
- constructor.functionSignature.requiredParameterCount == 0) {
- return constructor;
- }
- return null;
- }
-
- /**
- * Returns the super class, if any.
- *
- * The returned element may not be resolved yet.
- */
- ClassElement get superclass {
- assert(supertypeLoadState == STATE_DONE,
- failedAt(this, "Superclass has not been computed for $this."));
- return supertype == null ? null : supertype.element;
- }
-
- // A class declaration is defined by the declaration element.
- AstElement get definingElement => declaration;
-
- ResolutionInterfaceType get thisType => super.thisType;
-
- ResolutionInterfaceType get rawType => super.rawType;
-
- // TODO(johnniwinther): Remove this.
- ClassElement get declaration => super.declaration;
-
- // TODO(johnniwinther): Remove this.
- ClassElement get implementation => super.implementation;
-
- // TODO(johnniwinther): Remove this.
- ClassElement get origin => super.origin;
-
- // TODO(johnniwinther): Remove this.
- ClassElement get patch => super.patch;
-}
-
-abstract class ClassElementX extends BaseClassElementX {
- Link<Element> localMembersReversed = const Link<Element>();
- final ScopeX localScope = new ScopeX();
-
- Link<Element> localMembersCache;
-
- Link<Element> get localMembers {
- if (localMembersCache == null) {
- localMembersCache = localMembersReversed.reverse();
- }
- return localMembersCache;
- }
-
- ClassElementX(String name, Element enclosing, int id, int initialState)
- : super(name, enclosing, id, initialState);
-
- bool get isMixinApplication => false;
- bool get hasLocalScopeMembers => !localScope.isEmpty;
-
- void addMember(Element element, DiagnosticReporter reporter) {
- localMembersCache = null;
- localMembersReversed = localMembersReversed.prepend(element);
- addToScope(element, reporter);
- }
-
- void addToScope(Element element, DiagnosticReporter reporter) {
- if (element.isField && element.name == name) {
- reporter.reportErrorMessage(element, MessageKind.MEMBER_USES_CLASS_NAME);
- }
- localScope.add(element, reporter);
- }
-
- Element localLookup(String elementName) {
- Element result = localScope.lookup(elementName);
- if (result == null && isPatch) {
- result = origin.localLookup(elementName);
- }
- return result;
- }
-
- void forEachLocalMember(void f(Element member)) {
- localMembers.forEach(f);
- }
-
- bool get hasConstructor {
- // Search in scope to be sure we search patched constructors.
- for (var element in localScope.values) {
- if (element.isConstructor) return true;
- }
- return false;
- }
-
- void setDefaultConstructor(
- FunctionElement constructor, DiagnosticReporter reporter) {
- // The default constructor, although synthetic, is part of a class' API.
- addMember(constructor, reporter);
- }
-
- List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) {
- ClassNode node = parseNode(parsing);
- return createTypeVariables(node.typeParameters);
- }
-
- Scope buildScope() => new ClassScope(enclosingElement.buildScope(), this);
-
- String toString() {
- if (origin != null) {
- return 'patch ${super.toString()}';
- } else if (patch != null) {
- return 'origin ${super.toString()}';
- } else {
- return super.toString();
- }
- }
-}
-
-/// This element is used to encode an enum class.
-///
-/// For instance
-///
-/// enum A { b, c, }
-///
-/// is modelled as
-///
-/// class A {
-/// final int index;
-///
-/// const A(this.index);
-///
-/// String toString() {
-/// return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-/// }
-///
-/// static const A b = const A(0);
-/// static const A c = const A(1);
-///
-/// static const List<A> values = const <A>[b, c];
-/// }
-///
-/// where the `A` class is encoded using this element.
-///
-class EnumClassElementX extends ClassElementX
- implements EnumClassElement, DeclarationSite {
- final Enum node;
- List<EnumConstantElement> _enumValues;
-
- EnumClassElementX(String name, Element enclosing, int id, this.node)
- : super(name, enclosing, id, STATE_NOT_STARTED);
-
- @override
- bool get hasNode => true;
-
- @override
- Token get position => node.name.token;
-
- @override
- bool get isEnumClass => true;
-
- @override
- Node parseNode(ParsingContext parsing) => node;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitEnumClassElement(this, arg);
- }
-
- List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) =>
- const <ResolutionDartType>[];
-
- List<EnumConstantElement> get enumValues {
- assert(_enumValues != null,
- failedAt(this, "enumValues has not been computed for $this."));
- return _enumValues;
- }
-
- void set enumValues(List<EnumConstantElement> values) {
- assert(_enumValues == null,
- failedAt(this, "enumValues has already been computed for $this."));
- _enumValues = values;
- }
-
- @override
- DeclarationSite get declarationSite => this;
-}
-
-/// This element is used to encode the implicit constructor in an enum class.
-///
-/// For instance
-///
-/// enum A { b, c, }
-///
-/// is modelled as
-///
-/// class A {
-/// final int index;
-///
-/// const A(this.index);
-///
-/// String toString() {
-/// return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-/// }
-///
-/// static const A b = const A(0);
-/// static const A c = const A(1);
-///
-/// static const List<A> values = const <A>[b, c];
-/// }
-///
-/// where the `const A(...)` constructor is encoded using this element.
-///
-class EnumConstructorElementX extends ConstructorElementX {
- final FunctionExpression node;
-
- EnumConstructorElementX(
- EnumClassElementX enumClass, Modifiers modifiers, this.node)
- : super(
- '', // Name.
- ElementKind.GENERATIVE_CONSTRUCTOR,
- modifiers,
- enumClass);
-
- @override
- bool get hasNode => true;
-
- @override
- FunctionExpression parseNode(ParsingContext parsing) => node;
-
- @override
- SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the implicit methods in an enum class.
-///
-/// For instance
-///
-/// enum A { b, c, }
-///
-/// is modelled as
-///
-/// class A {
-/// final int index;
-///
-/// const A(this.index);
-///
-/// String toString() {
-/// return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-/// }
-///
-/// static const A b = const A(0);
-/// static const A c = const A(1);
-///
-/// static const List<A> values = const <A>[b, c];
-/// }
-///
-/// where the `toString` method is encoded using this element.
-///
-class EnumMethodElementX extends MethodElementX {
- final FunctionExpression node;
-
- EnumMethodElementX(
- String name, EnumClassElementX enumClass, Modifiers modifiers, this.node)
- : super(name, ElementKind.FUNCTION, modifiers, enumClass, true);
-
- @override
- bool get hasNode => true;
-
- @override
- FunctionExpression parseNode(ParsingContext parsing) => node;
-
- @override
- SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the initializing formal of the implicit
-/// constructor in an enum class.
-///
-/// For instance
-///
-/// enum A { b, c, }
-///
-/// is modelled as
-///
-/// class A {
-/// final int index;
-///
-/// const A(this.index);
-///
-/// String toString() {
-/// return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-/// }
-///
-/// static const A b = const A(0);
-/// static const A c = const A(1);
-///
-/// static const List<A> values = const <A>[b, c];
-/// }
-///
-/// where the `this.index` formal is encoded using this element.
-///
-class EnumFormalElementX extends InitializingFormalElementX {
- EnumFormalElementX(
- ConstructorElement constructor,
- VariableDefinitions variables,
- Identifier identifier,
- EnumFieldElementX fieldElement)
- : super(constructor, variables, identifier, null, fieldElement) {
- typeCache = fieldElement.type;
- }
-
- @override
- SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the implicitly fields in an enum class.
-///
-/// For instance
-///
-/// enum A { b, c, }
-///
-/// is modelled as
-///
-/// class A {
-/// final int index;
-///
-/// const A(this.index);
-///
-/// String toString() {
-/// return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-/// }
-///
-/// static const A b = const A(0);
-/// static const A c = const A(1);
-///
-/// static const List<A> values = const <A>[b, c];
-/// }
-///
-/// where the `index` and `values` fields are encoded using this element.
-///
-class EnumFieldElementX extends FieldElementX {
- EnumFieldElementX(Identifier name, EnumClassElementX enumClass,
- VariableList variableList, Node definition,
- [Expression initializer])
- : super(name, enumClass, variableList) {
- definitionsCache = new VariableDefinitions(
- null, variableList.modifiers, new NodeList.singleton(definition));
- initializerCache = initializer;
- definitionCache = definition;
- }
-
- @override
- SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the constant value in an enum class.
-///
-/// For instance
-///
-/// enum A { b, c, }
-///
-/// is modelled as
-///
-/// class A {
-/// final int index;
-///
-/// const A(this.index);
-///
-/// String toString() {
-/// return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-/// }
-///
-/// static const A b = const A(0);
-/// static const A c = const A(1);
-///
-/// static const List<A> values = const <A>[b, c];
-/// }
-///
-/// where the `b` and `c` fields are encoded using this element.
-///
-class EnumConstantElementX extends EnumFieldElementX
- implements EnumConstantElement {
- final int index;
-
- EnumConstantElementX(
- Identifier name,
- EnumClassElementX enumClass,
- VariableList variableList,
- Node definition,
- Expression initializer,
- this.index)
- : super(name, enumClass, variableList, definition, initializer);
-
- @override
- SourceSpan get sourcePosition {
- return new SourceSpan(enclosingClass.sourcePosition.uri,
- position.charOffset, position.charEnd);
- }
-
- EnumClassElement get enclosingClass => super.enclosingClass;
-}
-
-abstract class MixinApplicationElementX extends BaseClassElementX
- with MixinApplicationElementCommon
- implements MixinApplicationElement {
- Link<ConstructorElement> constructors = new Link<ConstructorElement>();
-
- ResolutionInterfaceType mixinType;
-
- MixinApplicationElementX(String name, Element enclosing, int id)
- : super(name, enclosing, id, STATE_NOT_STARTED);
-
- ClassElement get mixin => mixinType != null ? mixinType.element : null;
-
- bool get isMixinApplication => true;
- bool get hasConstructor => !constructors.isEmpty;
- bool get hasLocalScopeMembers => !constructors.isEmpty;
-
- get patch => null;
- get origin => null;
-
- bool get hasNode => true;
-
- Token get position => node.getBeginToken();
-
- Node parseNode(ParsingContext parsing) => node;
-
- void addMember(Element element, DiagnosticReporter reporter) {
- throw new UnsupportedError("Cannot add member to $this.");
- }
-
- void addToScope(Element element, DiagnosticReporter reporter) {
- reporter.internalError(this, 'Cannot add to scope of $this.');
- }
-
- void addConstructor(FunctionElement constructor) {
- constructors = constructors.prepend(constructor);
- }
-
- void setDefaultConstructor(
- FunctionElement constructor, DiagnosticReporter reporter) {
- assert(!hasConstructor);
- addConstructor(constructor);
- }
-
- List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) {
- NamedMixinApplication named = node.asNamedMixinApplication();
- if (named == null) {
- failedAt(
- node,
- "Type variables on unnamed mixin applications must be set on "
- "creation.");
- }
- return createTypeVariables(named.typeParameters);
- }
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitMixinApplicationElement(this, arg);
- }
-}
-
-class NamedMixinApplicationElementX extends MixinApplicationElementX
- implements DeclarationSite {
- final NamedMixinApplication node;
-
- NamedMixinApplicationElementX(
- String name, CompilationUnitElement enclosing, int id, this.node)
- : super(name, enclosing, id);
-
- Modifiers get modifiers => node.modifiers;
-
- DeclarationSite get declarationSite => this;
-
- ClassElement get subclass => null;
-}
-
-class UnnamedMixinApplicationElementX extends MixinApplicationElementX {
- final Node node;
- final ClassElement subclass;
-
- UnnamedMixinApplicationElementX(
- String name, ClassElement subclass, int id, this.node)
- : this.subclass = subclass,
- super(name, subclass.compilationUnit, id);
-
- bool get isUnnamedMixinApplication => true;
-
- bool get isAbstract => true;
-}
-
-class LabelDefinitionX extends LabelDefinition<Node> {
- final Label label;
- final String labelName;
- final JumpTargetX target;
- bool isBreakTarget = false;
- bool isContinueTarget = false;
-
- LabelDefinitionX(Label label, String labelName, this.target)
- : this.label = label,
- this.labelName = labelName;
-
- // In case of a synthetic label, just use [labelName] for identifying the
- // label.
- String get name => label == null ? labelName : label.identifier.source;
-
- void setBreakTarget() {
- isBreakTarget = true;
- target.isBreakTarget = true;
- }
-
- void setContinueTarget() {
- isContinueTarget = true;
- target.isContinueTarget = true;
- }
-
- String toString() => 'Label:${name}';
-}
-
-class JumpTargetX extends JumpTarget<Node> {
- final ExecutableElement executableContext;
- final Node statement;
- final int nestingLevel;
- List<LabelDefinition<Node>> labels = <LabelDefinition<Node>>[];
- bool isBreakTarget = false;
- bool isContinueTarget = false;
-
- final int hashCode = ElementX.newHashCode();
-
- JumpTargetX(this.statement, this.nestingLevel, this.executableContext);
-
- MemberElement get memberContext => executableContext.memberContext;
-
- LabelDefinition<Node> addLabel(Label label, String labelName,
- {bool isBreakTarget: false, bool isContinueTarget: false}) {
- LabelDefinitionX result = new LabelDefinitionX(label, labelName, this);
- labels.add(result);
- if (isBreakTarget) {
- result.setBreakTarget();
- }
- if (isContinueTarget) {
- result.setContinueTarget();
- }
- return result;
- }
-
- bool get isSwitch => statement is SwitchStatement;
-
- bool get isSwitchCase => statement is SwitchCase;
-
- String toString() => 'Target:$statement';
-}
-
-class TypeVariableElementX extends ElementX
- with AstElementMixin
- implements TypeVariableElement {
- final int index;
- final Node node;
- ResolutionTypeVariableType typeCache;
- ResolutionDartType boundCache;
-
- TypeVariableElementX(
- String name, GenericElement enclosing, this.index, this.node)
- : super(name, ElementKind.TYPE_VARIABLE, enclosing);
-
- GenericElement get typeDeclaration => enclosingElement;
-
- ResolutionTypeVariableType computeType(Resolution resolution) => type;
-
- ResolutionTypeVariableType get type {
- assert(
- typeCache != null, failedAt(this, "Type has not been set on $this."));
- return typeCache;
- }
-
- ResolutionDartType get bound {
- assert(
- boundCache != null, failedAt(this, "Bound has not been set on $this."));
- return boundCache;
- }
-
- bool get hasNode => true;
-
- Node parseNode(ParsingContext parsing) => node;
-
- Token get position => node.getBeginToken();
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitTypeVariableElement(this, arg);
- }
-
- // A type variable cannot be patched therefore defines itself.
- AstElement get definingElement => this;
-}
-
-/**
- * A single metadata annotation.
- *
- * For example, consider:
- *
- * class Data {
- * const Data();
- * }
- *
- * const data = const Data();
- *
- * @data
- * class Foo {}
- *
- * @data @data
- * class Bar {}
- *
- * In this example, there are three instances of [MetadataAnnotation]
- * and they correspond each to a location in the source code where
- * there is an at-sign, '@'. The [constant] of each of these instances
- * are the same compile-time constant, [: const Data() :].
- *
- * The mirror system does not have a concept matching this class.
- */
-abstract class MetadataAnnotationX implements MetadataAnnotation {
- /**
- * The compile-time constant which this annotation resolves to.
- * In the mirror system, this would be an object mirror.
- */
- ConstantExpression constant;
- Element annotatedElement;
- int resolutionState;
-
- /**
- * The beginning token of this annotation, or [:null:] if it is synthetic.
- */
- Token get beginToken;
-
- Token get endToken;
-
- final int hashCode = ElementX.newHashCode();
-
- MetadataAnnotationX([this.resolutionState = STATE_NOT_STARTED]);
-
- MetadataAnnotation ensureResolved(Resolution resolution) {
- if (annotatedElement.isClass || annotatedElement.isTypedef) {
- TypeDeclarationElement typeDeclaration = annotatedElement;
- typeDeclaration.ensureResolved(resolution);
- }
- if (resolutionState == STATE_NOT_STARTED) {
- resolution.resolveMetadataAnnotation(this);
- }
- return this;
- }
-
- Node parseNode(ParsingContext parsing);
-
- SourceSpan get sourcePosition {
- Uri uri = annotatedElement.compilationUnit.script.resourceUri;
- return new SourceSpan.fromTokens(uri, beginToken, endToken);
- }
-
- String toString() => 'MetadataAnnotation($constant, $resolutionState)';
-}
-
-/// Metadata annotation on a parameter.
-class ParameterMetadataAnnotation extends MetadataAnnotationX {
- final Metadata metadata;
-
- ParameterMetadataAnnotation(Metadata this.metadata);
-
- Node parseNode(ParsingContext parsing) => metadata.expression;
-
- Token get beginToken => metadata.getBeginToken();
-
- Token get endToken => metadata.getEndToken();
-
- bool get hasNode => true;
-
- Metadata get node => metadata;
-}
-
-/// Mixin for the implementation of patched elements.
-///
-/// See `patch_parser.dart` for a description of the terminology.
-abstract class PatchMixin<E extends Element> implements Element {
- E patch = null;
- E origin = null;
-
- bool get isPatch => origin != null;
- bool get isPatched => patch != null;
-
- bool get isImplementation => !isPatched;
- bool get isDeclaration => !isPatch;
-
- E get implementation => isPatched ? patch : this;
- E get declaration => isPatch ? origin : this;
-
- /// Applies a patch to this element. This method must be called at most once.
- void applyPatch(PatchMixin<E> patch) {
- assert(this.patch == null, failedAt(this, "Element is patched twice."));
- assert(this.origin == null, failedAt(this, "Origin element is a patch."));
- assert(patch.origin == null, failedAt(patch, "Element is patched twice."));
- assert(patch.patch == null, failedAt(patch, "Patch element is patched."));
- this.patch = patch as E;
- patch.origin = this as E;
- }
-}
-
-/// Abstract implementation of the [AstElement] interface.
-abstract class AstElementMixin implements AstElement {
- /// The element whose node defines this element.
- ///
- /// For patched functions the defining element is the patch element found
- /// through [implementation] since its node define the implementation of the
- /// function. For patched classes the defining element is the origin element
- /// found through [declaration] since its node define the inheritance relation
- /// for the class. For unpatched elements the defining element is the element
- /// itself.
- AstElement get definingElement;
-
- bool get hasResolvedAst {
- return definingElement.hasNode && definingElement.hasTreeElements;
- }
-
- ResolvedAst get resolvedAst {
- Node node = definingElement.node;
- Node body;
- if (definingElement.isField) {
- FieldElement field = definingElement;
- body = field.initializer;
- } else if (node != null && node.asFunctionExpression() != null) {
- body = node.asFunctionExpression().body;
- }
- return new ParsedResolvedAst(
- declaration,
- node,
- body,
- definingElement.treeElements,
- definingElement.compilationUnit.script.resourceUri);
- }
-}
diff --git a/pkg/compiler/lib/src/elements/operators.dart b/pkg/compiler/lib/src/elements/operators.dart
index adf1813..ddc9cff3 100644
--- a/pkg/compiler/lib/src/elements/operators.dart
+++ b/pkg/compiler/lib/src/elements/operators.dart
@@ -322,197 +322,3 @@
String get selectorName => '??';
}
-
-enum AssignmentOperatorKind {
- ASSIGN,
- IF_NULL,
- ADD,
- SUB,
- MUL,
- DIV,
- IDIV,
- MOD,
- SHL,
- SHR,
- AND,
- OR,
- XOR,
-}
-
-class AssignmentOperator {
- final AssignmentOperatorKind kind;
- final BinaryOperator binaryOperator;
- final String name;
- final bool isUserDefinable;
-
- const AssignmentOperator._(this.kind, this.name, this.binaryOperator,
- {this.isUserDefinable: true});
-
- String get selectorName {
- return binaryOperator != null ? binaryOperator.selectorName : null;
- }
-
- String toString() => name;
-
- /// The = operator.
- static const AssignmentOperator ASSIGN = const AssignmentOperator._(
- AssignmentOperatorKind.ASSIGN, '=', null,
- isUserDefinable: false);
-
- /// The ??= operator.
- static const AssignmentOperator IF_NULL = const AssignmentOperator._(
- AssignmentOperatorKind.IF_NULL, '??=', BinaryOperator.IF_NULL,
- isUserDefinable: false);
-
- /// The += assignment operator.
- static const AssignmentOperator ADD = const AssignmentOperator._(
- AssignmentOperatorKind.ADD, '+=', BinaryOperator.ADD);
-
- /// The -= assignment operator.
- static const AssignmentOperator SUB = const AssignmentOperator._(
- AssignmentOperatorKind.SUB, '-=', BinaryOperator.SUB);
-
- /// The *= assignment operator.
- static const AssignmentOperator MUL = const AssignmentOperator._(
- AssignmentOperatorKind.MUL, '*=', BinaryOperator.MUL);
-
- /// The /= assignment operator.
- static const AssignmentOperator DIV = const AssignmentOperator._(
- AssignmentOperatorKind.DIV, '/=', BinaryOperator.DIV);
-
- /// The ~/= assignment operator.
- static const AssignmentOperator IDIV = const AssignmentOperator._(
- AssignmentOperatorKind.IDIV, '~/=', BinaryOperator.IDIV);
-
- /// The %= assignment operator.
- static const AssignmentOperator MOD = const AssignmentOperator._(
- AssignmentOperatorKind.MOD, '%=', BinaryOperator.MOD);
-
- /// The <<= assignment operator.
- static const AssignmentOperator SHL = const AssignmentOperator._(
- AssignmentOperatorKind.SHL, '<<=', BinaryOperator.SHL);
-
- /// The >>= assignment operator.
- static const AssignmentOperator SHR = const AssignmentOperator._(
- AssignmentOperatorKind.SHR, '>>=', BinaryOperator.SHR);
-
- /// The &= assignment operator.
- static const AssignmentOperator AND = const AssignmentOperator._(
- AssignmentOperatorKind.AND, '&=', BinaryOperator.AND);
-
- /// The |= assignment operator.
- static const AssignmentOperator OR = const AssignmentOperator._(
- AssignmentOperatorKind.OR, '|=', BinaryOperator.OR);
-
- /// The ^= assignment operator.
- static const AssignmentOperator XOR = const AssignmentOperator._(
- AssignmentOperatorKind.XOR, '^=', BinaryOperator.XOR);
-
- static AssignmentOperator parse(String value) {
- switch (value) {
- case '=':
- return ASSIGN;
- case '??=':
- return IF_NULL;
- case '*=':
- return MUL;
- case '/=':
- return DIV;
- case '%=':
- return MOD;
- case '~/=':
- return IDIV;
- case '+=':
- return ADD;
- case '-=':
- return SUB;
- case '<<=':
- return SHL;
- case '>>=':
- return SHR;
- case '&=':
- return AND;
- case '^=':
- return XOR;
- case '|=':
- return OR;
- default:
- return null;
- }
- }
-
- // ignore: MISSING_RETURN
- static AssignmentOperator fromKind(AssignmentOperatorKind kind) {
- switch (kind) {
- case AssignmentOperatorKind.ASSIGN:
- return ASSIGN;
- case AssignmentOperatorKind.IF_NULL:
- return IF_NULL;
- case AssignmentOperatorKind.ADD:
- return ADD;
- case AssignmentOperatorKind.SUB:
- return SUB;
- case AssignmentOperatorKind.MUL:
- return MUL;
- case AssignmentOperatorKind.DIV:
- return DIV;
- case AssignmentOperatorKind.IDIV:
- return IDIV;
- case AssignmentOperatorKind.MOD:
- return MOD;
- case AssignmentOperatorKind.SHL:
- return SHL;
- case AssignmentOperatorKind.SHR:
- return SHR;
- case AssignmentOperatorKind.AND:
- return AND;
- case AssignmentOperatorKind.OR:
- return OR;
- case AssignmentOperatorKind.XOR:
- return XOR;
- }
- }
-}
-
-enum IncDecOperatorKind { INC, DEC }
-
-class IncDecOperator {
- final IncDecOperatorKind kind;
- final String name;
- final BinaryOperator binaryOperator;
-
- const IncDecOperator._(this.kind, this.name, this.binaryOperator);
-
- String get selectorName => binaryOperator.selectorName;
-
- String toString() => name;
-
- /// The prefix/postfix ++ operator.
- static const IncDecOperator INC =
- const IncDecOperator._(IncDecOperatorKind.INC, '++', BinaryOperator.ADD);
-
- /// The prefix/postfix -- operator.
- static const IncDecOperator DEC =
- const IncDecOperator._(IncDecOperatorKind.DEC, '--', BinaryOperator.SUB);
-
- static IncDecOperator parse(String value) {
- switch (value) {
- case '++':
- return INC;
- case '--':
- return DEC;
- default:
- return null;
- }
- }
-
- // ignore: MISSING_RETURN
- static IncDecOperator fromKind(IncDecOperatorKind kind) {
- switch (kind) {
- case IncDecOperatorKind.INC:
- return INC;
- case IncDecOperatorKind.DEC:
- return DEC;
- }
- }
-}
diff --git a/pkg/compiler/lib/src/elements/resolution_types.dart b/pkg/compiler/lib/src/elements/resolution_types.dart
deleted file mode 100644
index 3c0949f..0000000
--- a/pkg/compiler/lib/src/elements/resolution_types.dart
+++ /dev/null
@@ -1,1879 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Implementation of the Dart types hierarchy in 'types.dart' specifically
-/// tailored to the resolution phase of the compiler.
-
-library resolution_types;
-
-import 'dart:math' show min;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common_elements.dart';
-import '../ordered_typeset.dart' show OrderedTypeSet;
-import '../util/util.dart' show equalElements;
-import 'elements.dart';
-import 'entities.dart';
-import 'modelx.dart' show TypeDeclarationElementX;
-import 'names.dart';
-import 'types.dart';
-
-enum ResolutionTypeKind {
- FUNCTION,
- INTERFACE,
- TYPEDEF,
- TYPE_VARIABLE,
- MALFORMED_TYPE,
- DYNAMIC,
- VOID,
-}
-
-abstract class ResolutionDartType implements DartType {
- String get name;
-
- ResolutionTypeKind get kind;
-
- const ResolutionDartType();
-
- /**
- * Returns the [Element] which declared this type.
- *
- * This can be [ClassElement] for classes, [TypedefElement] for typedefs,
- * [TypeVariableElement] for type variables and [FunctionElement] for
- * function types.
- *
- * Invariant: [element] must be a declaration element.
- */
- Element get element;
-
- /**
- * Performs the substitution [: [arguments[i]/parameters[i]]this :].
- *
- * The notation is known from this lambda calculus rule:
- *
- * (lambda x.e0)e1 -> [e1/x]e0.
- *
- * See [ResolutionTypeVariableType] for a motivation for this method.
- *
- * Invariant: There must be the same number of [arguments] and [parameters].
- */
- ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters);
-
- /// Performs the substitution of the type arguments of [type] for their
- /// corresponding type variables in this type.
- ResolutionDartType substByContext(GenericType type) {
- return subst(type.typeArguments, type.element.typeVariables);
- }
-
- /// Computes the unaliased type of this type.
- ///
- /// The unaliased type of a typedef'd type is the unaliased type to which its
- /// name is bound. The unaliased version of any other type is the type itself.
- ///
- /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the
- /// function type `(B) -> A` and the unaliased type of `Func<int,String>`
- /// is the function type `(String) -> int`.
- // TODO(johnniwinther): Maybe move this to [TypedefType].
- void computeUnaliased(Resolution resolution) {}
-
- /// Returns the unaliased type of this type.
- ///
- /// The unaliased type of a typedef'd type is the unaliased type to which its
- /// name is bound. The unaliased version of any other type is the type itself.
- ///
- /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the
- /// function type `(B) -> A` and the unaliased type of `Func<int,String>`
- /// is the function type `(String) -> int`.
- ResolutionDartType get unaliased => this;
-
- /**
- * If this type is malformed or a generic type created with the wrong number
- * of type arguments then [userProvidedBadType] holds the bad type provided
- * by the user.
- */
- ResolutionDartType get userProvidedBadType => null;
-
- /// Is [: true :] if this type has no explicit type arguments.
- bool get isRaw => true;
-
- /// Returns the raw version of this type.
- ResolutionDartType asRaw() => this;
-
- /// Is [: true :] if this type has no non-dynamic type arguments.
- bool get treatAsRaw => isRaw;
-
- /// Is [: true :] if this type should be treated as the dynamic type.
- bool get treatAsDynamic => false;
-
- /// Is [: true :] if this type is the dynamic type.
- bool get isDynamic => kind == ResolutionTypeKind.DYNAMIC;
-
- /// Is [: true :] if this type is the void type.
- bool get isVoid => kind == ResolutionTypeKind.VOID;
-
- /// Is [: true :] if this is the type of `Object` from dart:core.
- bool get isObject => false;
-
- /// Is [: true :] if this type is an interface type.
- bool get isInterfaceType => kind == ResolutionTypeKind.INTERFACE;
-
- /// Is [: true :] if this type is a typedef.
- bool get isTypedef => kind == ResolutionTypeKind.TYPEDEF;
-
- /// Is [: true :] if this type is a function type.
- bool get isFunctionType => kind == ResolutionTypeKind.FUNCTION;
-
- /// Is [: true :] if this type is a type variable.
- bool get isTypeVariable => kind == ResolutionTypeKind.TYPE_VARIABLE;
-
- @override
- bool get isFunctionTypeVariable => false;
-
- @override
- bool get isFutureOr => false;
-
- /// Is [: true :] if this type is a malformed type.
- bool get isMalformed => false;
-
- /// Is `true` if this type is declared by an enum.
- bool get isEnumType => false;
-
- /// Returns an occurrence of a type variable within this type, if any.
- ResolutionTypeVariableType get typeVariableOccurrence => null;
-
- /// Applies [f] to each occurence of a [ResolutionTypeVariableType] within
- /// this type.
- void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {}
-
- ResolutionTypeVariableType _findTypeVariableOccurrence(
- List<ResolutionDartType> types) {
- for (ResolutionDartType type in types) {
- ResolutionTypeVariableType typeVariable = type.typeVariableOccurrence;
- if (typeVariable != null) {
- return typeVariable;
- }
- }
- return null;
- }
-
- /// Is [: true :] if this type contains any type variables.
- bool get containsTypeVariables => typeVariableOccurrence != null;
-
- bool get containsFreeTypeVariables {
- assert(!containsMethodTypeVariableType,
- 'Used only after removing method type variables');
- return containsTypeVariables;
- }
-
- /// Returns a textual representation of this type as if it was the type
- /// of a member named [name].
- String getStringAsDeclared(String name) {
- return new TypeDeclarationFormatter().format(this, name);
- }
-
- R accept<R, A>(covariant ResolutionDartTypeVisitor<R, A> visitor, A argument);
-
- void visitChildren<R, A>(
- ResolutionDartTypeVisitor<R, A> visitor, A argument) {}
-
- static void visitList<R, A>(List<ResolutionDartType> types,
- ResolutionDartTypeVisitor<R, A> visitor, A argument) {
- for (ResolutionDartType type in types) {
- type.accept(visitor, argument);
- }
- }
-
- /// Returns a [ResolutionDartType] which corresponds to [this] except that
- /// each contained [MethodTypeVariableType] is replaced by a
- /// [ResolutionDynamicType].
- /// GENERIC_METHODS: Temporary, only used with '--generic-method-syntax'.
- ResolutionDartType get dynamifyMethodTypeVariableType => this;
-
- /// Returns true iff [this] is or contains a [MethodTypeVariableType].
- /// GENERIC_METHODS: Temporary, only used with '--generic-method-syntax'
- bool get containsMethodTypeVariableType => false;
-}
-
-/**
- * Represents a type variable, that is the type parameters of a class type.
- *
- * For example, in [: class Array<E> { ... } :], E is a type variable.
- *
- * Each class should have its own unique type variables, one for each type
- * parameter. A class with type parameters is said to be parameterized or
- * generic.
- *
- * Non-static members, constructors, and factories of generic
- * class/interface can refer to type variables of the current class
- * (not of supertypes).
- *
- * When using a generic type, also known as an application or
- * instantiation of the type, the actual type arguments should be
- * substituted for the type variables in the class declaration.
- *
- * For example, given a box, [: class Box<T> { T value; } :], the
- * type of the expression [: new Box<String>().value :] is
- * [: String :] because we must substitute [: String :] for the
- * the type variable [: T :].
- */
-class ResolutionTypeVariableType extends ResolutionDartType
- implements TypeVariableType {
- final TypeVariableElement element;
-
- ResolutionTypeVariableType(this.element);
-
- ResolutionTypeKind get kind => ResolutionTypeKind.TYPE_VARIABLE;
-
- String get name => element.name;
-
- ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) {
- assert(arguments.length == parameters.length);
- if (parameters.isEmpty) {
- // Return fast on empty substitutions.
- return this;
- }
- for (int index = 0; index < arguments.length; index++) {
- ResolutionTypeVariableType parameter = parameters[index];
- ResolutionDartType argument = arguments[index];
- if (parameter == this) {
- return argument;
- }
- }
- // The type variable was not substituted.
- return this;
- }
-
- ResolutionTypeVariableType get typeVariableOccurrence => this;
-
- void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {
- f(this);
- }
-
- R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
- return visitor.visitTypeVariableType(this, argument);
- }
-
- int get hashCode => 17 * element.hashCode;
-
- bool operator ==(other) {
- if (other is! ResolutionTypeVariableType) return false;
- return identical(other.element, element);
- }
-
- String toString() => '${element.typeDeclaration.name}.$name';
-}
-
-/// Provides a thin model of method type variables: They are treated as if
-/// their value were `dynamic` when used in a type annotation, and as a
-/// malformed type when used in an `as` or `is` expression.
-class MethodTypeVariableType extends ResolutionTypeVariableType {
- MethodTypeVariableType(TypeVariableElement element) : super(element);
-
- @override
- bool get treatAsDynamic => true;
-
- @override
- bool get isMalformed => true;
-
- @override
- ResolutionDartType get dynamifyMethodTypeVariableType =>
- const ResolutionDynamicType();
-
- @override
- get containsMethodTypeVariableType => true;
-}
-
-class ResolutionVoidType extends ResolutionDartType implements VoidType {
- const ResolutionVoidType();
-
- ResolutionTypeKind get kind => ResolutionTypeKind.VOID;
-
- String get name => 'void';
-
- Element get element => null;
-
- ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) {
- // Void cannot be substituted.
- return this;
- }
-
- R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
- return visitor.visitVoidType(this, argument);
- }
-
- String toString() => name;
-
- int get hashCode => 6007;
-}
-
-class MalformedType extends ResolutionDartType {
- final ErroneousElement element;
-
- /**
- * [declaredType] holds the type which the user wrote in code.
- *
- * For instance, for a resolved but malformed type like [: Map<String> :] the
- * [declaredType] is [: Map<String> :] whereas for an unresolved type
- * [userProvidedBadType] is [: null :].
- */
- final ResolutionDartType userProvidedBadType;
-
- /**
- * Type arguments for the malformed typed, if these cannot fit in the
- * [declaredType].
- *
- * This field is for instance used for [: dynamic<int> :] and [: T<int> :]
- * where [: T :] is a type variable, in which case [declaredType] holds
- * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :]
- * is not resolved or does not imply a type.
- */
- final List<ResolutionDartType> typeArguments;
-
- final int hashCode = _nextHash = (_nextHash + 1).toUnsigned(30);
- static int _nextHash = 43765;
-
- MalformedType(this.element, this.userProvidedBadType,
- [this.typeArguments = null]);
-
- ResolutionTypeKind get kind => ResolutionTypeKind.MALFORMED_TYPE;
-
- String get name => element.name;
-
- ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) {
- // Malformed types are not substitutable.
- return this;
- }
-
- // Malformed types are treated as dynamic.
- bool get treatAsDynamic => true;
-
- @override
- bool get isMalformed => true;
-
- R accept<R, A>(
- covariant ResolutionDartTypeVisitor<R, A> visitor, A argument) {
- return visitor.visitMalformedType(this, argument);
- }
-
- String toString() {
- var sb = new StringBuffer();
- if (typeArguments != null) {
- if (userProvidedBadType != null) {
- sb.write(userProvidedBadType.name);
- } else {
- sb.write(element.name);
- }
- if (!typeArguments.isEmpty) {
- sb.write('<');
- sb.write(typeArguments.join(', '));
- sb.write('>');
- }
- } else {
- sb.write(userProvidedBadType.toString());
- }
- return sb.toString();
- }
-}
-
-abstract class GenericType extends ResolutionDartType {
- final TypeDeclarationElement element;
- final List<ResolutionDartType> typeArguments;
-
- GenericType(
- TypeDeclarationElement element, List<ResolutionDartType> typeArguments,
- {bool checkTypeArgumentCount: true})
- : this.element = element,
- this.typeArguments = typeArguments,
- this.containsMethodTypeVariableType =
- typeArguments.any(_typeContainsMethodTypeVariableType) {
- assert(
- element != null,
- failedAt(
- CURRENT_ELEMENT_SPANNABLE, "Missing element for generic type."));
- assert(() {
- if (!checkTypeArgumentCount) return true;
- if (element is TypeDeclarationElementX) {
- return element.thisTypeCache == null ||
- typeArguments.length == element.typeVariables.length;
- }
- return true;
- }(),
- failedAt(
- element,
- 'Invalid type argument count on ${element.thisType}. '
- 'Provided type arguments: $typeArguments.'));
- }
-
- /// Creates a new instance of this type using the provided type arguments.
- GenericType createInstantiation(List<ResolutionDartType> newTypeArguments);
-
- GenericType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) {
- if (typeArguments.isEmpty) {
- // Return fast on non-generic types.
- return this;
- }
- if (parameters.isEmpty) {
- assert(arguments.isEmpty);
- // Return fast on empty substitutions.
- return this;
- }
- List<ResolutionDartType> newTypeArguments =
- Types.substTypes(typeArguments, arguments, parameters);
- if (!identical(typeArguments, newTypeArguments)) {
- // Create a new type only if necessary.
- return createInstantiation(newTypeArguments);
- }
- return this;
- }
-
- ResolutionTypeVariableType get typeVariableOccurrence {
- return _findTypeVariableOccurrence(typeArguments);
- }
-
- void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {
- for (ResolutionDartType type in typeArguments) {
- type.forEachTypeVariable(f);
- }
- }
-
- void visitChildren<R, A>(
- ResolutionDartTypeVisitor<R, A> visitor, var argument) {
- ResolutionDartType.visitList(typeArguments, visitor, argument);
- }
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.write(name);
- if (!isRaw) {
- sb.write('<');
- sb.write(typeArguments.join(', '));
- sb.write('>');
- }
- return sb.toString();
- }
-
- @override
- final bool containsMethodTypeVariableType;
-
- @override
- ResolutionDartType get dynamifyMethodTypeVariableType {
- if (!containsMethodTypeVariableType) return this;
- List<ResolutionDartType> newTypeArguments = typeArguments
- .map((ResolutionDartType type) => type.dynamifyMethodTypeVariableType)
- .toList();
- return createInstantiation(newTypeArguments);
- }
-
- int get hashCode {
- int hash = element.hashCode;
- for (ResolutionDartType argument in typeArguments) {
- int argumentHash = argument != null ? argument.hashCode : 0;
- hash = 17 * hash + 3 * argumentHash;
- }
- return hash;
- }
-
- bool operator ==(other) {
- if (other is! GenericType) return false;
- return kind == other.kind &&
- element == other.element &&
- equalElements(typeArguments, other.typeArguments);
- }
-
- /// Returns `true` if the declaration of this type has type variables.
- bool get isGeneric => !typeArguments.isEmpty;
-
- bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
-
- GenericType asRaw() => element.rawType;
-
- bool get treatAsRaw {
- if (isRaw) return true;
- for (ResolutionDartType type in typeArguments) {
- if (!type.treatAsDynamic) return false;
- }
- return true;
- }
-}
-
-class ResolutionInterfaceType extends GenericType implements InterfaceType {
- int _hashCode;
-
- ResolutionInterfaceType(ClassElement element,
- [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
- : super(element, typeArguments) {
- assert(element.isDeclaration, failedAt(element));
- }
-
- ResolutionInterfaceType.forUserProvidedBadType(ClassElement element,
- [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
- : super(element, typeArguments, checkTypeArgumentCount: false);
-
- ClassElement get element => super.element;
-
- ResolutionTypeKind get kind => ResolutionTypeKind.INTERFACE;
-
- String get name => element.name;
-
- bool get isObject => element.isObject;
-
- bool get isEnumType => element.isEnumClass;
-
- ResolutionInterfaceType createInstantiation(
- List<ResolutionDartType> newTypeArguments) {
- return new ResolutionInterfaceType(element, newTypeArguments);
- }
-
- /**
- * Returns the type as an instance of class [other], if possible, null
- * otherwise.
- */
- ResolutionInterfaceType asInstanceOf(ClassElement other) {
- other = other.declaration;
- if (element == other) return this;
- ResolutionInterfaceType supertype = element.asInstanceOf(other);
- if (supertype != null) {
- List<ResolutionDartType> arguments = Types.substTypes(
- supertype.typeArguments, typeArguments, element.typeVariables);
- return new ResolutionInterfaceType(supertype.element, arguments);
- }
- return null;
- }
-
- MemberSignature lookupInterfaceMember(Name name) {
- MemberSignature member = element.lookupInterfaceMember(name);
- if (member != null && isGeneric) {
- return new InterfaceMember(this, member);
- }
- return member;
- }
-
- MemberSignature lookupClassMember(Name name) {
- MemberSignature member = element.lookupClassMember(name);
- if (member != null && isGeneric) {
- return new InterfaceMember(this, member);
- }
- return member;
- }
-
- int get hashCode => _hashCode ??= super.hashCode;
-
- ResolutionInterfaceType asRaw() => super.asRaw();
-
- R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
- return visitor.visitInterfaceType(this, argument);
- }
-
- /// Returns the type of the 'call' method in this interface type, or
- /// `null` if the interface type has no 'call' method.
- ResolutionFunctionType get callType {
- ResolutionFunctionType type = element.callType;
- return type != null && isGeneric ? type.substByContext(this) : type;
- }
-
- ResolutionInterfaceType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) {
- return super.subst(arguments, parameters);
- }
-}
-
-/// Special subclass of [ResolutionInterfaceType] used for generic interface
-/// types created with the wrong number of type arguments.
-///
-/// The type uses `dynamic` for all it s type arguments.
-class BadInterfaceType extends ResolutionInterfaceType {
- final ResolutionInterfaceType userProvidedBadType;
-
- BadInterfaceType(
- ClassElement element, ResolutionInterfaceType this.userProvidedBadType)
- : super(element, element.rawType.typeArguments);
-
- String toString() {
- return userProvidedBadType.toString();
- }
-}
-
-/**
- * Special subclass of [ResolutionTypedefType] used for generic typedef types
- * created with the wrong number of type arguments.
- *
- * The type uses [:dynamic:] for all it s type arguments.
- */
-class BadTypedefType extends ResolutionTypedefType {
- final ResolutionTypedefType userProvidedBadType;
-
- BadTypedefType(
- TypedefElement element, ResolutionTypedefType this.userProvidedBadType)
- : super(element, element.rawType.typeArguments);
-
- String toString() {
- return userProvidedBadType.toString();
- }
-}
-
-class ResolutionFunctionType extends ResolutionDartType
- implements FunctionType {
- final FunctionTypedElement element;
- final ResolutionDartType returnType;
- final List<ResolutionDartType> parameterTypes;
- final List<ResolutionDartType> optionalParameterTypes;
-
- /**
- * The names of the named parameters ordered lexicographically.
- */
- final List<String> namedParameters;
-
- /**
- * The types of the named parameters in the order corresponding to the
- * [namedParameters].
- */
- final List<ResolutionDartType> namedParameterTypes;
-
- TypedefType get typedefType => null;
-
- factory ResolutionFunctionType(FunctionTypedElement element,
- [ResolutionDartType returnType = const ResolutionDynamicType(),
- List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],
- List<ResolutionDartType> optionalParameterTypes =
- const <ResolutionDartType>[],
- List<String> namedParameters = const <String>[],
- List<ResolutionDartType> namedParameterTypes =
- const <ResolutionDartType>[]]) {
- assert(element != null, failedAt(CURRENT_ELEMENT_SPANNABLE));
- assert(element.isDeclaration, failedAt(element));
- return new ResolutionFunctionType.internal(
- element,
- returnType,
- parameterTypes,
- optionalParameterTypes,
- namedParameters,
- namedParameterTypes);
- }
-
- factory ResolutionFunctionType.synthesized(
- [ResolutionDartType returnType = const ResolutionDynamicType(),
- List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],
- List<ResolutionDartType> optionalParameterTypes =
- const <ResolutionDartType>[],
- List<String> namedParameters = const <String>[],
- List<ResolutionDartType> namedParameterTypes =
- const <ResolutionDartType>[]]) {
- return new ResolutionFunctionType.internal(null, returnType, parameterTypes,
- optionalParameterTypes, namedParameters, namedParameterTypes);
- }
-
- factory ResolutionFunctionType.generalized(
- ResolutionDartType returnType,
- List<ResolutionDartType> parameterTypes,
- List<ResolutionDartType> optionalParameterTypes,
- List<String> namedParameters,
- List<ResolutionDartType> namedParameterTypes) {
- return new ResolutionFunctionType.internal(null, returnType, parameterTypes,
- optionalParameterTypes, namedParameters, namedParameterTypes);
- }
-
- ResolutionFunctionType.internal(FunctionTypedElement this.element,
- [ResolutionDartType returnType = const ResolutionDynamicType(),
- List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],
- List<ResolutionDartType> optionalParameterTypes =
- const <ResolutionDartType>[],
- List<String> namedParameters = const <String>[],
- List<ResolutionDartType> namedParameterTypes =
- const <ResolutionDartType>[]])
- : this.returnType = returnType,
- this.parameterTypes = parameterTypes,
- this.optionalParameterTypes = optionalParameterTypes,
- this.namedParameters = namedParameters,
- this.namedParameterTypes = namedParameterTypes,
- this.containsMethodTypeVariableType = returnType
- .containsMethodTypeVariableType ||
- parameterTypes.any(_typeContainsMethodTypeVariableType) ||
- optionalParameterTypes.any(_typeContainsMethodTypeVariableType) ||
- namedParameterTypes.any(_typeContainsMethodTypeVariableType) {
- assert(element == null || element.isDeclaration,
- failedAt(CURRENT_ELEMENT_SPANNABLE));
- // Assert that optional and named parameters are not used at the same time.
- assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty);
- assert(namedParameters.length == namedParameterTypes.length);
- }
-
- @override
- final List<FunctionTypeVariable> typeVariables =
- const <FunctionTypeVariable>[];
-
- FunctionType instantiate(List<DartType> arguments) {
- throw new UnsupportedError("ResolutionFunctionType.instantiate");
- }
-
- ResolutionTypeKind get kind => ResolutionTypeKind.FUNCTION;
-
- ResolutionDartType getNamedParameterType(String name) {
- for (int i = 0; i < namedParameters.length; i++) {
- if (namedParameters[i] == name) {
- return namedParameterTypes[i];
- }
- }
- return null;
- }
-
- ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) {
- if (parameters.isEmpty) {
- assert(arguments.isEmpty);
- // Return fast on empty substitutions.
- return this;
- }
- ResolutionDartType newReturnType = returnType.subst(arguments, parameters);
- bool changed = !identical(newReturnType, returnType);
- List<ResolutionDartType> newParameterTypes =
- Types.substTypes(parameterTypes, arguments, parameters);
- List<ResolutionDartType> newOptionalParameterTypes =
- Types.substTypes(optionalParameterTypes, arguments, parameters);
- List<ResolutionDartType> newNamedParameterTypes =
- Types.substTypes(namedParameterTypes, arguments, parameters);
- if (!changed &&
- (!identical(parameterTypes, newParameterTypes) ||
- !identical(optionalParameterTypes, newOptionalParameterTypes) ||
- !identical(namedParameterTypes, newNamedParameterTypes))) {
- changed = true;
- }
- if (changed) {
- // Create a new type only if necessary.
- return new ResolutionFunctionType.internal(
- element,
- newReturnType,
- newParameterTypes,
- newOptionalParameterTypes,
- namedParameters,
- newNamedParameterTypes);
- }
- return this;
- }
-
- ResolutionTypeVariableType get typeVariableOccurrence {
- ResolutionTypeVariableType typeVariableType =
- returnType.typeVariableOccurrence;
- if (typeVariableType != null) return typeVariableType;
-
- typeVariableType = _findTypeVariableOccurrence(parameterTypes);
- if (typeVariableType != null) return typeVariableType;
-
- typeVariableType = _findTypeVariableOccurrence(optionalParameterTypes);
- if (typeVariableType != null) return typeVariableType;
-
- return _findTypeVariableOccurrence(namedParameterTypes);
- }
-
- void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {
- returnType.forEachTypeVariable(f);
- parameterTypes.forEach((ResolutionDartType type) {
- type.forEachTypeVariable(f);
- });
- optionalParameterTypes.forEach((ResolutionDartType type) {
- type.forEachTypeVariable(f);
- });
- namedParameterTypes.forEach((ResolutionDartType type) {
- type.forEachTypeVariable(f);
- });
- }
-
- R accept<R, A>(covariant DartTypeVisitor<R, A> visitor, A argument) {
- return visitor.visitFunctionType(this, argument);
- }
-
- void visitChildren<R, A>(
- ResolutionDartTypeVisitor<R, A> visitor, var argument) {
- returnType.accept(visitor, argument);
- ResolutionDartType.visitList(parameterTypes, visitor, argument);
- ResolutionDartType.visitList(optionalParameterTypes, visitor, argument);
- ResolutionDartType.visitList(namedParameterTypes, visitor, argument);
- }
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.write('(');
- sb.write(parameterTypes.join(', '));
- bool first = parameterTypes.isEmpty;
- if (!optionalParameterTypes.isEmpty) {
- if (!first) {
- sb.write(', ');
- }
- sb.write('[');
- sb.write(optionalParameterTypes.join(', '));
- sb.write(']');
- first = false;
- }
- if (!namedParameterTypes.isEmpty) {
- if (!first) {
- sb.write(', ');
- }
- sb.write('{');
- first = true;
- for (int i = 0; i < namedParameters.length; i++) {
- if (!first) {
- sb.write(', ');
- }
- sb.write(namedParameterTypes[i]);
- sb.write(' ');
- sb.write(namedParameters[i]);
- first = false;
- }
- sb.write('}');
- }
- sb.write(') -> ${returnType}');
- return sb.toString();
- }
-
- String get name => 'Function';
-
- @override
- ResolutionDartType get dynamifyMethodTypeVariableType {
- if (!containsMethodTypeVariableType) return this;
- ResolutionDartType eraseIt(ResolutionDartType type) =>
- type.dynamifyMethodTypeVariableType;
- ResolutionDartType newReturnType =
- returnType.dynamifyMethodTypeVariableType;
- List<ResolutionDartType> newParameterTypes =
- parameterTypes.map(eraseIt).toList();
- List<ResolutionDartType> newOptionalParameterTypes =
- optionalParameterTypes.map(eraseIt).toList();
- List<ResolutionDartType> newNamedParameterTypes =
- namedParameterTypes.map(eraseIt).toList();
- return new ResolutionFunctionType.internal(
- element,
- newReturnType,
- newParameterTypes,
- newOptionalParameterTypes,
- namedParameters,
- newNamedParameterTypes);
- }
-
- @override
- final bool containsMethodTypeVariableType;
-
- int get hashCode {
- int hash = 3 * returnType.hashCode;
- for (ResolutionDartType parameter in parameterTypes) {
- hash = 17 * hash + 5 * parameter.hashCode;
- }
- for (ResolutionDartType parameter in optionalParameterTypes) {
- hash = 19 * hash + 7 * parameter.hashCode;
- }
- for (String name in namedParameters) {
- hash = 23 * hash + 11 * name.hashCode;
- }
- for (ResolutionDartType parameter in namedParameterTypes) {
- hash = 29 * hash + 13 * parameter.hashCode;
- }
- return hash;
- }
-
- bool operator ==(other) {
- if (other is! ResolutionFunctionType) return false;
- return returnType == other.returnType &&
- equalElements(parameterTypes, other.parameterTypes) &&
- equalElements(optionalParameterTypes, other.optionalParameterTypes) &&
- equalElements(namedParameters, other.namedParameters) &&
- equalElements(namedParameterTypes, other.namedParameterTypes);
- }
-}
-
-bool _typeContainsMethodTypeVariableType(ResolutionDartType type) =>
- type.containsMethodTypeVariableType;
-
-class ResolutionTypedefType extends GenericType implements TypedefType {
- ResolutionDartType _unaliased;
-
- ResolutionTypedefType(TypedefElement element,
- [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
- : super(element, typeArguments);
-
- ResolutionTypedefType.forUserProvidedBadType(TypedefElement element,
- [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
- : super(element, typeArguments, checkTypeArgumentCount: false);
-
- TypedefElement get element => super.element;
-
- ResolutionTypeKind get kind => ResolutionTypeKind.TYPEDEF;
-
- String get name => element.name;
-
- ResolutionTypedefType createInstantiation(
- List<ResolutionDartType> newTypeArguments) {
- return new ResolutionTypedefType(element, newTypeArguments);
- }
-
- ResolutionTypedefType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) {
- return super.subst(arguments, parameters);
- }
-
- void computeUnaliased(Resolution resolution) {
- if (_unaliased == null) {
- element.ensureResolved(resolution);
- if (element.isMalformed) {
- _unaliased = const ResolutionDynamicType();
- return;
- }
- element.checkCyclicReference(resolution);
- element.alias.computeUnaliased(resolution);
- _unaliased = element.alias.unaliased.substByContext(this);
- }
- }
-
- ResolutionDartType get unaliased {
- if (_unaliased == null) {
- ResolutionDartType definition = element.alias.unaliased;
- _unaliased = definition.substByContext(this);
- }
- return _unaliased;
- }
-
- int get hashCode => super.hashCode;
-
- ResolutionTypedefType asRaw() => super.asRaw();
-
- R accept<R, A>(
- covariant ResolutionDartTypeVisitor<R, A> visitor, A argument) {
- return visitor.visitTypedefType(this, argument);
- }
-}
-
-/**
- * Special type for the `dynamic` type.
- */
-class ResolutionDynamicType extends ResolutionDartType implements DynamicType {
- const ResolutionDynamicType();
-
- Element get element => null;
-
- String get name => 'dynamic';
-
- bool get treatAsDynamic => true;
-
- ResolutionTypeKind get kind => ResolutionTypeKind.DYNAMIC;
-
- ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
- covariant List<ResolutionDartType> parameters) =>
- this;
-
- R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
- return visitor.visitDynamicType(this, argument);
- }
-
- int get hashCode => 91;
-
- String toString() => name;
-}
-
-/**
- * [InterfaceMember] encapsulates a member (method, field, property) with
- * the types of the declarer and receiver in order to do substitution on the
- * member type.
- *
- * Consider for instance these classes and the variable `B<String> b`:
- *
- * class A<E> {
- * E field;
- * }
- * class B<F> extends A<F> {}
- *
- * In an [InterfaceMember] for `b.field` the [receiver] is the type
- * `B<String>` and the declarer is the type `A<F>`, which is the supertype of
- * `B<F>` from which `field` has been inherited. To compute the type of
- * `b.field` we must first substitute `E` by `F` using the relation between
- * `A<E>` and `A<F>`, and then `F` by `String` using the relation between
- * `B<F>` and `B<String>`.
- */
-class InterfaceMember implements MemberSignature {
- final ResolutionInterfaceType instance;
- final MemberSignature member;
-
- InterfaceMember(this.instance, this.member);
-
- Name get name => member.name;
-
- ResolutionDartType get type => member.type.substByContext(instance);
-
- ResolutionFunctionType get functionType =>
- member.functionType.substByContext(instance);
-
- bool get isGetter => member.isGetter;
-
- bool get isSetter => member.isSetter;
-
- bool get isMethod => member.isMethod;
-
- Iterable<Member> get declarations => member.declarations;
-}
-
-abstract class ResolutionDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> {
- const ResolutionDartTypeVisitor();
-
- R visitMalformedType(MalformedType type, A argument) => null;
-
- R visitTypedefType(TypedefType type, A argument) => null;
-}
-
-abstract class BaseResolutionDartTypeVisitor<R, A>
- extends BaseDartTypeVisitor<R, A>
- implements ResolutionDartTypeVisitor<R, A> {
- const BaseResolutionDartTypeVisitor();
-
- @override
- R visitMalformedType(MalformedType type, A argument) =>
- visitType(type, argument);
-
- R visitGenericType(GenericType type, A argument) => visitType(type, argument);
-
- @override
- R visitInterfaceType(covariant ResolutionInterfaceType type, A argument) =>
- visitGenericType(type, argument);
-
- @override
- R visitTypedefType(covariant ResolutionTypedefType type, A argument) =>
- visitGenericType(type, argument);
-}
-
-abstract class AbstractTypeRelationMixin
- implements
- AbstractTypeRelation<ResolutionDartType>,
- ResolutionDartTypeVisitor<bool, ResolutionDartType> {
- Resolution get resolution;
-
- @override
- CommonElements get commonElements => resolution.commonElements;
-
- /// Ensures that the super hierarchy of [type] is computed.
- void ensureResolved(covariant ResolutionInterfaceType type) {
- // TODO(johnniwinther): Currently needed since literal types like int,
- // double, bool etc. might not have been resolved yet.
- type.element.ensureResolved(resolution);
- }
-
- /// Returns the unaliased version of [type].
- ResolutionDartType getUnaliased(covariant ResolutionDartType type) {
- type.computeUnaliased(resolution);
- return type.unaliased;
- }
-
- @override
- DartType getTypeVariableBound(covariant TypeVariableElement element) =>
- element.bound;
-
- @override
- FunctionType getCallType(covariant ResolutionInterfaceType type) =>
- type.callType;
-
- @override
- InterfaceType asInstanceOf(
- covariant ResolutionInterfaceType type, ClassEntity cls) =>
- type.asInstanceOf(cls);
-
- /// Handle as dynamic for both subtype and more specific relation to avoid
- /// spurious errors from malformed types.
- bool visitMalformedType(MalformedType t, ResolutionDartType s) => true;
-
- bool visitTypedefType(
- covariant ResolutionTypedefType t, ResolutionDartType s) =>
- visitType(t, s);
-}
-
-class ResolutionMoreSpecificVisitor
- extends MoreSpecificVisitor<ResolutionDartType>
- with AbstractTypeRelationMixin {
- final Resolution resolution;
- bool get strongMode => false;
-
- ResolutionMoreSpecificVisitor(this.resolution);
-}
-
-class ResolutionSubtypeVisitor extends SubtypeVisitor<ResolutionDartType>
- with AbstractTypeRelationMixin {
- final Resolution resolution;
- bool get strongMode => false;
-
- ResolutionSubtypeVisitor(this.resolution);
-}
-
-class ResolutionPotentialSubtypeVisitor
- extends PotentialSubtypeVisitor<ResolutionDartType>
- with AbstractTypeRelationMixin {
- final Resolution resolution;
- bool get strongMode => false;
-
- ResolutionPotentialSubtypeVisitor(this.resolution);
-}
-
-/**
- * Callback used to check whether the [typeArgument] of [type] is a valid
- * substitute for the bound of [typeVariable]. [bound] holds the bound against
- * which [typeArgument] should be checked.
- */
-typedef void CheckTypeVariableBound<T>(T context, DartType typeArgument,
- TypeVariableType typeVariable, DartType bound);
-
-class Types extends DartTypes {
- final Resolution resolution;
- final ResolutionMoreSpecificVisitor moreSpecificVisitor;
- final ResolutionSubtypeVisitor subtypeVisitor;
- final ResolutionPotentialSubtypeVisitor potentialSubtypeVisitor;
-
- CommonElements get commonElements => resolution.commonElements;
-
- DiagnosticReporter get reporter => resolution.reporter;
-
- Types(Resolution resolution)
- : this.resolution = resolution,
- this.moreSpecificVisitor =
- new ResolutionMoreSpecificVisitor(resolution),
- this.subtypeVisitor = new ResolutionSubtypeVisitor(resolution),
- this.potentialSubtypeVisitor =
- new ResolutionPotentialSubtypeVisitor(resolution);
-
- Types copy(Resolution resolution) {
- return new Types(resolution);
- }
-
- @override
- InterfaceType asInstanceOf(
- covariant ResolutionInterfaceType type, ClassEntity cls) {
- return type.asInstanceOf(cls);
- }
-
- @override
- ResolutionDartType substByContext(covariant ResolutionDartType base,
- covariant ResolutionInterfaceType context) {
- return base.substByContext(context);
- }
-
- @override
- InterfaceType getThisType(covariant ClassElement cls) => cls.thisType;
-
- @override
- ResolutionInterfaceType getSupertype(covariant ClassElement cls) =>
- cls.supertype;
-
- @override
- Iterable<InterfaceType> getSupertypes(covariant ClassElement cls) {
- assert(cls.allSupertypes != null,
- failedAt(cls, 'Supertypes have not been computed for $cls.'));
- return cls.allSupertypes;
- }
-
- @override
- Iterable<InterfaceType> getInterfaces(covariant ClassElement cls) {
- return new List<InterfaceType>.from(cls.interfaces.toList());
- }
-
- @override
- FunctionType getCallType(covariant ResolutionInterfaceType type) =>
- type.callType;
-
- /// Flatten [type] by recursively removing enclosing `Future` annotations.
- ///
- /// Defined in the language specification as:
- ///
- /// If T = Future<S> then flatten(T) = flatten(S).
- /// Otherwise if T <: Future then let S be a type such that T << Future<S>
- /// and for all R, if T << Future<R> then S << R. Then flatten(T) = S.
- /// In any other circumstance, flatten(T) = T.
- ///
- /// For instance:
- /// flatten(T) = T
- /// flatten(Future<T>) = T
- /// flatten(Future<Future<T>>) = T
- ///
- /// This method is used in the static typing of await and type checking of
- /// return.
- ResolutionDartType flatten(ResolutionDartType type) {
- if (type is ResolutionInterfaceType) {
- if (type.element == commonElements.futureClass) {
- // T = Future<S>
- return flatten(type.typeArguments.first);
- }
- ResolutionInterfaceType futureType =
- type.asInstanceOf(commonElements.futureClass);
- if (futureType != null) {
- // T << Future<S>
- return futureType.typeArguments.single;
- }
- }
- return type;
- }
-
- /// Returns true if [t] is more specific than [s].
- bool isMoreSpecific(ResolutionDartType t, ResolutionDartType s) {
- return moreSpecificVisitor.isMoreSpecific(t, s);
- }
-
- /// Returns the most specific type of [t] and [s] or `null` if neither is more
- /// specific than the other.
- ResolutionDartType getMostSpecific(
- ResolutionDartType t, ResolutionDartType s) {
- if (isMoreSpecific(t, s)) {
- return t;
- } else if (isMoreSpecific(s, t)) {
- return s;
- } else {
- return null;
- }
- }
-
- /** Returns true if t is a subtype of s */
- bool isSubtype(
- covariant ResolutionDartType t, covariant ResolutionDartType s) {
- return subtypeVisitor.isSubtype(t, s);
- }
-
- bool isAssignable(
- covariant ResolutionDartType r, covariant ResolutionDartType s) {
- return subtypeVisitor.isAssignable(r, s);
- }
-
- bool isPotentialSubtype(
- covariant ResolutionDartType t, covariant ResolutionDartType s,
- {bool assumeInstantiations: true}) {
- // TODO(johnniwinther): Return a set of variable points in the positive
- // cases.
- return potentialSubtypeVisitor.isPotentialSubtype(t, s,
- assumeInstantiations: assumeInstantiations);
- }
-
- @override
- void checkTypeVariableBounds<T>(
- T context,
- List<DartType> typeArguments,
- List<DartType> typeVariables,
- void checkTypeVariableBound(T context, DartType typeArgument,
- TypeVariableType typeVariable, DartType bound)) {
- void f(T context, DartType typeArgument, TypeVariableType typeVariable,
- DartType bound) =>
- checkTypeVariableBound(context, typeArgument, typeVariable, bound);
- genericCheckTypeVariableBounds(context, typeArguments, typeVariables, f);
- }
-
- /**
- * Checks the type arguments of [type] against the type variable bounds
- * declared on [element]. Calls [checkTypeVariableBound] on each type
- * argument and bound.
- */
- void genericCheckTypeVariableBounds<T>(
- T context,
- List<DartType> typeArguments,
- List<DartType> typeVariables,
- CheckTypeVariableBound<T> checkTypeVariableBound) {
- assert(typeVariables.length == typeArguments.length);
- for (int index = 0; index < typeArguments.length; index++) {
- ResolutionTypeVariableType typeVariable = typeVariables[index];
- ResolutionDartType bound =
- typeVariable.element.bound.subst(typeArguments, typeVariables);
- ResolutionDartType typeArgument = typeArguments[index];
- checkTypeVariableBound(context, typeArgument, typeVariable, bound);
- }
- }
-
- /**
- * Helper method for performing substitution of a list of types.
- *
- * If no types are changed by the substitution, the [types] is returned
- * instead of a newly created list.
- */
- static List<ResolutionDartType> substTypes(List<ResolutionDartType> types,
- List<ResolutionDartType> arguments, List<ResolutionDartType> parameters) {
- bool changed = false;
- List<ResolutionDartType> result =
- new List<ResolutionDartType>.generate(types.length, (index) {
- ResolutionDartType type = types[index];
- ResolutionDartType argument = type.subst(arguments, parameters);
- if (!changed && !identical(argument, type)) {
- changed = true;
- }
- return argument;
- });
- // Use the new List only if necessary.
- return changed ? result : types;
- }
-
- /**
- * A `compareTo` function that globally orders types using
- * [Elements.compareByPosition] to order types defined by a declaration.
- *
- * The order is:
- * * void
- * * dynamic
- * * interface, typedef, type variables ordered by element order
- * - interface and typedef of the same element are ordered by
- * the order of their type arguments
- * * function types, ordered by
- * - return type
- * - required parameter types
- * - optional parameter types
- * - named parameter names
- * - named parameter types
- * * malformed types
- * * statement types
- */
- static int compare(ResolutionDartType a, ResolutionDartType b) {
- if (a == b) return 0;
- if (a.isVoid) {
- // [b] is not void => a < b.
- return -1;
- } else if (b.isVoid) {
- // [a] is not void => a > b.
- return 1;
- }
- if (a.isDynamic) {
- // [b] is not dynamic => a < b.
- return -1;
- } else if (b.isDynamic) {
- // [a] is not dynamic => a > b.
- return 1;
- }
- bool isDefinedByDeclaration(ResolutionDartType type) {
- return type.isInterfaceType || type.isTypedef || type.isTypeVariable;
- }
-
- if (isDefinedByDeclaration(a)) {
- if (isDefinedByDeclaration(b)) {
- int result = Elements.compareByPosition(a.element, b.element);
- if (result != 0) return result;
- if (a.isTypeVariable) {
- return b.isTypeVariable
- ? 0
- : 1; // [b] is not a type variable => a > b.
- } else {
- if (b.isTypeVariable) {
- // [a] is not a type variable => a < b.
- return -1;
- } else {
- return compareList((a as GenericType).typeArguments,
- (b as GenericType).typeArguments);
- }
- }
- } else {
- // [b] is neither an interface, typedef, type variable, dynamic,
- // nor void => a < b.
- return -1;
- }
- } else if (isDefinedByDeclaration(b)) {
- // [a] is neither an interface, typedef, type variable, dynamic,
- // nor void => a > b.
- return 1;
- }
- if (a.isFunctionType) {
- if (b.isFunctionType) {
- ResolutionFunctionType aFunc = a;
- ResolutionFunctionType bFunc = b;
- int result = compare(aFunc.returnType, bFunc.returnType);
- if (result != 0) return result;
- result = compareList(aFunc.parameterTypes, bFunc.parameterTypes);
- if (result != 0) return result;
- result = compareList(
- aFunc.optionalParameterTypes, bFunc.optionalParameterTypes);
- if (result != 0) return result;
- // TODO(karlklose): reuse [compareList].
- Iterator<String> aNames = aFunc.namedParameters.iterator;
- Iterator<String> bNames = bFunc.namedParameters.iterator;
- while (aNames.moveNext() && bNames.moveNext()) {
- int result = aNames.current.compareTo(bNames.current);
- if (result != 0) return result;
- }
- if (aNames.moveNext()) {
- // [aNames] is longer that [bNames] => a > b.
- return 1;
- } else if (bNames.moveNext()) {
- // [bNames] is longer that [aNames] => a < b.
- return -1;
- }
- return compareList(
- aFunc.namedParameterTypes, bFunc.namedParameterTypes);
- } else {
- // [b] is a malformed or statement type => a < b.
- return -1;
- }
- } else if (b.isFunctionType) {
- // [b] is a malformed or statement type => a > b.
- return 1;
- }
- assert(a.isMalformed);
- assert(b.isMalformed);
- // TODO(johnniwinther): Can we do this better?
- return Elements.compareByPosition(a.element, b.element);
- }
-
- static int compareList(
- List<ResolutionDartType> a, List<ResolutionDartType> b) {
- for (int index = 0; index < min(a.length, b.length); index++) {
- int result = compare(a[index], b[index]);
- if (result != 0) return result;
- }
- if (a.length > b.length) {
- return 1;
- } else if (a.length < b.length) {
- return -1;
- }
- return 0;
- }
-
- static List<ResolutionDartType> sorted(Iterable<ResolutionDartType> types) {
- return types.toList()..sort(compare);
- }
-
- /// Computes the least upper bound of two interface types [a] and [b].
- ResolutionInterfaceType computeLeastUpperBoundInterfaces(
- ResolutionInterfaceType a, ResolutionInterfaceType b) {
- /// Returns the set of supertypes of [type] at depth [depth].
- Set<ResolutionDartType> getSupertypesAtDepth(
- ResolutionInterfaceType type, int depth) {
- OrderedTypeSet types = type.element.allSupertypesAndSelf;
- Set<ResolutionDartType> set = new Set<ResolutionDartType>();
- types.forEach(depth, (_supertype) {
- ResolutionInterfaceType supertype = _supertype;
- set.add(supertype.substByContext(type));
- });
- return set;
- }
-
- ClassElement aClass = a.element;
- ClassElement bClass = b.element;
- int maxCommonDepth = min(aClass.hierarchyDepth, bClass.hierarchyDepth);
- for (int depth = maxCommonDepth; depth >= 0; depth--) {
- Set<ResolutionDartType> aTypeSet = getSupertypesAtDepth(a, depth);
- Set<ResolutionDartType> bTypeSet = getSupertypesAtDepth(b, depth);
- Set<ResolutionDartType> intersection = aTypeSet..retainAll(bTypeSet);
- if (intersection.length == 1) {
- return intersection.first;
- }
- }
-
- reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
- 'No least upper bound computed for $a and $b.');
- return null;
- }
-
- /// Computes the least upper bound of the types in the longest prefix of [a]
- /// and [b].
- List<ResolutionDartType> computeLeastUpperBoundsTypes(
- List<ResolutionDartType> a, List<ResolutionDartType> b) {
- if (a.isEmpty || b.isEmpty) return const <ResolutionDartType>[];
- int prefixLength = min(a.length, b.length);
- List<ResolutionDartType> types = new List<ResolutionDartType>(prefixLength);
- for (int index = 0; index < prefixLength; index++) {
- types[index] = computeLeastUpperBound(a[index], b[index]);
- }
- return types;
- }
-
- /// Computes the least upper bound of two function types [a] and [b].
- ///
- /// If the required parameter count of [a] and [b] does not match, `Function`
- /// is returned.
- ///
- /// Otherwise, a function type is returned whose return type and
- /// parameter types are the least upper bound of those of [a] and [b],
- /// respectively. In addition, the optional parameters are the least upper
- /// bound of the longest common prefix of the optional parameters of [a] and
- /// [b], and the named parameters are the least upper bound of those common to
- /// [a] and [b].
- ResolutionDartType computeLeastUpperBoundFunctionTypes(
- ResolutionFunctionType a, ResolutionFunctionType b) {
- if (a.parameterTypes.length != b.parameterTypes.length) {
- ResolutionInterfaceType functionType = commonElements.functionType;
- return functionType;
- }
- ResolutionDartType returnType =
- computeLeastUpperBound(a.returnType, b.returnType);
- List<ResolutionDartType> parameterTypes =
- computeLeastUpperBoundsTypes(a.parameterTypes, b.parameterTypes);
- List<ResolutionDartType> optionalParameterTypes =
- computeLeastUpperBoundsTypes(
- a.optionalParameterTypes, b.optionalParameterTypes);
- List<String> namedParameters = <String>[];
- List<String> aNamedParameters = a.namedParameters;
- List<String> bNamedParameters = b.namedParameters;
- List<ResolutionDartType> namedParameterTypes = <ResolutionDartType>[];
- List<ResolutionDartType> aNamedParameterTypes = a.namedParameterTypes;
- List<ResolutionDartType> bNamedParameterTypes = b.namedParameterTypes;
- int aIndex = 0;
- int bIndex = 0;
- while (
- aIndex < aNamedParameters.length && bIndex < bNamedParameters.length) {
- String aNamedParameter = aNamedParameters[aIndex];
- String bNamedParameter = bNamedParameters[bIndex];
- int result = aNamedParameter.compareTo(bNamedParameter);
- if (result == 0) {
- namedParameters.add(aNamedParameter);
- namedParameterTypes.add(computeLeastUpperBound(
- aNamedParameterTypes[aIndex], bNamedParameterTypes[bIndex]));
- }
- if (result <= 0) {
- aIndex++;
- }
- if (result >= 0) {
- bIndex++;
- }
- }
- return new ResolutionFunctionType.synthesized(returnType, parameterTypes,
- optionalParameterTypes, namedParameters, namedParameterTypes);
- }
-
- /// Computes the least upper bound of two types of which at least one is a
- /// type variable. The least upper bound of a type variable is defined in
- /// terms of its bound, but to ensure reflexivity we need to check for common
- /// bounds transitively.
- ResolutionDartType computeLeastUpperBoundTypeVariableTypes(
- ResolutionDartType a, ResolutionDartType b) {
- Set<ResolutionDartType> typeVariableBounds = new Set<ResolutionDartType>();
- while (a.isTypeVariable) {
- if (a == b) return a;
- typeVariableBounds.add(a);
- TypeVariableElement element = a.element;
- a = element.bound;
- }
- while (b.isTypeVariable) {
- if (typeVariableBounds.contains(b)) return b;
- TypeVariableElement element = b.element;
- b = element.bound;
- }
- return computeLeastUpperBound(a, b);
- }
-
- /// Computes the least upper bound for [a] and [b].
- ResolutionDartType computeLeastUpperBound(
- ResolutionDartType a, ResolutionDartType b) {
- if (a == b) return a;
-
- if (a.isTypeVariable || b.isTypeVariable) {
- return computeLeastUpperBoundTypeVariableTypes(a, b);
- }
-
- a.computeUnaliased(resolution);
- a = a.unaliased;
- b.computeUnaliased(resolution);
- b = b.unaliased;
-
- if (a.treatAsDynamic || b.treatAsDynamic)
- return const ResolutionDynamicType();
- if (a.isVoid || b.isVoid) return const ResolutionVoidType();
-
- if (a.isFunctionType && b.isFunctionType) {
- return computeLeastUpperBoundFunctionTypes(a, b);
- }
-
- if (a.isFunctionType) {
- ResolutionInterfaceType functionType = commonElements.functionType;
- a = functionType;
- }
- if (b.isFunctionType) {
- ResolutionInterfaceType functionType = commonElements.functionType;
- b = functionType;
- }
-
- if (a.isInterfaceType && b.isInterfaceType) {
- return computeLeastUpperBoundInterfaces(a, b);
- }
- return const ResolutionDynamicType();
- }
-
- /// Computes the unaliased type of the first non type variable bound of
- /// [type].
- ///
- /// This is used to normalize malformed types, type variables and typedef
- /// before use in typechecking.
- ///
- /// Malformed types are normalized to `dynamic`. Typedefs are normalized to
- /// their alias, or `dynamic` if cyclic. Type variables are normalized to the
- /// normalized type of their bound, or `Object` if cyclic.
- ///
- /// For instance for these types:
- ///
- /// class Foo<T extends Bar, S extends T, U extends Baz> {}
- /// class Bar<X extends Y, Y extends X> {}
- /// typedef Baz();
- ///
- /// the unaliased bounds types are:
- ///
- /// unaliasedBound(Foo) = Foo
- /// unaliasedBound(Bar) = Bar
- /// unaliasedBound(Unresolved) = `dynamic`
- /// unaliasedBound(Baz) = ()->dynamic
- /// unaliasedBound(T) = Bar
- /// unaliasedBound(S) = unaliasedBound(T) = Bar
- /// unaliasedBound(U) = unaliasedBound(Baz) = ()->dynamic
- /// unaliasedBound(X) = unaliasedBound(Y) = `Object`
- ///
- static ResolutionDartType computeUnaliasedBound(
- Resolution resolution, ResolutionDartType type) {
- ResolutionDartType originalType = type;
- while (type.isTypeVariable) {
- ResolutionTypeVariableType variable = type;
- type = variable.element.bound;
- if (type == originalType) {
- ResolutionInterfaceType objectType =
- resolution.commonElements.objectType;
- type = objectType;
- }
- }
- if (type.isMalformed) {
- return const ResolutionDynamicType();
- }
- type.computeUnaliased(resolution);
- return type.unaliased;
- }
-
- /// Computes the interface type of [type], which is the type that defines
- /// the property of [type].
- ///
- /// For an interface type it is the type itself, for a type variable it is the
- /// interface type of the bound, for function types and typedefs it is the
- /// `Function` type. For other types, like `dynamic`, `void` and malformed
- /// types, there is no interface type and `null` is returned.
- ///
- /// For instance for these types:
- ///
- /// class Foo<T extends Bar, S extends T, U extends Baz> {}
- /// class Bar {}
- /// typedef Baz();
- ///
- /// the interface types are:
- ///
- /// interfaceType(Foo) = Foo
- /// interfaceType(Bar) = Bar
- /// interfaceType(Baz) = interfaceType(()->dynamic) = Function
- /// interfaceType(T) = interfaceType(Bar) = Bar
- /// interfaceType(S) = interfaceType(T) = interfaceType(Bar) = Bar
- /// interfaceType(U) = interfaceType(Baz)
- /// = intefaceType(()->dynamic) = Function
- ///
- /// When typechecking `o.foo` the interface type of the static type of `o` is
- /// used to lookup the existence and type of `foo`.
- ///
- static ResolutionInterfaceType computeInterfaceType(
- Resolution resolution, ResolutionDartType type) {
- type = computeUnaliasedBound(resolution, type);
- if (type.treatAsDynamic) {
- return null;
- }
- if (type.isFunctionType) {
- ResolutionInterfaceType functionType =
- resolution.commonElements.functionType;
- type = functionType;
- }
- assert(type.isInterfaceType,
- failedAt(NO_LOCATION_SPANNABLE, "unexpected type kind ${type.kind}."));
- return type;
- }
-}
-
-/// Visitor used to compute an instantiation of a generic type that is more
-/// specific than a given type.
-///
-/// The visitor tries to compute constraints for all type variables in the
-/// visited type by structurally matching it with the argument type. If the
-/// constraints are too complex or the two types are too different, `false`
-/// is returned. Otherwise, the [constraintMap] holds the valid constraints.
-class MoreSpecificSubtypeVisitor
- extends BaseResolutionDartTypeVisitor<bool, ResolutionDartType> {
- final Types types;
- Map<ResolutionTypeVariableType, ResolutionDartType> constraintMap;
-
- MoreSpecificSubtypeVisitor(this.types);
-
- /// Compute an instance of [element] which is more specific than [supertype].
- /// If no instance is found, `null` is returned.
- ///
- /// Note that this computation is a heuristic. It does not find a suggestion
- /// in all possible cases.
- ResolutionInterfaceType computeMoreSpecific(
- ClassElement element, ResolutionInterfaceType supertype) {
- ResolutionInterfaceType supertypeInstance =
- element.thisType.asInstanceOf(supertype.element);
- if (supertypeInstance == null) return null;
-
- constraintMap = new Map<ResolutionTypeVariableType, ResolutionDartType>();
- element.typeVariables.forEach((ResolutionDartType typeVariable) {
- constraintMap[typeVariable] = const ResolutionDynamicType();
- });
- if (supertypeInstance.accept(this, supertype)) {
- List<ResolutionDartType> variables = element.typeVariables;
- List<ResolutionDartType> typeArguments =
- new List<ResolutionDartType>.generate(
- variables.length, (int index) => constraintMap[variables[index]]);
- return element.thisType.createInstantiation(typeArguments);
- }
- return null;
- }
-
- bool visitType(
- covariant ResolutionDartType type, ResolutionDartType argument) {
- return types.isMoreSpecific(type, argument);
- }
-
- bool visitTypes(List<ResolutionDartType> a, List<ResolutionDartType> b) {
- int prefixLength = min(a.length, b.length);
- for (int index = 0; index < prefixLength; index++) {
- if (!a[index].accept(this, b[index])) return false;
- }
- return prefixLength == a.length && a.length == b.length;
- }
-
- bool visitTypeVariableType(
- covariant ResolutionTypeVariableType type, ResolutionDartType argument) {
- ResolutionDartType constraint =
- types.getMostSpecific(constraintMap[type], argument);
- constraintMap[type] = constraint;
- return constraint != null;
- }
-
- bool visitFunctionType(
- covariant ResolutionFunctionType type, ResolutionDartType argument) {
- if (argument is ResolutionFunctionType) {
- if (type.parameterTypes.length != argument.parameterTypes.length) {
- return false;
- }
- if (type.optionalParameterTypes.length !=
- argument.optionalParameterTypes.length) {
- return false;
- }
- if (type.namedParameters != argument.namedParameters) {
- return false;
- }
-
- if (!type.returnType.accept(this, argument.returnType)) return false;
- if (visitTypes(type.parameterTypes, argument.parameterTypes)) {
- return false;
- }
- if (visitTypes(
- type.optionalParameterTypes, argument.optionalParameterTypes)) {
- return false;
- }
- return visitTypes(type.namedParameterTypes, argument.namedParameterTypes);
- }
- return false;
- }
-
- bool visitGenericType(GenericType type, ResolutionDartType argument) {
- if (argument is GenericType) {
- if (type.element != argument.element) return false;
- return visitTypes(type.typeArguments, argument.typeArguments);
- }
- return false;
- }
-}
-
-/// Visitor used to print type annotation like they used in the source code.
-/// The visitor is especially for printing a function type like
-/// `(Foo,[Bar])->Baz` as `Baz m(Foo a1, [Bar a2])`.
-class TypeDeclarationFormatter
- extends BaseResolutionDartTypeVisitor<dynamic, String> {
- Set<String> usedNames;
- StringBuffer sb;
-
- /// Creates textual representation of [type] as if a member by the [name] were
- /// declared. For instance 'String foo' for `format(String, 'foo')`.
- String format(ResolutionDartType type, String name) {
- sb = new StringBuffer();
- usedNames = new Set<String>();
- type.accept(this, name);
- usedNames = null;
- return sb.toString();
- }
-
- String createName(String name) {
- if (name != null && !usedNames.contains(name)) {
- usedNames.add(name);
- return name;
- }
- int index = usedNames.length;
- String proposal;
- do {
- proposal = '${name}${index++}';
- } while (usedNames.contains(proposal));
- usedNames.add(proposal);
- return proposal;
- }
-
- void visit(covariant ResolutionDartType type, [_]) {
- type.accept(this, null);
- }
-
- void visitTypes(List<ResolutionDartType> types, String prefix) {
- bool needsComma = false;
- for (ResolutionDartType type in types) {
- if (needsComma) {
- sb.write(', ');
- }
- type.accept(this, prefix);
- needsComma = true;
- }
- }
-
- void visitType(covariant ResolutionDartType type, String name) {
- if (name == null) {
- sb.write(type);
- } else {
- sb.write('$type ${createName(name)}');
- }
- }
-
- void visitGenericType(GenericType type, String name) {
- sb.write(type.name);
- if (!type.treatAsRaw) {
- sb.write('<');
- visitTypes(type.typeArguments, null);
- sb.write('>');
- }
- if (name != null) {
- sb.write(' ');
- sb.write(createName(name));
- }
- }
-
- void visitFunctionType(covariant ResolutionFunctionType type, String name) {
- visit(type.returnType);
- sb.write(' ');
- if (name != null) {
- sb.write(name);
- } else {
- sb.write(createName('f'));
- }
- sb.write('(');
- visitTypes(type.parameterTypes, 'a');
- bool needsComma = !type.parameterTypes.isEmpty;
- if (!type.optionalParameterTypes.isEmpty) {
- if (needsComma) {
- sb.write(', ');
- }
- sb.write('[');
- visitTypes(type.optionalParameterTypes, 'a');
- sb.write(']');
- needsComma = true;
- }
- if (!type.namedParameterTypes.isEmpty) {
- if (needsComma) {
- sb.write(', ');
- }
- sb.write('{');
- List<String> namedParameters = type.namedParameters;
- List<ResolutionDartType> namedParameterTypes = type.namedParameterTypes;
- needsComma = false;
- for (int index = 0; index < namedParameters.length; index++) {
- if (needsComma) {
- sb.write(', ');
- }
- namedParameterTypes[index].accept(this, namedParameters[index]);
- needsComma = true;
- }
- sb.write('}');
- }
- sb.write(')');
- }
-}
diff --git a/pkg/compiler/lib/src/elements/visitor.dart b/pkg/compiler/lib/src/elements/visitor.dart
deleted file mode 100644
index 339dfba..0000000
--- a/pkg/compiler/lib/src/elements/visitor.dart
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library visitor;
-
-import '../closure.dart'
- show BoxFieldElement, ClosureClassElement, ClosureFieldElement;
-import 'elements.dart';
-
-abstract class ElementVisitor<R, A> {
- const ElementVisitor();
-
- R visit(covariant Element e, covariant A arg) => e.accept(this, arg);
-
- R visitErroneousElement(covariant ErroneousElement e, covariant A arg) =>
- null;
- R visitWarnOnUseElement(covariant WarnOnUseElement e, covariant A arg) =>
- null;
- R visitAmbiguousElement(covariant AmbiguousElement e, covariant A arg) =>
- null;
- R visitCompilationUnitElement(
- covariant CompilationUnitElement e, covariant A arg) =>
- null;
- R visitLibraryElement(covariant LibraryElement e, covariant A arg) => null;
- R visitImportElement(covariant ImportElement e, covariant A arg) => null;
- R visitExportElement(covariant ExportElement e, covariant A arg) => null;
- R visitPrefixElement(covariant PrefixElement e, covariant A arg) => null;
- R visitTypedefElement(covariant TypedefElement e, covariant A arg) => null;
- R visitLocalVariableElement(
- covariant LocalVariableElement e, covariant A arg) =>
- null;
- R visitParameterElement(covariant ParameterElement e, covariant A arg) =>
- null;
- R visitFormalElement(covariant FormalElement e, covariant A arg) => null;
- R visitFieldElement(covariant FieldElement e, covariant A arg) => null;
- R visitFieldParameterElement(
- covariant InitializingFormalElement e, covariant A arg) =>
- null;
- R visitAbstractFieldElement(
- covariant AbstractFieldElement e, covariant A arg) =>
- null;
- R visitMethodElement(covariant MethodElement e, covariant A arg) => null;
- R visitGetterElement(covariant GetterElement e, covariant A arg) => null;
- R visitSetterElement(covariant SetterElement e, covariant A arg) => null;
- R visitLocalFunctionElement(
- covariant LocalFunctionElement e, covariant A arg) =>
- null;
- R visitConstructorElement(covariant ConstructorElement e, covariant A arg) =>
- null;
- R visitConstructorBodyElement(
- covariant ConstructorBodyElement e, covariant A arg) =>
- null;
- R visitClassElement(covariant ClassElement e, covariant A arg) => null;
- R visitMixinApplicationElement(
- covariant MixinApplicationElement e, covariant A arg) =>
- null;
- R visitEnumClassElement(covariant EnumClassElement e, covariant A arg) =>
- null;
- R visitTypeVariableElement(
- covariant TypeVariableElement e, covariant A arg) =>
- null;
- R visitBoxFieldElement(covariant BoxFieldElement e, covariant A arg) => null;
- R visitClosureClassElement(
- covariant ClosureClassElement e, covariant A arg) =>
- null;
- R visitClosureFieldElement(
- covariant ClosureFieldElement e, covariant A arg) =>
- null;
-}
-
-abstract class BaseElementVisitor<R, A> extends ElementVisitor<R, A> {
- const BaseElementVisitor();
-
- R visitElement(covariant Element e, covariant A arg);
-
- @override
- R visitErroneousElement(covariant ErroneousElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitWarnOnUseElement(covariant WarnOnUseElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitAmbiguousElement(covariant AmbiguousElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- R visitScopeContainerElement(
- covariant ScopeContainerElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitCompilationUnitElement(
- covariant CompilationUnitElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitLibraryElement(covariant LibraryElement e, covariant A arg) {
- return visitScopeContainerElement(e, arg);
- }
-
- @override
- R visitImportElement(covariant ImportElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitExportElement(covariant ExportElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitPrefixElement(covariant PrefixElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitTypedefElement(covariant TypedefElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- R visitVariableElement(covariant VariableElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitLocalVariableElement(
- covariant LocalVariableElement e, covariant A arg) {
- return visitVariableElement(e, arg);
- }
-
- @override
- R visitParameterElement(covariant ParameterElement e, covariant A arg) {
- return visitVariableElement(e, arg);
- }
-
- @override
- R visitFormalElement(covariant FormalElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitFieldElement(covariant FieldElement e, covariant A arg) {
- return visitVariableElement(e, arg);
- }
-
- @override
- R visitFieldParameterElement(
- covariant InitializingFormalElement e, covariant A arg) {
- return visitParameterElement(e, arg);
- }
-
- @override
- R visitAbstractFieldElement(
- covariant AbstractFieldElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- R visitFunctionElement(covariant FunctionElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitMethodElement(covariant MethodElement e, covariant A arg) {
- return visitFunctionElement(e, arg);
- }
-
- @override
- R visitGetterElement(covariant GetterElement e, covariant A arg) {
- return visitFunctionElement(e, arg);
- }
-
- @override
- R visitSetterElement(covariant SetterElement e, covariant A arg) {
- return visitFunctionElement(e, arg);
- }
-
- @override
- R visitLocalFunctionElement(
- covariant LocalFunctionElement e, covariant A arg) {
- return visitFunctionElement(e, arg);
- }
-
- @override
- R visitConstructorElement(covariant ConstructorElement e, covariant A arg) {
- return visitFunctionElement(e, arg);
- }
-
- @override
- R visitConstructorBodyElement(
- covariant ConstructorBodyElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitClassElement(covariant ClassElement e, covariant A arg) {
- return visitScopeContainerElement(e, arg);
- }
-
- R visitTypeDeclarationElement(
- covariant TypeDeclarationElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitMixinApplicationElement(
- covariant MixinApplicationElement e, covariant A arg) {
- return visitClassElement(e, arg);
- }
-
- @override
- R visitEnumClassElement(covariant EnumClassElement e, covariant A arg) {
- return visitClassElement(e, arg);
- }
-
- @override
- R visitTypeVariableElement(covariant TypeVariableElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitBoxFieldElement(covariant BoxFieldElement e, covariant A arg) {
- return visitElement(e, arg);
- }
-
- @override
- R visitClosureClassElement(covariant ClosureClassElement e, covariant A arg) {
- return visitClassElement(e, arg);
- }
-
- @override
- R visitClosureFieldElement(covariant ClosureFieldElement e, covariant A arg) {
- return visitVariableElement(e, arg);
- }
-}
diff --git a/pkg/compiler/lib/src/frontend_strategy.dart b/pkg/compiler/lib/src/frontend_strategy.dart
index b6943cb..8f915bf 100644
--- a/pkg/compiler/lib/src/frontend_strategy.dart
+++ b/pkg/compiler/lib/src/frontend_strategy.dart
@@ -14,20 +14,14 @@
import 'elements/entities.dart';
import 'elements/types.dart';
import 'enqueue.dart';
-import 'environment.dart';
-import 'js_backend/backend.dart';
import 'js_backend/backend_usage.dart';
import 'js_backend/interceptor_data.dart';
-import 'js_backend/mirrors_analysis.dart';
-import 'js_backend/mirrors_data.dart';
import 'js_backend/native_data.dart';
import 'js_backend/no_such_method_registry.dart';
import 'js_backend/runtime_types.dart';
import 'library_loader.dart';
import 'native/enqueue.dart' show NativeResolutionEnqueuer;
import 'native/resolver.dart';
-import 'patch_parser.dart';
-import 'resolved_uri_translator.dart';
import 'universe/class_hierarchy_builder.dart';
import 'universe/world_builder.dart';
import 'universe/world_impact.dart';
@@ -36,16 +30,8 @@
/// the resolved element model.
abstract class FrontendStrategy {
/// Creates library loader task for this strategy.
- LibraryLoaderTask createLibraryLoader(
- ResolvedUriTranslator uriTranslator,
- ScriptLoader scriptLoader,
- api.CompilerInput compilerInput,
- ElementScanner scriptScanner,
- PatchResolverFunction patchResolverFunc,
- PatchParserTask patchParser,
- Environment environment,
- DiagnosticReporter reporter,
- Measurer measurer);
+ LibraryLoaderTask createLibraryLoader(api.CompilerInput compilerInput,
+ DiagnosticReporter reporter, Measurer measurer);
/// Returns the [ElementEnvironment] for the element model used in this
/// strategy.
@@ -103,16 +89,6 @@
FunctionEntity computeMain(
LibraryEntity mainLibrary, WorldImpactBuilder impactBuilder);
- // TODO(johnniwinther): Reuse the following classes between strategies:
-
- /// Creates the [MirrorsDataBuilder] for this strategy.
- MirrorsDataBuilder createMirrorsDataBuilder();
-
- /// Creates the [MirrorsResolutionAnalysis] for this strategy.
- // TODO(johnniwinther): Avoid passing [JavaScriptBackend].
- MirrorsResolutionAnalysis createMirrorsResolutionAnalysis(
- JavaScriptBackend backend);
-
/// Creates the [RuntimeTypesNeedBuilder] for this strategy.
RuntimeTypesNeedBuilder createRuntimeTypesNeedBuilder();
@@ -153,7 +129,7 @@
/// Class that deletes the contents of an [WorldImpact] cache.
// TODO(redemption): this can be deleted when we sunset the old front end.
abstract class ImpactCacheDeleter {
- bool retainCachesForTesting;
+ static bool retainCachesForTesting = false;
/// Removes the [WorldImpact] for [element] from the resolution cache. Later
/// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
diff --git a/pkg/compiler/lib/src/id_generator.dart b/pkg/compiler/lib/src/id_generator.dart
deleted file mode 100644
index 9107c7a..0000000
--- a/pkg/compiler/lib/src/id_generator.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// A generator of globally unique identifiers.
-class IdGenerator {
- int _nextFreeId = 0;
-
- /// Returns the next free identifier.
- ///
- /// This identifier is guaranteed to be unique.
- int getNextFreeId() => _nextFreeId++;
-}
diff --git a/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart
deleted file mode 100644
index acea941..0000000
--- a/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import '../common.dart';
-import '../common/names.dart';
-import '../compiler.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../resolution/tree_elements.dart';
-import '../tree/nodes.dart' as ast;
-import '../types/types.dart';
-import '../world.dart';
-import 'builder.dart';
-import 'inferrer_engine.dart';
-import 'type_graph_nodes.dart';
-import 'type_system.dart';
-
-class AstInferrerEngine extends InferrerEngineImpl<ast.Node> {
- final Compiler compiler;
-
- AstInferrerEngine(this.compiler, ClosedWorld closedWorld,
- ClosedWorldRefiner closedWorldRefiner, FunctionEntity mainElement)
- : super(
- compiler.options,
- compiler.progress,
- compiler.reporter,
- compiler.outputProvider,
- closedWorld,
- closedWorldRefiner,
- compiler.backend.mirrorsData,
- compiler.backend.noSuchMethodRegistry,
- mainElement,
- compiler.backendStrategy.sorter,
- const TypeSystemStrategyImpl());
-
- GlobalTypeInferenceElementData<ast.Node> createElementData() =>
- new AstGlobalTypeInferenceElementData();
-
- int computeMemberSize(MemberEntity member) => resolveAstApproxSize(member);
-
- ast.Node computeMemberBody(covariant MemberElement member) {
- ResolvedAst resolvedAst = member.resolvedAst;
- ast.Node body;
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- body = resolvedAst.body;
- if (member.isField &&
- member.isInstanceMember &&
- !member.isFinal &&
- body is ast.LiteralNull) {
- return null;
- }
- }
- return body;
- }
-
- FunctionEntity lookupCallMethod(covariant ClassElement cls) {
- MethodElement callMethod = cls.lookupMember(Identifiers.call);
- if (callMethod == null || callMethod.isAbstract) {
- callMethod = cls.lookupMember(Identifiers.noSuchMethod_);
- }
- return callMethod;
- }
-
- TypeInformation computeMemberTypeInformation(
- MemberEntity member, ast.Node body) {
- ElementGraphBuilder visitor =
- new ElementGraphBuilder(member, compiler, this);
- return visitor.run();
- }
-
- bool isFieldInitializerPotentiallyNull(
- FieldEntity field, ast.Node initializer) {
- dynamic argument = initializer;
- // TODO(13429): We could do better here by using the
- // constant handler to figure out if it's a lazy field or not.
- return argument.asSend() != null ||
- (argument.asNewExpression() != null && !argument.isConst);
- }
-
- ConstantValue getFieldConstant(covariant FieldElement field) {
- ConstantExpression constant = field.constant;
- if (constant != null) {
- ConstantValue value =
- compiler.backend.constants.getConstantValue(constant);
- if (value == null) {
- assert(
- field.isInstanceMember ||
- constant.isImplicit ||
- constant.isPotential,
- failedAt(
- field,
- "Constant expression without value: "
- "${constant.toStructuredText()}."));
- }
- return value;
- }
- return null;
- }
-
- @override
- bool hasCallType(covariant ClassElement cls) {
- return cls.callType != null;
- }
-
- /// Computes a 'size' of [_element] based on the number of selectors in the
- /// associated [TreeElements]. This is used for sorting member for the type
- /// inference work-queue.
- // TODO(johnniwinther): This is brittle and cannot be translated in the
- // kernel based inference. Find a more stable a reproducable size measure.
- static int resolveAstApproxSize(_element) {
- MemberElement element = _element;
- ResolvedAst resolvedAst = element.resolvedAst;
- element = element.implementation;
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- TreeElementMapping mapping = resolvedAst.elements;
- return mapping.getSelectorCount();
- }
- return 0;
- }
-}
-
-class TypeSystemStrategyImpl implements TypeSystemStrategy<ast.Node> {
- const TypeSystemStrategyImpl();
-
- @override
- MemberTypeInformation createMemberTypeInformation(
- covariant MemberElement member) {
- assert(member.isDeclaration, failedAt(member));
- if (member.isField) {
- FieldElement field = member;
- return new FieldTypeInformation(field, field.type);
- } else if (member.isGetter) {
- GetterElement getter = member;
- return new GetterTypeInformation(getter, getter.type);
- } else if (member.isSetter) {
- SetterElement setter = member;
- return new SetterTypeInformation(setter);
- } else if (member.isFunction) {
- MethodElement method = member;
- return new MethodTypeInformation(method, method.type);
- } else {
- ConstructorElement constructor = member;
- if (constructor.isFactoryConstructor) {
- return new FactoryConstructorTypeInformation(
- constructor, constructor.type);
- } else {
- return new GenerativeConstructorTypeInformation(constructor);
- }
- }
- }
-
- @override
- ParameterTypeInformation createParameterTypeInformation(
- covariant ParameterElement parameter, TypeSystem<ast.Node> types) {
- assert(parameter.isImplementation, failedAt(parameter));
- FunctionTypedElement function = parameter.functionDeclaration.declaration;
- if (function.isLocal) {
- LocalFunctionElement localFunction = function;
- MethodElement callMethod = localFunction.callMethod;
- return new ParameterTypeInformation.localFunction(
- types.getInferredTypeOfMember(callMethod),
- parameter,
- parameter.type,
- callMethod);
- } else if (function.isInstanceMember) {
- MethodElement method = function;
- return new ParameterTypeInformation.instanceMember(
- types.getInferredTypeOfMember(method),
- parameter,
- parameter.type,
- method,
- new ParameterAssignments());
- } else {
- MethodElement method = function;
- return new ParameterTypeInformation.static(
- types.getInferredTypeOfMember(method),
- parameter,
- parameter.type,
- method,
- // TODO(johnniwinther): Is this still valid now that initializing
- // formals also introduce locals?
- isInitializingFormal: parameter.isInitializingFormal);
- }
- }
-
- @override
- void forEachParameter(
- covariant MethodElement function, void f(Local parameter)) {
- MethodElement impl = function.implementation;
- FunctionSignature signature = impl.functionSignature;
- signature.forEachParameter((FormalElement _parameter) {
- ParameterElement parameter = _parameter;
- f(parameter);
- });
- }
-
- @override
- bool checkMapNode(ast.Node node) {
- return node is ast.LiteralMap;
- }
-
- @override
- bool checkListNode(ast.Node node) {
- return node is ast.LiteralList || node is ast.Send;
- }
-
- @override
- bool checkLoopPhiNode(ast.Node node) {
- return node is ast.Loop || node is ast.SwitchStatement;
- }
-
- @override
- bool checkPhiNode(ast.Node node) {
- return true;
- }
-
- @override
- bool checkClassEntity(covariant ClassElement cls) {
- return cls.isDeclaration;
- }
-}
diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart
deleted file mode 100644
index bf8b69d..0000000
--- a/pkg/compiler/lib/src/inferrer/builder.dart
+++ /dev/null
@@ -1,3021 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library simple_types_inferrer;
-
-import '../closure.dart' show ClosureRepresentationInfo, ScopeInfo;
-import '../common.dart';
-import '../common/names.dart' show Identifiers, Selectors;
-import '../compiler.dart' show Compiler;
-import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart' show ConstantValue, IntConstantValue;
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/jumps.dart';
-import '../elements/names.dart';
-import '../elements/operators.dart' as op;
-import '../elements/resolution_types.dart'
- show ResolutionDartType, ResolutionInterfaceType;
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../native/native.dart' as native;
-import '../resolution/semantic_visitor.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart' as ast;
-import '../types/constants.dart' show computeTypeMask;
-import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData;
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import '../universe/side_effects.dart' show SideEffectsBuilder;
-import '../util/util.dart' show Link, Setlet;
-import '../world.dart' show ClosedWorld;
-import 'inferrer_engine.dart';
-import 'locals_handler.dart';
-import 'type_graph_nodes.dart';
-import 'type_system.dart';
-
-/// [ElementGraphBuilder] can be thought of as a type-inference graph
-/// builder for a single element.
-///
-/// Calling [run] will start the work of visiting the body of the code to
-/// construct a set of infernece-nodes that abstractly represent what the code
-/// is doing.
-///
-/// This visitor is parameterized by an [InferenceEngine], which internally
-/// decides how to represent inference nodes.
-class ElementGraphBuilder extends ast.Visitor<TypeInformation>
- with
- SemanticSendResolvedMixin<TypeInformation, dynamic>,
- CompoundBulkMixin<TypeInformation, dynamic>,
- SetIfNullBulkMixin<TypeInformation, dynamic>,
- PrefixBulkMixin<TypeInformation, dynamic>,
- PostfixBulkMixin<TypeInformation, dynamic>,
- ErrorBulkMixin<TypeInformation, dynamic>,
- NewBulkMixin<TypeInformation, dynamic>,
- SetBulkMixin<TypeInformation, dynamic>
- implements SemanticSendVisitor<TypeInformation, dynamic> {
- final Compiler compiler;
- final MemberElement analyzedElement;
- final ResolvedAst resolvedAst;
- final TypeSystem<ast.Node> types;
- final Map<JumpTarget, List<LocalsHandler>> breaksFor =
- new Map<JumpTarget, List<LocalsHandler>>();
- final Map<JumpTarget, List<LocalsHandler>> continuesFor =
- new Map<JumpTarget, List<LocalsHandler>>();
- LocalsHandler<ast.Node> locals;
- final List<TypeInformation> cascadeReceiverStack =
- new List<TypeInformation>();
-
- TypeInformation returnType;
- bool visitingInitializers = false;
- bool isConstructorRedirect = false;
- bool seenSuperConstructorCall = false;
- final SideEffectsBuilder sideEffectsBuilder;
- final MemberElement outermostElement;
- final InferrerEngine inferrer;
- final Setlet<Entity> capturedVariables = new Setlet<Entity>();
- final GlobalTypeInferenceElementData memberData;
-
- ElementGraphBuilder.internal(
- MemberElement analyzedElement,
- this.resolvedAst,
- this.outermostElement,
- InferrerEngine inferrer,
- this.compiler,
- this.locals)
- : this.analyzedElement = analyzedElement,
- this.inferrer = inferrer,
- this.types = inferrer.types,
- this.memberData = inferrer.dataOfMember(analyzedElement.memberContext),
- this.sideEffectsBuilder = analyzedElement is MethodElement
- ? inferrer.closedWorldRefiner.getSideEffectsBuilder(analyzedElement)
- : new SideEffectsBuilder.free(analyzedElement) {
- assert(analyzedElement.isDeclaration);
- assert(outermostElement != null);
- assert(outermostElement.isDeclaration);
- if (locals != null) return;
- ast.Node node;
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- node = resolvedAst.node;
- }
- FieldInitializationScope<ast.Node> fieldScope =
- analyzedElement.isGenerativeConstructor
- ? new FieldInitializationScope<ast.Node>(types)
- : null;
- locals = new LocalsHandler<ast.Node>(
- inferrer, types, compiler.options, node, fieldScope);
- }
-
- ElementGraphBuilder(
- MemberElement element, Compiler compiler, InferrerEngine inferrer,
- [LocalsHandler handler])
- : this.internal(element, element.resolvedAst,
- element.memberContext.declaration, inferrer, compiler, handler);
-
- TreeElements get elements => resolvedAst.elements;
-
- bool accumulateIsChecks = false;
- bool conditionIsSimple = false;
- List<ast.Send> isChecks;
- int loopLevel = 0;
-
- bool get inLoop => loopLevel > 0;
- bool get isThisExposed {
- return analyzedElement.isGenerativeConstructor
- ? locals.fieldScope.isThisExposed
- : true;
- }
-
- void set isThisExposed(value) {
- if (analyzedElement.isGenerativeConstructor) {
- locals.fieldScope.isThisExposed = value;
- }
- }
-
- void initializationIsIndefinite() {
- if (analyzedElement.isGenerativeConstructor) {
- locals.fieldScope.isIndefinite = true;
- }
- }
-
- DiagnosticReporter get reporter => compiler.reporter;
-
- ClosedWorld get closedWorld => inferrer.closedWorld;
-
- @override
- SemanticSendVisitor<TypeInformation, dynamic> get sendVisitor => this;
-
- @override
- TypeInformation apply(ast.Node node, _) => visit(node);
-
- TypeInformation visitAssert(ast.Assert node) {
- // Avoid pollution from assert statement unless enabled.
- if (!compiler.options.enableUserAssertions) {
- return null;
- }
- List<ast.Send> tests = <ast.Send>[];
- bool simpleCondition = handleCondition(node.condition, tests);
- LocalsHandler saved = locals;
- locals = new LocalsHandler.from(locals, node);
- updateIsChecks(tests, usePositive: true);
-
- LocalsHandler thenLocals = locals;
- locals = new LocalsHandler.from(saved, node);
- if (simpleCondition) updateIsChecks(tests, usePositive: false);
- visit(node.message);
- locals.seenReturnOrThrow = true;
- saved.mergeDiamondFlow(thenLocals, locals);
- locals = saved;
- return null;
- }
-
- @override
- TypeInformation bulkHandleSet(ast.SendSet node, _) {
- return handleSendSet(node);
- }
-
- @override
- TypeInformation bulkHandleCompound(ast.SendSet node, _) {
- return handleSendSet(node);
- }
-
- @override
- TypeInformation bulkHandleSetIfNull(ast.SendSet node, _) {
- return handleSendSet(node);
- }
-
- @override
- TypeInformation bulkHandlePrefix(ast.SendSet node, _) {
- return handleSendSet(node);
- }
-
- @override
- TypeInformation bulkHandlePostfix(ast.SendSet node, _) {
- return handleSendSet(node);
- }
-
- @override
- TypeInformation bulkHandleError(ast.Node node, ErroneousElement error, _) {
- return types.dynamicType;
- }
-
- TypeInformation visitNode(ast.Node node) {
- return node.visitChildren(this);
- }
-
- TypeInformation visit(ast.Node node) {
- return node == null ? null : node.accept(this);
- }
-
- TypeInformation visitLiteralString(ast.LiteralString node) {
- return types.stringLiteralType(node.dartString.slowToString());
- }
-
- TypeInformation visitStringJuxtaposition(ast.StringJuxtaposition node) {
- node.visitChildren(this);
- return types.stringType;
- }
-
- TypeInformation visitLiteralBool(ast.LiteralBool node) {
- return types.boolLiteralType(node.value);
- }
-
- TypeInformation visitLiteralDouble(ast.LiteralDouble node) {
- ConstantSystem constantSystem = closedWorld.constantSystem;
- // The JavaScript backend may turn this literal into an integer at
- // runtime.
- return types.getConcreteTypeFor(
- computeTypeMask(closedWorld, constantSystem.createDouble(node.value)));
- }
-
- TypeInformation visitLiteralInt(ast.LiteralInt node) {
- ConstantSystem constantSystem = closedWorld.constantSystem;
- // The JavaScript backend may turn this literal into a double at
- // runtime.
- return types.getConcreteTypeFor(
- computeTypeMask(closedWorld, constantSystem.createInt(node.value)));
- }
-
- TypeInformation visitLiteralNull(ast.LiteralNull node) {
- return types.nullType;
- }
-
- TypeInformation visitLiteralSymbol(ast.LiteralSymbol node) {
- return types
- .nonNullSubtype(closedWorld.commonElements.symbolImplementationClass);
- }
-
- @override
- void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
- // Deferred access does not affect inference.
- }
-
- TypeInformation handleTypeLiteralGet() {
- return types.typeType;
- }
-
- @override
- TypeInformation bulkHandleNode(ast.Node node, String message, _) {
- return internalError(node, message.replaceAll('#', '$node'));
- }
-
- @override
- TypeInformation visitConstantGet(
- ast.Send node, ConstantExpression constant, _) {
- return bulkHandleNode(node, "Constant read `#` unhandled.", _);
- }
-
- @override
- TypeInformation visitConstantInvoke(
- ast.Send node,
- ConstantExpression constant,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return bulkHandleNode(node, "Constant invoke `#` unhandled.", _);
- }
-
- TypeInformation visitClassTypeLiteralGet(
- ast.Send node, ConstantExpression constant, _) {
- return handleTypeLiteralGet();
- }
-
- TypeInformation visitClassTypeLiteralInvoke(
- ast.Send node,
- ConstantExpression constant,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleTypeLiteralInvoke(arguments);
- }
-
- TypeInformation visitTypedefTypeLiteralGet(
- ast.Send node, ConstantExpression constant, _) {
- return handleTypeLiteralGet();
- }
-
- TypeInformation visitTypedefTypeLiteralInvoke(
- ast.Send node,
- ConstantExpression constant,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleTypeLiteralInvoke(arguments);
- }
-
- TypeInformation visitTypeVariableTypeLiteralGet(
- ast.Send node, TypeVariableElement element, _) {
- return handleTypeLiteralGet();
- }
-
- TypeInformation visitTypeVariableTypeLiteralInvoke(
- ast.Send node,
- TypeVariableElement element,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleTypeLiteralInvoke(arguments);
- }
-
- TypeInformation visitDynamicTypeLiteralGet(
- ast.Send node, ConstantExpression constant, _) {
- return handleTypeLiteralGet();
- }
-
- TypeInformation visitDynamicTypeLiteralInvoke(
- ast.Send node,
- ConstantExpression constant,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleTypeLiteralInvoke(arguments);
- }
-
- TypeInformation _thisType;
- TypeInformation get thisType {
- if (_thisType != null) return _thisType;
- ClassElement cls = outermostElement.enclosingClass;
- if (closedWorld.isUsedAsMixin(cls)) {
- return _thisType = types.nonNullSubtype(cls);
- } else {
- return _thisType = types.nonNullSubclass(cls);
- }
- }
-
- @override
- TypeInformation visitThisGet(ast.Identifier node, _) {
- return thisType;
- }
-
- TypeInformation visitIdentifier(ast.Identifier node) {
- if (node.isThis()) {
- return thisType;
- } else if (node.isSuper()) {
- return internalError(node, 'Unexpected expression $node.');
- } else {
- Element element = elements[node];
- if (Elements.isLocal(element)) {
- LocalElement local = element;
- return locals.use(local);
- }
- return null;
- }
- }
-
- void potentiallyAddIsCheck(ast.Send node) {
- if (!accumulateIsChecks) return;
- if (!Elements.isLocal(elements[node.receiver])) return;
- isChecks.add(node);
- }
-
- void potentiallyAddNullCheck(ast.Send node, ast.Node receiver) {
- if (!accumulateIsChecks) return;
- if (!Elements.isLocal(elements[receiver])) return;
- isChecks.add(node);
- }
-
- void updateIsChecks(List<ast.Node> tests, {bool usePositive}) {
- if (tests == null) return;
- for (ast.Send node in tests) {
- if (node.isTypeTest) {
- if (node.isIsNotCheck) {
- if (usePositive) continue;
- } else {
- if (!usePositive) continue;
- }
- ResolutionDartType type =
- elements.getType(node.typeAnnotationFromIsCheckOrCast);
- Element element = elements[node.receiver];
- if (Elements.isLocal(element)) {
- LocalElement local = element;
- locals.narrow(local, type, node);
- }
- } else {
- Element receiverElement = elements[node.receiver];
- Element argumentElement = elements[node.arguments.first];
- String operator = node.selector.asOperator().source;
- if ((operator == '==' && usePositive) ||
- (operator == '!=' && !usePositive)) {
- // Type the elements as null.
- if (Elements.isLocal(receiverElement)) {
- LocalElement local = receiverElement;
- locals.update(local, types.nullType, node, local.type);
- }
- if (Elements.isLocal(argumentElement)) {
- LocalElement local = argumentElement;
- locals.update(local, types.nullType, node, local.type);
- }
- } else {
- // Narrow the elements to a non-null type.
- ResolutionInterfaceType objectType =
- closedWorld.commonElements.objectType;
- if (Elements.isLocal(receiverElement)) {
- LocalElement local = receiverElement;
- locals.narrow(local, objectType, node);
- }
- if (Elements.isLocal(argumentElement)) {
- LocalElement local = argumentElement;
- locals.narrow(local, objectType, node);
- }
- }
- }
- }
- }
-
- @override
- TypeInformation visitIndex(
- ast.Send node, ast.Node receiver, ast.Node index, _) {
- return handleDynamicInvoke(node);
- }
-
- @override
- TypeInformation visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
- ast.NodeList arguments, Selector selector, _) {
- return handleDynamicInvoke(node);
- }
-
- @override
- TypeInformation visitIfNotNullDynamicPropertyInvoke(ast.Send node,
- ast.Node receiver, ast.NodeList arguments, Selector selector, _) {
- return handleDynamicInvoke(node);
- }
-
- @override
- TypeInformation visitThisPropertyInvoke(
- ast.Send node, ast.NodeList arguments, Selector selector, _) {
- return handleDynamicInvoke(node);
- }
-
- @override
- TypeInformation visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
- TypeInformation firstType = visit(left);
- TypeInformation secondType = visit(right);
- return types.allocateDiamondPhi(types.narrowNotNull(firstType), secondType);
- }
-
- @override
- TypeInformation visitLogicalAnd(
- ast.Send node, ast.Node left, ast.Node right, _) {
- conditionIsSimple = false;
- bool oldAccumulateIsChecks = accumulateIsChecks;
- List<ast.Send> oldIsChecks = isChecks;
- if (!accumulateIsChecks) {
- accumulateIsChecks = true;
- isChecks = <ast.Send>[];
- }
- visit(left);
- LocalsHandler saved = locals;
- locals = new LocalsHandler.from(locals, node);
- updateIsChecks(isChecks, usePositive: true);
- LocalsHandler narrowed;
- if (oldAccumulateIsChecks) {
- narrowed = new LocalsHandler.topLevelCopyOf(locals);
- } else {
- accumulateIsChecks = false;
- isChecks = oldIsChecks;
- }
- visit(right);
- if (oldAccumulateIsChecks) {
- bool invalidatedInRightHandSide(ast.Send test) {
- Element receiver = elements[test.receiver];
- if (receiver is LocalElement) {
- return narrowed.locals[receiver] != locals.locals[receiver];
- }
- return false;
- }
-
- isChecks.removeWhere(invalidatedInRightHandSide);
- }
- saved.mergeDiamondFlow(locals, null);
- locals = saved;
- return types.boolType;
- }
-
- @override
- TypeInformation visitLogicalOr(
- ast.Send node, ast.Node left, ast.Node right, _) {
- conditionIsSimple = false;
- List<ast.Send> tests = <ast.Send>[];
- bool isSimple = handleCondition(left, tests);
- LocalsHandler saved = locals;
- locals = new LocalsHandler.from(locals, node);
- if (isSimple) updateIsChecks(tests, usePositive: false);
- bool oldAccumulateIsChecks = accumulateIsChecks;
- accumulateIsChecks = false;
- visit(right);
- accumulateIsChecks = oldAccumulateIsChecks;
- saved.mergeDiamondFlow(locals, null);
- locals = saved;
- return types.boolType;
- }
-
- @override
- TypeInformation visitNot(ast.Send node, ast.Node expression, _) {
- bool oldAccumulateIsChecks = accumulateIsChecks;
- accumulateIsChecks = false;
- visit(expression);
- accumulateIsChecks = oldAccumulateIsChecks;
- return types.boolType;
- }
-
- @override
- TypeInformation visitIs(
- ast.Send node, ast.Node expression, ResolutionDartType type, _) {
- potentiallyAddIsCheck(node);
- visit(expression);
- return types.boolType;
- }
-
- @override
- TypeInformation visitIsNot(
- ast.Send node, ast.Node expression, ResolutionDartType type, _) {
- potentiallyAddIsCheck(node);
- visit(expression);
- return types.boolType;
- }
-
- @override
- TypeInformation visitAs(
- ast.Send node, ast.Node expression, ResolutionDartType type, _) {
- TypeInformation receiverType = visit(expression);
- return types.narrowType(receiverType, type);
- }
-
- @override
- TypeInformation visitUnary(
- ast.Send node, op.UnaryOperator operator, ast.Node expression, _) {
- return handleDynamicInvoke(node);
- }
-
- @override
- TypeInformation visitNotEquals(
- ast.Send node, ast.Node left, ast.Node right, _) {
- handleDynamicInvoke(node);
- return types.boolType;
- }
-
- @override
- TypeInformation visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
- return handleDynamicInvoke(node);
- }
-
- @override
- TypeInformation visitBinary(ast.Send node, ast.Node left,
- op.BinaryOperator operator, ast.Node right, _) {
- return handleDynamicInvoke(node);
- }
-
- // Because some nodes just visit their children, we may end up
- // visiting a type annotation, that may contain a send in case of a
- // prefixed type. Therefore we explicitly visit the type annotation
- // to avoid confusing the [ResolvedVisitor].
- visitTypeAnnotation(ast.TypeAnnotation node) {}
-
- TypeInformation visitConditional(ast.Conditional node) {
- List<ast.Send> tests = <ast.Send>[];
- bool simpleCondition = handleCondition(node.condition, tests);
- LocalsHandler saved = locals;
- locals = new LocalsHandler.from(locals, node);
- updateIsChecks(tests, usePositive: true);
- TypeInformation firstType = visit(node.thenExpression);
- LocalsHandler thenLocals = locals;
- locals = new LocalsHandler.from(saved, node);
- if (simpleCondition) updateIsChecks(tests, usePositive: false);
- TypeInformation secondType = visit(node.elseExpression);
- saved.mergeDiamondFlow(thenLocals, locals);
- locals = saved;
- TypeInformation type = types.allocateDiamondPhi(firstType, secondType);
- return type;
- }
-
- TypeInformation visitVariableDefinitions(ast.VariableDefinitions node) {
- for (Link<ast.Node> link = node.definitions.nodes;
- !link.isEmpty;
- link = link.tail) {
- ast.Node definition = link.head;
- if (definition is ast.Identifier) {
- LocalElement local = elements[definition];
- locals.update(local, types.nullType, node, local.type);
- } else {
- assert(definition.asSendSet() != null);
- handleSendSet(definition);
- }
- }
- return null;
- }
-
- bool handleCondition(ast.Node node, List<ast.Send> tests) {
- bool oldConditionIsSimple = conditionIsSimple;
- bool oldAccumulateIsChecks = accumulateIsChecks;
- List<ast.Send> oldIsChecks = isChecks;
- accumulateIsChecks = true;
- conditionIsSimple = true;
- isChecks = tests;
- visit(node);
- bool simpleCondition = conditionIsSimple;
- accumulateIsChecks = oldAccumulateIsChecks;
- isChecks = oldIsChecks;
- conditionIsSimple = oldConditionIsSimple;
- return simpleCondition;
- }
-
- TypeInformation visitIf(ast.If node) {
- List<ast.Send> tests = <ast.Send>[];
- bool simpleCondition = handleCondition(node.condition, tests);
- LocalsHandler saved = locals;
- locals = new LocalsHandler.from(locals, node);
- updateIsChecks(tests, usePositive: true);
- visit(node.thenPart);
- LocalsHandler thenLocals = locals;
- locals = new LocalsHandler.from(saved, node);
- if (simpleCondition) updateIsChecks(tests, usePositive: false);
- visit(node.elsePart);
- saved.mergeDiamondFlow(thenLocals, locals);
- locals = saved;
- return null;
- }
-
- void setupBreaksAndContinues(JumpTarget element) {
- if (element == null) return;
- if (element.isContinueTarget) continuesFor[element] = <LocalsHandler>[];
- if (element.isBreakTarget) breaksFor[element] = <LocalsHandler>[];
- }
-
- void clearBreaksAndContinues(JumpTarget element) {
- continuesFor.remove(element);
- breaksFor.remove(element);
- }
-
- List<LocalsHandler> getBreaks(JumpTarget element) {
- List<LocalsHandler> list = <LocalsHandler>[locals];
- if (element == null) return list;
- if (!element.isBreakTarget) return list;
- return list..addAll(breaksFor[element]);
- }
-
- List<LocalsHandler> getLoopBackEdges(JumpTarget element) {
- List<LocalsHandler> list = <LocalsHandler>[locals];
- if (element == null) return list;
- if (!element.isContinueTarget) return list;
- return list..addAll(continuesFor[element]);
- }
-
- TypeInformation handleLoop(ast.Node node, void logic()) {
- loopLevel++;
- bool changed = false;
- JumpTarget target = elements.getTargetDefinition(node);
- LocalsHandler saved = locals;
- saved.startLoop(node);
- do {
- // Setup (and clear in case of multiple iterations of the loop)
- // the lists of breaks and continues seen in the loop.
- setupBreaksAndContinues(target);
- locals = new LocalsHandler.from(saved, node);
- logic();
- changed = saved.mergeAll(getLoopBackEdges(target));
- } while (changed);
- loopLevel--;
- saved.endLoop(node);
- bool keepOwnLocals = node.asDoWhile() == null;
- saved.mergeAfterBreaks(getBreaks(target), keepOwnLocals: keepOwnLocals);
- locals = saved;
- clearBreaksAndContinues(target);
- return null;
- }
-
- TypeInformation visitWhile(ast.While node) {
- return handleLoop(node, () {
- List<ast.Send> tests = <ast.Send>[];
- handleCondition(node.condition, tests);
- updateIsChecks(tests, usePositive: true);
- visit(node.body);
- });
- }
-
- TypeInformation visitDoWhile(ast.DoWhile node) {
- return handleLoop(node, () {
- visit(node.body);
- List<ast.Send> tests = <ast.Send>[];
- handleCondition(node.condition, tests);
- // TODO(29309): This condition appears to strengthen both the back-edge
- // and exit-edge. For now, avoid strengthening on the condition until the
- // proper fix is found.
- //
- // updateIsChecks(tests, usePositive: true);
- });
- }
-
- TypeInformation visitFor(ast.For node) {
- visit(node.initializer);
- return handleLoop(node, () {
- List<ast.Send> tests = <ast.Send>[];
- handleCondition(node.condition, tests);
- updateIsChecks(tests, usePositive: true);
- visit(node.body);
- visit(node.update);
- });
- }
-
- TypeInformation visitTryStatement(ast.TryStatement node) {
- LocalsHandler saved = locals;
- locals = new LocalsHandler.from(locals, node, useOtherTryBlock: false);
- initializationIsIndefinite();
- visit(node.tryBlock);
- saved.mergeDiamondFlow(locals, null);
- locals = saved;
- for (ast.Node catchBlock in node.catchBlocks) {
- saved = locals;
- locals = new LocalsHandler.from(locals, catchBlock);
- visit(catchBlock);
- saved.mergeDiamondFlow(locals, null);
- locals = saved;
- }
- visit(node.finallyBlock);
- return null;
- }
-
- TypeInformation visitThrow(ast.Throw node) {
- node.visitChildren(this);
- locals.seenReturnOrThrow = true;
- return types.nonNullEmpty();
- }
-
- TypeInformation visitCatchBlock(ast.CatchBlock node) {
- ast.Node exception = node.exception;
- if (exception != null) {
- ResolutionDartType type = elements.getType(node.type);
- TypeInformation mask;
- if (type == null || type.treatAsDynamic || type.isTypeVariable) {
- mask = types.dynamicType;
- } else {
- ResolutionInterfaceType interfaceType = type;
- mask = types.nonNullSubtype(interfaceType.element);
- }
- LocalElement local = elements[exception];
- locals.update(local, mask, node, local.type);
- }
- ast.Node trace = node.trace;
- if (trace != null) {
- LocalElement local = elements[trace];
- locals.update(local, types.dynamicType, node, local.type);
- }
- visit(node.block);
- return null;
- }
-
- TypeInformation visitParenthesizedExpression(
- ast.ParenthesizedExpression node) {
- return visit(node.expression);
- }
-
- TypeInformation visitBlock(ast.Block node) {
- if (node.statements != null) {
- for (ast.Node statement in node.statements) {
- visit(statement);
- if (locals.aborts) break;
- }
- }
- return null;
- }
-
- TypeInformation visitLabeledStatement(ast.LabeledStatement node) {
- ast.Statement body = node.statement;
- if (body is ast.Loop ||
- body is ast.SwitchStatement ||
- Elements.isUnusedLabel(node, elements)) {
- // Loops and switches handle their own labels.
- visit(body);
- } else {
- JumpTarget targetElement = elements.getTargetDefinition(body);
- setupBreaksAndContinues(targetElement);
- visit(body);
- locals.mergeAfterBreaks(getBreaks(targetElement));
- clearBreaksAndContinues(targetElement);
- }
- return null;
- }
-
- TypeInformation visitBreakStatement(ast.BreakStatement node) {
- JumpTarget target = elements.getTargetOf(node);
- locals.seenBreakOrContinue = true;
- // Do a deep-copy of the locals, because the code following the
- // break will change them.
- breaksFor[target].add(new LocalsHandler.deepCopyOf(locals));
- return null;
- }
-
- TypeInformation visitContinueStatement(ast.ContinueStatement node) {
- JumpTarget target = elements.getTargetOf(node);
- locals.seenBreakOrContinue = true;
- // Do a deep-copy of the locals, because the code following the
- // continue will change them.
- continuesFor[target].add(new LocalsHandler.deepCopyOf(locals));
- return null;
- }
-
- internalError(Spannable node, String reason) {
- reporter.internalError(node, reason);
- }
-
- TypeInformation visitSwitchStatement(ast.SwitchStatement node) {
- visit(node.parenthesizedExpression);
-
- setupBreaksAndContinues(elements.getTargetDefinition(node));
- if (Elements.switchStatementHasContinue(node, elements)) {
- void forEachLabeledCase(void action(JumpTarget target)) {
- for (ast.SwitchCase switchCase in node.cases) {
- for (ast.Node labelOrCase in switchCase.labelsAndCases) {
- if (labelOrCase.asLabel() == null) continue;
- LabelDefinition labelElement =
- elements.getLabelDefinition(labelOrCase);
- if (labelElement != null) {
- action(labelElement.target);
- }
- }
- }
- }
-
- forEachLabeledCase((JumpTarget target) {
- setupBreaksAndContinues(target);
- });
-
- // If the switch statement has a continue, we conservatively
- // visit all cases and update [locals] until we have reached a
- // fixed point.
- bool changed;
- locals.startLoop(node);
- do {
- changed = false;
- for (ast.Node switchCase in node.cases) {
- LocalsHandler saved = locals;
- locals = new LocalsHandler.from(locals, switchCase);
- visit(switchCase);
- changed = saved.mergeAll([locals]) || changed;
- locals = saved;
- }
- } while (changed);
- locals.endLoop(node);
-
- forEachLabeledCase((JumpTarget target) {
- clearBreaksAndContinues(target);
- });
- } else {
- LocalsHandler saved = locals;
- List<LocalsHandler> localsToMerge = <LocalsHandler>[];
- bool hasDefaultCase = false;
-
- for (ast.SwitchCase switchCase in node.cases) {
- if (switchCase.isDefaultCase) {
- hasDefaultCase = true;
- }
- locals = new LocalsHandler.from(saved, switchCase);
- visit(switchCase);
- localsToMerge.add(locals);
- }
- saved.mergeAfterBreaks(localsToMerge, keepOwnLocals: !hasDefaultCase);
- locals = saved;
- }
- clearBreaksAndContinues(elements.getTargetDefinition(node));
- return null;
- }
-
- TypeInformation visitCascadeReceiver(ast.CascadeReceiver node) {
- var type = visit(node.expression);
- cascadeReceiverStack.add(type);
- return type;
- }
-
- TypeInformation visitCascade(ast.Cascade node) {
- // Ignore the result of the cascade send and return the type of the cascade
- // receiver.
- visit(node.expression);
- return cascadeReceiverStack.removeLast();
- }
-
- void analyzeSuperConstructorCall(ConstructorElement target) {
- assert(target.isDeclaration);
- inferrer.analyze(target);
- isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
- }
-
- TypeInformation run() {
- var node;
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- node = resolvedAst.node;
- }
- ast.Expression initializer;
- if (analyzedElement.isField) {
- initializer = resolvedAst.body;
- if (initializer == null) {
- // Eagerly bailout, because computing the closure data only
- // works for functions and field assignments.
- return types.nullType;
- }
- }
- // Update the locals that are boxed in [locals]. These locals will
- // be handled specially, in that we are computing their LUB at
- // each update, and reading them yields the type that was found in a
- // previous analysis of [outermostElement].
- ScopeInfo scopeInfo = compiler.backendStrategy.closureDataLookup
- .getScopeInfo(analyzedElement);
- scopeInfo.forEachBoxedVariable((variable, field) {
- locals.setCapturedAndBoxed(variable, field);
- });
- if (analyzedElement.isField) {
- return visit(initializer);
- }
-
- MethodElement function = analyzedElement.implementation;
- FunctionSignature signature = function.functionSignature;
- signature.forEachOptionalParameter((FormalElement _element) {
- ParameterElement parameter = _element;
- ast.Expression defaultValue = parameter.initializer;
- // TODO(25566): The default value of a parameter of a redirecting factory
- // constructor comes from the corresponding parameter of the target.
-
- // If this is a default value from a different context (because
- // the current function is synthetic, e.g., a constructor from
- // a mixin application), we have to start a new inferrer visitor
- // with the correct context.
- // TODO(johnniwinther): Remove once function signatures are fixed.
- ElementGraphBuilder visitor = this;
- if (inferrer.hasAlreadyComputedTypeOfParameterDefault(parameter)) return;
-
- FunctionElement declaration = parameter.functionDeclaration.declaration;
- MethodElement declarationMethod = declaration is LocalFunctionElement
- ? declaration.callMethod
- : declaration;
- bool needNewContext = declarationMethod != analyzedElement;
- if (needNewContext) {
- assert(
- declarationMethod is ConstructorElement,
- failedAt(
- parameter,
- "Unexpected function declaration "
- "${declarationMethod}, expected ${analyzedElement}."));
- visitor =
- new ElementGraphBuilder(declarationMethod, compiler, inferrer);
- }
- TypeInformation type =
- (defaultValue == null) ? types.nullType : visitor.visit(defaultValue);
- inferrer.setDefaultTypeOfParameter(parameter, type,
- isInstanceMember: function.isInstanceMember);
- });
-
- if (closedWorld.nativeData.isNativeMember(analyzedElement)) {
- // Native methods do not have a body, and we currently just say
- // they return dynamic.
- return types.dynamicType;
- }
-
- if (analyzedElement.isGenerativeConstructor) {
- ConstructorElement analyzedConstructor = analyzedElement;
- isThisExposed = false;
- signature.forEachParameter((FormalElement _element) {
- ParameterElement element = _element;
- TypeInformation parameterType = inferrer.typeOfParameter(element);
- if (element.isInitializingFormal) {
- InitializingFormalElement initializingFormal = element;
- if (initializingFormal.fieldElement.isFinal) {
- inferrer.recordTypeOfField(
- initializingFormal.fieldElement, parameterType);
- } else {
- locals.updateField(initializingFormal.fieldElement, parameterType);
- inferrer.recordTypeOfField(
- initializingFormal.fieldElement, parameterType);
- }
- }
- locals.update(element, parameterType, node, element.type);
- });
- ClassElement cls = analyzedConstructor.enclosingClass;
- Spannable spannable = node;
- if (analyzedConstructor.isSynthesized) {
- spannable = analyzedConstructor;
- synthesizeForwardingCall(
- spannable, analyzedConstructor.definingConstructor);
- } else {
- visitingInitializers = true;
- if (node.initializers != null) {
- for (ast.Node initializer in node.initializers) {
- ast.SendSet fieldInitializer = initializer.asSendSet();
- if (fieldInitializer != null) {
- handleSendSet(fieldInitializer);
- } else {
- Element element = elements[initializer];
- handleConstructorSend(initializer, element);
- }
- }
- }
- visitingInitializers = false;
- // For a generative constructor like: `Foo();`, we synthesize
- // a call to the default super constructor (the one that takes
- // no argument). Resolution ensures that such a constructor
- // exists.
- if (!isConstructorRedirect &&
- !seenSuperConstructorCall &&
- !cls.isObject) {
- ConstructorElement target = cls.superclass.lookupDefaultConstructor();
- ArgumentsTypes arguments = new ArgumentsTypes([], {});
- analyzeSuperConstructorCall(target);
- inferrer.registerCalledMember(node, null, null, outermostElement,
- target, arguments, sideEffectsBuilder, inLoop);
- }
- visit(node.body);
- inferrer.recordExposesThis(analyzedConstructor, isThisExposed);
- }
- if (!isConstructorRedirect) {
- // Iterate over all instance fields, and give a null type to
- // fields that we haven't initialized for sure.
- cls.forEachInstanceField((_, FieldElement field) {
- if (field.isFinal) return;
- TypeInformation type = locals.fieldScope.readField(field);
- ResolvedAst resolvedAst = field.resolvedAst;
- if (type == null &&
- (resolvedAst.body == null ||
- resolvedAst.body is ast.LiteralNull)) {
- inferrer.recordTypeOfField(field, types.nullType);
- }
- });
- }
- if (analyzedElement.isGenerativeConstructor && cls.isAbstract) {
- if (closedWorld.isInstantiated(cls)) {
- returnType = types.nonNullSubclass(cls);
- } else {
- // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this
- // case; it's never called.
- returnType = types.nonNullEmpty();
- }
- } else {
- returnType = types.nonNullExact(cls);
- }
- } else {
- signature.forEachParameter((FormalElement _element) {
- ParameterElement element = _element;
- locals.update(
- element, inferrer.typeOfParameter(element), node, element.type);
- });
- visit(node.body);
- switch (function.asyncMarker) {
- case AsyncMarker.SYNC:
- if (returnType == null) {
- // No return in the body.
- returnType = locals.seenReturnOrThrow
- ? types.nonNullEmpty() // Body always throws.
- : types.nullType;
- } else if (!locals.seenReturnOrThrow) {
- // We haven't seen returns on all branches. So the method may
- // also return null.
- recordReturnType(types.nullType);
- }
- break;
-
- case AsyncMarker.SYNC_STAR:
- // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
- // contained is the method body's return type.
- recordReturnType(types.syncStarIterableType);
- break;
-
- case AsyncMarker.ASYNC:
- recordReturnType(types.asyncFutureType);
- break;
-
- case AsyncMarker.ASYNC_STAR:
- recordReturnType(types.asyncStarStreamType);
- break;
- }
- }
-
- assert(breaksFor.isEmpty);
- assert(continuesFor.isEmpty);
- return returnType;
- }
-
- TypeInformation visitFunctionExpression(ast.FunctionExpression node) {
- // We loose track of [this] in closures (see issue 20840). To be on
- // the safe side, we mark [this] as exposed here. We could do better by
- // analyzing the closure.
- // TODO(herhut): Analyze whether closure exposes this.
- isThisExposed = true;
- LocalFunctionElement element = elements.getFunctionDefinition(node);
- // We don't put the closure in the work queue of the
- // inferrer, because it will share information with its enclosing
- // method, like for example the types of local variables.
- LocalsHandler closureLocals =
- new LocalsHandler.from(locals, node, useOtherTryBlock: false);
- ElementGraphBuilder visitor = new ElementGraphBuilder(
- element.callMethod, compiler, inferrer, closureLocals);
- visitor.run();
- inferrer.recordReturnType(element.callMethod, visitor.returnType);
-
- // Record the types of captured non-boxed variables. Types of
- // these variables may already be there, because of an analysis of
- // a previous closure.
- ClosureRepresentationInfo nestedClosureData =
- compiler.backendStrategy.closureDataLookup.getClosureInfo(node);
- nestedClosureData.forEachFreeVariable((variable, field) {
- if (!nestedClosureData.isVariableBoxed(variable)) {
- if (variable == nestedClosureData.thisLocal) {
- inferrer.recordTypeOfField(field, thisType);
- }
- // The type is null for type parameters.
- if (locals.locals[variable] == null) return;
- inferrer.recordTypeOfField(field, locals.locals[variable]);
- }
- capturedVariables.add(variable);
- });
-
- return inferrer.concreteTypes.putIfAbsent(node, () {
- return types.allocateClosure(element.callMethod);
- });
- }
-
- TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) {
- LocalFunctionElement element =
- elements.getFunctionDefinition(node.function);
- TypeInformation type =
- inferrer.concreteTypes.putIfAbsent(node.function, () {
- return types.allocateClosure(element.callMethod);
- });
- locals.update(element, type, node, element.type);
- visit(node.function);
- return type;
- }
-
- TypeInformation visitStringInterpolation(ast.StringInterpolation node) {
- // Interpolation could have any effects since it could call any toString()
- // method.
- // TODO(sra): This could be modelled by a call to toString() but with a
- // guaranteed String return type. Interpolation of known types would get
- // specialized effects. This would not currently be effective since the JS
- // code in the toString methods for intercepted primitive types is assumed
- // to have all effects. Effect annotations on JS code would be needed to
- // get the benefit.
- sideEffectsBuilder.setAllSideEffects();
- node.visitChildren(this);
- return types.stringType;
- }
-
- TypeInformation visitLiteralList(ast.LiteralList node) {
- // We only set the type once. We don't need to re-visit the children
- // when re-analyzing the node.
- return inferrer.concreteTypes.putIfAbsent(node, () {
- TypeInformation elementType;
- int length = 0;
- for (ast.Node element in node.elements.nodes) {
- TypeInformation type = visit(element);
- elementType = elementType == null
- ? types.allocatePhi(null, null, type, isTry: false)
- : types.addPhiInput(null, elementType, type);
- length++;
- }
- elementType = elementType == null
- ? types.nonNullEmpty()
- : types.simplifyPhi(null, null, elementType);
- TypeInformation containerType =
- node.isConst ? types.constListType : types.growableListType;
- return types.allocateList(
- containerType, node, outermostElement, elementType, length);
- });
- }
-
- TypeInformation visitLiteralMap(ast.LiteralMap node) {
- return inferrer.concreteTypes.putIfAbsent(node, () {
- ast.NodeList entries = node.entries;
- List keyTypes = [];
- List valueTypes = [];
-
- for (ast.LiteralMapEntry entry in entries) {
- keyTypes.add(visit(entry.key));
- valueTypes.add(visit(entry.value));
- }
-
- TypeInformation type = node.isConst ? types.constMapType : types.mapType;
- return types.allocateMap(
- type, node, outermostElement, keyTypes, valueTypes);
- });
- }
-
- bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper();
-
- bool isInClassOrSubclass(Element element) {
- ClassElement cls = outermostElement.enclosingClass;
- ClassElement enclosing = element.enclosingClass;
- return closedWorld.isSubclassOf(enclosing, cls);
- }
-
- void checkIfExposesThis(Selector selector, TypeMask mask) {
- if (isThisExposed) return;
- if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
- // TODO(ngeoffray): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- } else {
- inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
- if (element.isField) {
- FieldElement field = element;
- ResolvedAst elementResolvedAst = field.resolvedAst;
- if (!selector.isSetter &&
- isInClassOrSubclass(field) &&
- !field.isFinal &&
- locals.fieldScope.readField(field) == null &&
- elementResolvedAst.body == null) {
- // If the field is being used before this constructor
- // actually had a chance to initialize it, say it can be
- // null.
- inferrer.recordTypeOfField(field, types.nullType);
- }
- // Accessing a field does not expose [:this:].
- return true;
- }
- // TODO(ngeoffray): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- return false;
- });
- }
- }
-
- bool get inInstanceContext {
- return (outermostElement.isInstanceMember && !outermostElement.isField) ||
- outermostElement.isGenerativeConstructor;
- }
-
- bool treatAsInstanceMember(Element element) {
- return (Elements.isUnresolved(element) && inInstanceContext) ||
- (element != null && element.isInstanceMember);
- }
-
- TypeInformation handleSendSet(ast.SendSet node) {
- Element element = elements[node];
- if (!Elements.isUnresolved(element) && element.impliesType) {
- node.visitChildren(this);
- return types.dynamicType;
- }
-
- Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
- TypeMask getterMask = memberData.typeOfGetter(node);
- TypeMask operatorMask = memberData.typeOfOperator(node);
- Selector setterSelector = elements.getSelector(node);
- TypeMask setterMask = memberData.typeOfSend(node);
-
- String op = node.assignmentOperator.source;
- bool isIncrementOrDecrement = op == '++' || op == '--';
-
- TypeInformation receiverType;
- bool isCallOnThis = false;
- if (node.receiver == null) {
- if (treatAsInstanceMember(element)) {
- receiverType = thisType;
- isCallOnThis = true;
- }
- } else {
- if (node.receiver != null) {
- Element receiver = elements[node.receiver];
- if (receiver is! PrefixElement && receiver is! ClassElement) {
- // TODO(johnniwinther): Avoid blindly recursing on the receiver.
- receiverType = visit(node.receiver);
- }
- }
- isCallOnThis = isThisOrSuper(node.receiver);
- }
-
- TypeInformation rhsType;
-
- if (isIncrementOrDecrement) {
- rhsType = types.uint31Type;
- if (node.isIndex) visit(node.arguments.head);
- } else if (node.isIndex) {
- visit(node.arguments.head);
- rhsType = visit(node.arguments.tail.head);
- } else {
- rhsType = visit(node.arguments.head);
- }
-
- if (!visitingInitializers && !isThisExposed) {
- for (ast.Node node in node.arguments) {
- if (isThisOrSuper(node)) {
- isThisExposed = true;
- break;
- }
- }
- if (!isThisExposed && isCallOnThis) {
- checkIfExposesThis(
- setterSelector, types.newTypedSelector(receiverType, setterMask));
- if (getterSelector != null) {
- checkIfExposesThis(
- getterSelector, types.newTypedSelector(receiverType, getterMask));
- }
- }
- }
-
- if (node.isIndex) {
- return internalError(node, "Unexpected index operation");
- } else if (op == '=') {
- return handlePlainAssignment(node, element, setterSelector, setterMask,
- receiverType, rhsType, node.arguments.head);
- } else {
- // [foo ??= bar], [: foo++ :] or [: foo += 1 :].
- TypeInformation getterType;
- TypeInformation newType;
-
- if (Elements.isMalformed(element)) return types.dynamicType;
-
- if (Elements.isStaticOrTopLevelField(element)) {
- Element getterElement = elements[node.selector];
- getterType = handleStaticSend(
- node, getterSelector, getterMask, getterElement, null);
- } else if (Elements.isUnresolved(element) ||
- element.isSetter ||
- element.isField) {
- getterType = handleDynamicSend(CallType.complex, node, getterSelector,
- getterMask, receiverType, null);
- } else if (element.isLocal) {
- LocalElement local = element;
- getterType = locals.use(local);
- } else {
- // Bogus SendSet, for example [: myMethod += 42 :].
- getterType = types.dynamicType;
- }
-
- if (op == '??=') {
- newType = types.allocateDiamondPhi(getterType, rhsType);
- } else {
- Selector operatorSelector =
- elements.getOperatorSelectorInComplexSendSet(node);
- newType = handleDynamicSend(CallType.complex, node, operatorSelector,
- operatorMask, getterType, new ArgumentsTypes([rhsType], null));
- }
-
- if (Elements.isStaticOrTopLevelField(element)) {
- handleStaticSend(node, setterSelector, setterMask, element,
- new ArgumentsTypes([newType], null));
- } else if (Elements.isUnresolved(element) ||
- element.isSetter ||
- element.isField) {
- handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
- receiverType, new ArgumentsTypes([newType], null));
- } else if (element.isLocal) {
- LocalElement local = element;
- locals.update(local, newType, node, local.type,
- isSetIfNull: node.isIfNullAssignment);
- }
-
- if (node.isPostfix) {
- if (node.isConditional) {
- return getterType;
- } else {
- // We have just successfully performed a `+ 1` operation on the getter
- // so we know it to be not `null`.
- return types.narrowNotNull(getterType);
- }
- } else {
- return newType;
- }
- }
- }
-
- /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`.
- TypeInformation handleCompoundIndexSet(
- ast.SendSet node,
- TypeInformation receiverType,
- TypeInformation indexType,
- TypeInformation rhsType) {
- Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
-
- TypeMask getterMask = memberData.typeOfGetter(node);
- Selector operatorSelector =
- elements.getOperatorSelectorInComplexSendSet(node);
- TypeMask operatorMask = memberData.typeOfOperator(node);
- Selector setterSelector = elements.getSelector(node);
- TypeMask setterMask = memberData.typeOfSend(node);
-
- TypeInformation getterType = handleDynamicSend(
- CallType.complex,
- node,
- getterSelector,
- getterMask,
- receiverType,
- new ArgumentsTypes([indexType], null));
-
- TypeInformation returnType;
- if (node.isIfNullAssignment) {
- returnType = types.allocateDiamondPhi(getterType, rhsType);
- } else {
- returnType = handleDynamicSend(CallType.complex, node, operatorSelector,
- operatorMask, getterType, new ArgumentsTypes([rhsType], null));
- }
- handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
- receiverType, new ArgumentsTypes([indexType, returnType], null));
-
- if (node.isPostfix) {
- return getterType;
- } else {
- return returnType;
- }
- }
-
- /// Handle compound prefix/postfix operations, like `a[0]++`.
- TypeInformation handleCompoundPrefixPostfix(
- ast.Send node, TypeInformation receiverType, TypeInformation indexType) {
- return handleCompoundIndexSet(
- node, receiverType, indexType, types.uint31Type);
- }
-
- @override
- TypeInformation visitIndexPostfix(ast.Send node, ast.Node receiver,
- ast.Node index, op.IncDecOperator operator, _) {
- TypeInformation receiverType = visit(receiver);
- TypeInformation indexType = visit(index);
- return handleCompoundPrefixPostfix(node, receiverType, indexType);
- }
-
- @override
- TypeInformation visitIndexPrefix(ast.Send node, ast.Node receiver,
- ast.Node index, op.IncDecOperator operator, _) {
- TypeInformation receiverType = visit(receiver);
- TypeInformation indexType = visit(index);
- return handleCompoundPrefixPostfix(node, receiverType, indexType);
- }
-
- @override
- TypeInformation visitCompoundIndexSet(ast.SendSet node, ast.Node receiver,
- ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) {
- TypeInformation receiverType = visit(receiver);
- TypeInformation indexType = visit(index);
- TypeInformation rhsType = visit(rhs);
- return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
- }
-
- @override
- TypeInformation visitIndexSetIfNull(
- ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
- TypeInformation receiverType = visit(receiver);
- TypeInformation indexType = visit(index);
- TypeInformation rhsType = visit(rhs);
- return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
- }
-
- @override
- TypeInformation visitSuperIndexPrefix(ast.Send node, MethodElement getter,
- MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
- }
-
- @override
- TypeInformation visitSuperIndexPostfix(ast.Send node, MethodElement getter,
- MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
- }
-
- /// Handle compound prefix/postfix operations, like `super[0]++`.
- TypeInformation handleSuperIndexPrefixPostfix(ast.Send node, Element getter,
- Element setter, TypeInformation indexType) {
- return _handleSuperCompoundIndexSet(
- node, getter, setter, indexType, types.uint31Type);
- }
-
- /// Handle compound super index set, like `super[42] =+ 2`.
- TypeInformation handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
- Element setter, ast.Node index, ast.Node rhs) {
- TypeInformation indexType = visit(index);
- TypeInformation rhsType = visit(rhs);
- return _handleSuperCompoundIndexSet(
- node, getter, setter, indexType, rhsType);
- }
-
- TypeInformation _handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
- Element setter, TypeInformation indexType, TypeInformation rhsType) {
- Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
-
- TypeMask getterMask = memberData.typeOfGetter(node);
- Selector setterSelector = elements.getSelector(node);
- TypeMask setterMask = memberData.typeOfSend(node);
-
- TypeInformation getterType = handleSuperSend(node, getterSelector,
- getterMask, getter, new ArgumentsTypes([indexType], null));
-
- TypeInformation returnType;
- if (node.isIfNullAssignment) {
- returnType = types.allocateDiamondPhi(getterType, rhsType);
- } else {
- Selector operatorSelector =
- elements.getOperatorSelectorInComplexSendSet(node);
- TypeMask operatorMask = memberData.typeOfOperator(node);
- returnType = handleDynamicSend(CallType.complex, node, operatorSelector,
- operatorMask, getterType, new ArgumentsTypes([rhsType], null));
- }
- handleSuperSend(node, setterSelector, setterMask, setter,
- new ArgumentsTypes([indexType, returnType], null));
-
- return node.isPostfix ? getterType : returnType;
- }
-
- TypeInformation handleSuperSend(ast.Node node, Selector selector,
- TypeMask mask, Element element, ArgumentsTypes arguments) {
- if (element.isMalformed) {
- return handleSuperNoSuchMethod(node, selector, mask, arguments);
- } else {
- return handleStaticSend(node, selector, mask, element, arguments);
- }
- }
-
- @override
- TypeInformation visitSuperCompoundIndexSet(
- ast.SendSet node,
- MethodElement getter,
- MethodElement setter,
- ast.Node index,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompoundIndexSet(node, getter, setter, index, rhs);
- }
-
- @override
- TypeInformation visitSuperIndexSetIfNull(
- ast.SendSet node,
- MethodElement getter,
- MethodElement setter,
- ast.Node index,
- ast.Node rhs,
- _) {
- return handleSuperCompoundIndexSet(node, getter, setter, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperCompoundIndexSet(
- ast.SendSet node,
- Element element,
- ast.Node index,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompoundIndexSet(node, element, element, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperIndexSetIfNull(
- ast.Send node, Element element, ast.Node index, ast.Node rhs, _) {
- return handleSuperCompoundIndexSet(node, element, element, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGetterCompoundIndexSet(
- ast.SendSet node,
- Element element,
- MethodElement setter,
- ast.Node index,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompoundIndexSet(node, element, setter, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node,
- Element element, MethodElement setter, ast.Node index, ast.Node rhs, _) {
- return handleSuperCompoundIndexSet(node, element, setter, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSetterCompoundIndexSet(
- ast.SendSet node,
- MethodElement getter,
- Element element,
- ast.Node index,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompoundIndexSet(node, getter, element, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node,
- MethodElement getter, Element element, ast.Node index, ast.Node rhs, _) {
- return handleSuperCompoundIndexSet(node, getter, element, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperIndexPrefix(ast.Send node,
- Element element, ast.Node index, op.IncDecOperator operator, _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, element, element, indexType);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGetterIndexPrefix(
- ast.SendSet node,
- Element element,
- MethodElement setter,
- ast.Node index,
- op.IncDecOperator operator,
- _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSetterIndexPrefix(
- ast.SendSet node,
- MethodElement getter,
- Element element,
- ast.Node index,
- op.IncDecOperator operator,
- _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
- }
-
- @override
- TypeInformation visitUnresolvedSuperIndexPostfix(ast.Send node,
- Element element, ast.Node index, op.IncDecOperator operator, _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, element, element, indexType);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGetterIndexPostfix(
- ast.SendSet node,
- Element element,
- MethodElement setter,
- ast.Node index,
- op.IncDecOperator operator,
- _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSetterIndexPostfix(
- ast.SendSet node,
- MethodElement getter,
- Element element,
- ast.Node index,
- op.IncDecOperator operator,
- _) {
- TypeInformation indexType = visit(index);
- return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
- }
-
- @override
- TypeInformation visitSuperFieldCompound(ast.Send node, FieldElement field,
- op.AssignmentOperator operator, ast.Node rhs, _) {
- return handleSuperCompound(node, field, field, rhs);
- }
-
- @override
- TypeInformation visitSuperFieldSetterCompound(
- ast.Send node,
- FieldElement field,
- SetterElement setter,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompound(node, field, setter, rhs);
- }
-
- @override
- TypeInformation visitSuperGetterFieldCompound(
- ast.Send node,
- GetterElement getter,
- FieldElement field,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompound(node, getter, field, rhs);
- }
-
- @override
- TypeInformation visitSuperGetterSetterCompound(
- ast.Send node,
- GetterElement getter,
- SetterElement setter,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompound(node, getter, setter, rhs);
- }
-
- @override
- TypeInformation visitSuperMethodSetterCompound(
- ast.Send node,
- FunctionElement method,
- SetterElement setter,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompound(node, method, setter, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperCompound(ast.Send node, Element element,
- op.AssignmentOperator operator, ast.Node rhs, _) {
- return handleSuperCompound(node, element, element, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGetterCompound(
- ast.SendSet node,
- Element getter,
- SetterElement setter,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompound(node, getter, setter, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSetterCompound(
- ast.Send node,
- GetterElement getter,
- Element setter,
- op.AssignmentOperator operator,
- ast.Node rhs,
- _) {
- return handleSuperCompound(node, getter, setter, rhs);
- }
-
- @override
- TypeInformation visitSuperFieldFieldSetIfNull(ast.Send node,
- FieldElement readField, FieldElement writtenField, ast.Node rhs, _) {
- return handleSuperCompound(node, readField, writtenField, rhs);
- }
-
- @override
- TypeInformation visitSuperFieldSetIfNull(
- ast.Send node, FieldElement field, ast.Node rhs, _) {
- return handleSuperCompound(node, field, field, rhs);
- }
-
- @override
- TypeInformation visitSuperFieldSetterSetIfNull(ast.Send node,
- FieldElement field, SetterElement setter, ast.Node rhs, _) {
- return handleSuperCompound(node, field, setter, rhs);
- }
-
- @override
- TypeInformation visitSuperGetterFieldSetIfNull(ast.Send node,
- GetterElement getter, FieldElement field, ast.Node rhs, _) {
- return handleSuperCompound(node, getter, field, rhs);
- }
-
- @override
- TypeInformation visitSuperGetterSetterSetIfNull(ast.Send node,
- GetterElement getter, SetterElement setter, ast.Node rhs, _) {
- return handleSuperCompound(node, getter, setter, rhs);
- }
-
- @override
- TypeInformation visitSuperMethodSetIfNull(
- ast.Send node, FunctionElement method, ast.Node rhs, _) {
- return handleSuperCompound(node, method, null, rhs);
- }
-
- @override
- TypeInformation visitSuperMethodSetterSetIfNull(ast.Send node,
- FunctionElement method, SetterElement setter, ast.Node rhs, _) {
- return handleSuperCompound(node, method, setter, rhs);
- }
-
- TypeInformation handleSuperCompound(
- ast.SendSet node, Element getter, Element setter, ast.Node rhs) {
- TypeInformation rhsType = visit(rhs);
- return _handleSuperCompound(node, getter, setter, rhsType);
- }
-
- @override
- TypeInformation visitSuperFieldFieldPostfix(
- ast.SendSet node,
- FieldElement readField,
- FieldElement writtenField,
- op.IncDecOperator operator,
- _) {
- return handleSuperPrefixPostfix(node, readField, writtenField);
- }
-
- @override
- TypeInformation visitSuperFieldFieldPrefix(
- ast.SendSet node,
- FieldElement readField,
- FieldElement writtenField,
- op.IncDecOperator operator,
- _) {
- return handleSuperPrefixPostfix(node, readField, writtenField);
- }
-
- @override
- TypeInformation visitSuperFieldPostfix(
- ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, field, field);
- }
-
- @override
- TypeInformation visitSuperFieldPrefix(
- ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, field, field);
- }
-
- @override
- TypeInformation visitSuperFieldSetterPostfix(ast.SendSet node,
- FieldElement field, SetterElement setter, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, field, setter);
- }
-
- @override
- TypeInformation visitSuperFieldSetterPrefix(ast.SendSet node,
- FieldElement field, SetterElement setter, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, field, setter);
- }
-
- @override
- TypeInformation visitSuperGetterFieldPostfix(ast.SendSet node,
- GetterElement getter, FieldElement field, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, getter, field);
- }
-
- @override
- TypeInformation visitSuperGetterFieldPrefix(ast.SendSet node,
- GetterElement getter, FieldElement field, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, getter, field);
- }
-
- @override
- TypeInformation visitSuperGetterSetterPostfix(
- ast.SendSet node,
- GetterElement getter,
- SetterElement setter,
- op.IncDecOperator operator,
- _) {
- return handleSuperPrefixPostfix(node, getter, setter);
- }
-
- @override
- TypeInformation visitSuperGetterSetterPrefix(
- ast.SendSet node,
- GetterElement getter,
- SetterElement setter,
- op.IncDecOperator operator,
- _) {
- return handleSuperPrefixPostfix(node, getter, setter);
- }
-
- @override
- TypeInformation visitSuperMethodSetterPostfix(
- ast.SendSet node,
- FunctionElement method,
- SetterElement setter,
- op.IncDecOperator operator,
- _) {
- return handleSuperPrefixPostfix(node, method, setter);
- }
-
- @override
- TypeInformation visitSuperMethodSetterPrefix(
- ast.SendSet node,
- FunctionElement method,
- SetterElement setter,
- op.IncDecOperator operator,
- _) {
- return handleSuperPrefixPostfix(node, method, setter);
- }
-
- @override
- TypeInformation visitUnresolvedSuperPrefix(
- ast.SendSet node, Element element, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, element, element);
- }
-
- @override
- TypeInformation visitUnresolvedSuperPostfix(
- ast.SendSet node, Element element, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, element, element);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGetterPrefix(ast.SendSet node,
- Element getter, SetterElement setter, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, getter, setter);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGetterPostfix(ast.SendSet node,
- Element getter, SetterElement setter, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, getter, setter);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSetterPrefix(ast.SendSet node,
- GetterElement getter, Element setter, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, getter, setter);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSetterPostfix(ast.SendSet node,
- GetterElement getter, Element setter, op.IncDecOperator operator, _) {
- return handleSuperPrefixPostfix(node, getter, setter);
- }
-
- TypeInformation handleSuperPrefixPostfix(
- ast.SendSet node, Element getter, Element setter) {
- return _handleSuperCompound(node, getter, setter, types.uint31Type);
- }
-
- TypeInformation _handleSuperCompound(ast.SendSet node, Element getter,
- Element setter, TypeInformation rhsType) {
- Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
- TypeMask getterMask = memberData.typeOfGetter(node);
- Selector setterSelector = elements.getSelector(node);
- TypeMask setterMask = memberData.typeOfSend(node);
-
- TypeInformation getterType =
- handleSuperSend(node, getterSelector, getterMask, getter, null);
-
- TypeInformation returnType;
- if (node.isIfNullAssignment) {
- returnType = types.allocateDiamondPhi(getterType, rhsType);
- } else {
- Selector operatorSelector =
- elements.getOperatorSelectorInComplexSendSet(node);
- TypeMask operatorMask = memberData.typeOfOperator(node);
- returnType = handleDynamicSend(CallType.complex, node, operatorSelector,
- operatorMask, getterType, new ArgumentsTypes([rhsType], null));
- }
- handleSuperSend(node, setterSelector, setterMask, setter,
- new ArgumentsTypes([returnType], null));
-
- return node.isPostfix ? getterType : returnType;
- }
-
- /// Handle index set, like `foo[0] = 42`.
- TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType,
- TypeInformation indexType, TypeInformation rhsType) {
- Selector setterSelector = elements.getSelector(node);
- TypeMask setterMask = memberData.typeOfSend(node);
- handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
- receiverType, new ArgumentsTypes([indexType, rhsType], null));
- return rhsType;
- }
-
- @override
- TypeInformation visitIndexSet(
- ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
- TypeInformation receiverType = visit(receiver);
- TypeInformation indexType = visit(index);
- TypeInformation rhsType = visit(rhs);
- return handleIndexSet(node, receiverType, indexType, rhsType);
- }
-
- /// Handle super index set, like `super[42] = true`.
- TypeInformation handleSuperIndexSet(
- ast.SendSet node, Element element, ast.Node index, ast.Node rhs) {
- TypeInformation indexType = visit(index);
- TypeInformation rhsType = visit(rhs);
- Selector setterSelector = elements.getSelector(node);
- TypeMask setterMask = memberData.typeOfSend(node);
- handleStaticSend(node, setterSelector, setterMask, element,
- new ArgumentsTypes([indexType, rhsType], null));
- return rhsType;
- }
-
- @override
- TypeInformation visitSuperIndexSet(ast.SendSet node, FunctionElement function,
- ast.Node index, ast.Node rhs, _) {
- return handleSuperIndexSet(node, function, index, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperIndexSet(ast.SendSet node,
- ErroneousElement element, ast.Node index, ast.Node rhs, _) {
- return handleSuperIndexSet(node, element, index, rhs);
- }
-
- TypeInformation handlePlainAssignment(
- ast.Node node,
- Element element,
- Selector setterSelector,
- TypeMask setterMask,
- TypeInformation receiverType,
- TypeInformation rhsType,
- ast.Node rhs) {
- ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
- if (Elements.isMalformed(element)) {
- // Code will always throw.
- } else if (Elements.isStaticOrTopLevelField(element)) {
- handleStaticSend(node, setterSelector, setterMask, element, arguments);
- } else if (Elements.isUnresolved(element) || element.isSetter) {
- if (analyzedElement.isGenerativeConstructor &&
- (node.asSendSet() != null) &&
- (node.asSendSet().receiver != null) &&
- node.asSendSet().receiver.isThis()) {
- TypeMask typedMask = types.newTypedSelector(thisType, setterMask);
- if (!closedWorld.includesClosureCall(setterSelector, typedMask)) {
- Iterable<MemberEntity> targets =
- closedWorld.locateMembers(setterSelector, typedMask);
- // We just recognized a field initialization of the form:
- // `this.foo = 42`. If there is only one target, we can update
- // its type.
- if (targets.length == 1) {
- MemberElement single = targets.first;
- if (single.isField) {
- FieldElement field = single;
- locals.updateField(field, rhsType);
- }
- }
- }
- }
- handleDynamicSend(CallType.access, node, setterSelector, setterMask,
- receiverType, arguments);
- } else if (element.isField) {
- FieldElement field = element;
- if (field.isFinal) {
- inferrer.recordTypeOfField(field, rhsType);
- } else {
- if (analyzedElement.isGenerativeConstructor) {
- locals.updateField(field, rhsType);
- }
- if (visitingInitializers) {
- inferrer.recordTypeOfField(field, rhsType);
- } else {
- handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
- receiverType, arguments);
- }
- }
- } else if (element.isLocal) {
- LocalElement local = element;
- ast.SendSet sendSet = node.asSendSet();
- bool isSetIfNull = sendSet != null && sendSet.isIfNullAssignment;
- locals.update(local, rhsType, node, local.type, isSetIfNull: isSetIfNull);
- }
- return rhsType;
- }
-
- /// Handle a super access or invocation that results in a `noSuchMethod` call.
- TypeInformation handleErroneousSuperSend(ast.Send node) {
- ArgumentsTypes arguments =
- node.isPropertyAccess ? null : analyzeArguments(node.arguments);
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- // TODO(herhut): We could do better here if we knew what we
- // are calling does not expose this.
- // TODO(johnniwinther): Do we still need this when calling directly?
- isThisExposed = true;
- return handleSuperNoSuchMethod(node, selector, mask, arguments);
- }
-
- TypeInformation handleSuperNoSuchMethod(ast.Send node, Selector selector,
- TypeMask mask, ArgumentsTypes arguments) {
- // Ensure we create a node, to make explicit the call to the
- // `noSuchMethod` handler.
- ClassElement cls = outermostElement.enclosingClass;
- MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
- if (!Selectors.noSuchMethod_.signatureApplies(element)) {
- ClassElement objectClass = closedWorld.commonElements.objectClass;
- element = objectClass.lookupMember(Identifiers.noSuchMethod_);
- }
- return handleStaticSend(node, selector, mask, element, arguments);
- }
-
- /// Handle a .call invocation on the values retrieved from the super
- /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter.
- TypeInformation handleSuperClosureCall(
- ast.Send node, MemberElement element, ast.NodeList arguments) {
- ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes);
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- // TODO(herhut): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- return inferrer.registerCalledClosure(
- node,
- selector,
- mask,
- inferrer.typeOfMember(element),
- outermostElement,
- argumentTypes,
- sideEffectsBuilder,
- inLoop: inLoop);
- }
-
- /// Handle an invocation of super [method].
- TypeInformation handleSuperMethodInvoke(
- ast.Send node, MethodElement method, ArgumentsTypes arguments) {
- // TODO(herhut): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- return handleStaticSend(node, selector, mask, method, arguments);
- }
-
- /// Handle access to a super field or getter [element].
- TypeInformation handleSuperGet(ast.Send node, Element element) {
- // TODO(herhut): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- return handleStaticSend(node, selector, mask, element, null);
- }
-
- /// Handle update to a super field or setter [element].
- TypeInformation handleSuperSet(ast.Send node, Element element, ast.Node rhs) {
- TypeInformation rhsType = visit(rhs);
- // TODO(herhut): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = true;
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- handleStaticSend(
- node, selector, mask, element, new ArgumentsTypes([rhsType], null));
- return rhsType;
- }
-
- @override
- TypeInformation visitSuperFieldSet(
- ast.Send node, FieldElement method, ast.Node rhs, _) {
- return handleSuperSet(node, method, rhs);
- }
-
- @override
- TypeInformation visitSuperSetterSet(
- ast.SendSet node, SetterElement field, ast.Node rhs, _) {
- return handleSuperSet(node, field, rhs);
- }
-
- @override
- TypeInformation visitUnresolvedSuperIndex(
- ast.Send node, Element element, ast.Node index, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitUnresolvedSuperUnary(
- ast.Send node, op.UnaryOperator operator, Element element, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitUnresolvedSuperBinary(ast.Send node, Element element,
- op.BinaryOperator operator, ast.Node argument, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitUnresolvedSuperGet(ast.Send node, Element element, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitSuperGetterSet(
- ast.Send node, GetterElement getter, ast.Node rhs, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitSuperMethodSet(
- ast.SendSet node, MethodElement method, ast.Node rhs, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitFinalSuperFieldSet(
- ast.Send node, FieldElement method, ast.Node rhs, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitUnresolvedSuperSet(
- ast.Send node, Element element, ast.Node rhs, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitUnresolvedSuperInvoke(
- ast.Send node, Element element, ast.Node argument, Selector selector, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitSuperFieldGet(ast.Send node, FieldElement field, _) {
- return handleSuperGet(node, field);
- }
-
- @override
- TypeInformation visitSuperGetterGet(ast.Send node, MethodElement method, _) {
- return handleSuperGet(node, method);
- }
-
- @override
- TypeInformation visitSuperMethodGet(ast.Send node, MethodElement method, _) {
- return handleSuperGet(node, method);
- }
-
- @override
- TypeInformation visitSuperFieldInvoke(ast.Send node, FieldElement field,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleSuperClosureCall(node, field, arguments);
- }
-
- @override
- TypeInformation visitSuperGetterInvoke(ast.Send node, GetterElement getter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleSuperClosureCall(node, getter, arguments);
- }
-
- @override
- TypeInformation visitSuperMethodInvoke(ast.Send node, MethodElement method,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleSuperMethodInvoke(
- node, method, analyzeArguments(arguments.nodes));
- }
-
- @override
- TypeInformation visitSuperSetterInvoke(ast.Send node, SetterElement setter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleErroneousSuperSend(node);
- }
-
- @override
- TypeInformation visitSuperIndex(
- ast.Send node, MethodElement method, ast.Node index, _) {
- return handleSuperMethodInvoke(
- node, method, analyzeArguments(node.arguments));
- }
-
- @override
- TypeInformation visitSuperEquals(
- ast.Send node, MethodElement method, ast.Node argument, _) {
- // TODO(johnniwinther): Special case ==.
- return handleSuperMethodInvoke(
- node, method, analyzeArguments(node.arguments));
- }
-
- @override
- TypeInformation visitSuperNotEquals(
- ast.Send node, MethodElement method, ast.Node argument, _) {
- // TODO(johnniwinther): Special case !=.
- return handleSuperMethodInvoke(
- node, method, analyzeArguments(node.arguments));
- }
-
- @override
- TypeInformation visitSuperBinary(ast.Send node, MethodElement method,
- op.BinaryOperator operator, ast.Node argument, _) {
- return handleSuperMethodInvoke(
- node, method, analyzeArguments(node.arguments));
- }
-
- @override
- TypeInformation visitSuperUnary(
- ast.Send node, op.UnaryOperator operator, MethodElement method, _) {
- return handleSuperMethodInvoke(
- node, method, analyzeArguments(node.arguments));
- }
-
- @override
- TypeInformation visitSuperMethodIncompatibleInvoke(
- ast.Send node,
- MethodElement method,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleErroneousSuperSend(node);
- }
-
- // Try to find the length given to a fixed array constructor call.
- int findLength(ast.Send node) {
- ast.Node firstArgument = node.arguments.head;
- Element element = elements[firstArgument];
- ast.LiteralInt length = firstArgument.asLiteralInt();
- if (length != null) {
- return length.value;
- } else if (element != null &&
- element.isField &&
- Elements.isStaticOrTopLevelField(element)) {
- FieldElement fieldElement = element;
- if (closedWorld.fieldNeverChanges(fieldElement)) {
- ConstantValue value =
- compiler.backend.constants.getConstantValue(fieldElement.constant);
- if (value != null && value.isInt) {
- IntConstantValue intValue = value;
- return intValue.intValue;
- }
- }
- }
- return null;
- }
-
- TypeInformation visitAwait(ast.Await node) {
- TypeInformation futureType = node.expression.accept(this);
- return inferrer.registerAwait(node, futureType);
- }
-
- TypeInformation visitYield(ast.Yield node) {
- TypeInformation operandType = node.expression.accept(this);
- return inferrer.registerYield(node, operandType);
- }
-
- TypeInformation handleTypeLiteralInvoke(ast.NodeList arguments) {
- // This is reached when users forget to put a `new` in front of a type
- // literal. The emitter will generate an actual call (even though it is
- // likely invalid), and for that it needs to have the arguments processed
- // as well.
- analyzeArguments(arguments.nodes);
- return types.dynamicType;
- }
-
- /// Handle constructor invocation of [constructor].
- TypeInformation handleConstructorSend(
- ast.Send node, ConstructorElement constructor) {
- ConstructorElement target = constructor.implementation;
- ArgumentsTypes arguments = analyzeArguments(node.arguments);
- if (visitingInitializers) {
- if (ast.Initializers.isConstructorRedirect(node)) {
- isConstructorRedirect = true;
- } else if (ast.Initializers.isSuperConstructorCall(node)) {
- seenSuperConstructorCall = true;
- analyzeSuperConstructorCall(constructor);
- }
- }
- // If we are looking at a new expression on a forwarding factory, we have to
- // forward the call to the effective target of the factory.
- // TODO(herhut): Remove the loop once effectiveTarget forwards to patches.
- while (target.isFactoryConstructor) {
- if (!target.isRedirectingFactory) break;
- target = target.effectiveTarget.implementation;
- }
- if (closedWorld.commonElements.isForeign(target)) {
- return handleForeignSend(node, target);
- }
- Selector selector = elements.getSelector(node);
- CallStructure callStructure = selector.callStructure;
- TypeMask mask = memberData.typeOfSend(node);
- // In erroneous code the number of arguments in the selector might not
- // match the function element.
- // TODO(polux): return nonNullEmpty and check it doesn't break anything
- if (target.isMalformed ||
- !callStructure.signatureApplies(target.parameterStructure)) {
- return types.dynamicType;
- }
-
- TypeInformation returnType =
- handleStaticSend(node, selector, mask, target.declaration, arguments);
- if (Elements.isGrowableListConstructorCall(
- constructor, node, closedWorld.commonElements)) {
- return inferrer.concreteTypes.putIfAbsent(
- node,
- () => types.allocateList(types.growableListType, node,
- outermostElement, types.nonNullEmpty(), 0));
- } else if (Elements.isFixedListConstructorCall(
- constructor, node, closedWorld.commonElements) ||
- Elements.isFilledListConstructorCall(
- constructor, node, closedWorld.commonElements)) {
- int length = findLength(node);
- TypeInformation elementType = Elements.isFixedListConstructorCall(
- constructor, node, closedWorld.commonElements)
- ? types.nullType
- : arguments.positional[1];
-
- return inferrer.concreteTypes.putIfAbsent(
- node,
- () => types.allocateList(types.fixedListType, node, outermostElement,
- elementType, length));
- } else if (Elements.isConstructorOfTypedArraySubclass(
- constructor, closedWorld)) {
- int length = findLength(node);
- MemberElement member = target.enclosingClass.lookupMember('[]');
- TypeInformation elementType = inferrer.returnTypeOfMember(member);
- return inferrer.concreteTypes.putIfAbsent(
- node,
- () => types.allocateList(types.nonNullExact(target.enclosingClass),
- node, outermostElement, elementType, length));
- } else {
- return returnType;
- }
- }
-
- @override
- TypeInformation bulkHandleNew(ast.NewExpression node, _) {
- Element element = elements[node.send];
- return handleConstructorSend(node.send, element);
- }
-
- @override
- TypeInformation errorNonConstantConstructorInvoke(
- ast.NewExpression node,
- Element element,
- ResolutionDartType type,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return bulkHandleNew(node, _);
- }
-
- /// Handle invocation of a top level or static field or getter [element].
- TypeInformation handleStaticFieldOrGetterInvoke(
- ast.Send node, MemberElement element) {
- ArgumentsTypes arguments = analyzeArguments(node.arguments);
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- handleStaticSend(node, selector, mask, element, arguments);
- return inferrer.registerCalledClosure(
- node,
- selector,
- mask,
- inferrer.typeOfMember(element),
- outermostElement,
- arguments,
- sideEffectsBuilder,
- inLoop: inLoop);
- }
-
- /// Handle invocation of a top level or static [function].
- TypeInformation handleStaticFunctionInvoke(
- ast.Send node, MethodElement function) {
- if (closedWorld.commonElements.isForeign(function)) {
- return handleForeignSend(node, function);
- }
- ArgumentsTypes arguments = analyzeArguments(node.arguments);
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- return handleStaticSend(node, selector, mask, function, arguments);
- }
-
- /// Handle an static invocation of an unresolved target or with incompatible
- /// arguments to a resolved target.
- TypeInformation handleInvalidStaticInvoke(ast.Send node) {
- analyzeArguments(node.arguments);
- return types.dynamicType;
- }
-
- @override
- TypeInformation visitStaticFieldInvoke(ast.Send node, FieldElement field,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleStaticFieldOrGetterInvoke(node, field);
- }
-
- @override
- TypeInformation visitStaticFunctionInvoke(
- ast.Send node,
- MethodElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleStaticFunctionInvoke(node, function);
- }
-
- @override
- TypeInformation visitStaticFunctionIncompatibleInvoke(
- ast.Send node,
- MethodElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleInvalidStaticInvoke(node);
- }
-
- @override
- TypeInformation visitStaticGetterInvoke(ast.Send node, GetterElement getter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleStaticFieldOrGetterInvoke(node, getter);
- }
-
- @override
- TypeInformation visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleStaticFieldOrGetterInvoke(node, field);
- }
-
- @override
- TypeInformation visitTopLevelFunctionInvoke(
- ast.Send node,
- MethodElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleStaticFunctionInvoke(node, function);
- }
-
- @override
- TypeInformation visitTopLevelFunctionIncompatibleInvoke(
- ast.Send node,
- MethodElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleInvalidStaticInvoke(node);
- }
-
- @override
- TypeInformation visitTopLevelGetterInvoke(ast.Send node, GetterElement getter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- if (getter.isDeferredLoaderGetter) {
- return types.dynamicType;
- }
- return handleStaticFieldOrGetterInvoke(node, getter);
- }
-
- @override
- TypeInformation visitStaticSetterInvoke(ast.Send node, MethodElement setter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleInvalidStaticInvoke(node);
- }
-
- @override
- TypeInformation visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleInvalidStaticInvoke(node);
- }
-
- @override
- TypeInformation visitUnresolvedInvoke(ast.Send node, Element element,
- ast.NodeList arguments, Selector selector, _) {
- return handleInvalidStaticInvoke(node);
- }
-
- TypeInformation handleForeignSend(ast.Send node, Element element) {
- ArgumentsTypes arguments = analyzeArguments(node.arguments);
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- String name = element.name;
- handleStaticSend(node, selector, mask, element, arguments);
- if (name == JavaScriptBackend.JS ||
- name == JavaScriptBackend.JS_EMBEDDED_GLOBAL ||
- name == JavaScriptBackend.JS_BUILTIN) {
- native.NativeBehavior nativeBehavior = elements.getNativeData(node);
- sideEffectsBuilder.add(nativeBehavior.sideEffects);
- return inferrer.typeOfNativeBehavior(nativeBehavior);
- } else if (name == JavaScriptBackend.JS_STRING_CONCAT) {
- return types.stringType;
- } else {
- sideEffectsBuilder.setAllSideEffects();
- return types.dynamicType;
- }
- }
-
- ArgumentsTypes analyzeArguments(Link<ast.Node> arguments) {
- List positional = [];
- Map<String, TypeInformation> named;
- for (var argument in arguments) {
- ast.NamedArgument namedArgument = argument.asNamedArgument();
- if (namedArgument != null) {
- argument = namedArgument.expression;
- if (named == null) named = new Map<String, TypeInformation>();
- named[namedArgument.name.source] = argument.accept(this);
- } else {
- positional.add(argument.accept(this));
- }
- // TODO(ngeoffray): We could do better here if we knew what we
- // are calling does not expose this.
- isThisExposed = isThisExposed || argument.isThis();
- }
- return new ArgumentsTypes(positional, named);
- }
-
- /// Read a local variable, function or parameter.
- TypeInformation handleLocalGet(ast.Send node, LocalElement local) {
- assert(locals.use(local) != null);
- return locals.use(local);
- }
-
- /// Read a static or top level field.
- TypeInformation handleStaticFieldGet(ast.Send node, FieldElement field) {
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- return handleStaticSend(node, selector, mask, field, null);
- }
-
- /// Invoke a static or top level getter.
- TypeInformation handleStaticGetterGet(ast.Send node, GetterElement getter) {
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- return handleStaticSend(node, selector, mask, getter, null);
- }
-
- /// Closurize a static or top level function.
- TypeInformation handleStaticFunctionGet(
- ast.Send node, MethodElement function) {
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- return handleStaticSend(node, selector, mask, function, null);
- }
-
- @override
- TypeInformation visitDynamicPropertyGet(
- ast.Send node, ast.Node receiver, Name name, _) {
- return handleDynamicGet(node);
- }
-
- @override
- TypeInformation visitIfNotNullDynamicPropertyGet(
- ast.Send node, ast.Node receiver, Name name, _) {
- return handleDynamicGet(node);
- }
-
- @override
- TypeInformation visitLocalVariableGet(
- ast.Send node, LocalVariableElement variable, _) {
- return handleLocalGet(node, variable);
- }
-
- @override
- TypeInformation visitParameterGet(
- ast.Send node, ParameterElement parameter, _) {
- return handleLocalGet(node, parameter);
- }
-
- @override
- TypeInformation visitLocalFunctionGet(
- ast.Send node, LocalFunctionElement function, _) {
- return handleLocalGet(node, function);
- }
-
- @override
- TypeInformation visitStaticFieldGet(ast.Send node, FieldElement field, _) {
- return handleStaticFieldGet(node, field);
- }
-
- @override
- TypeInformation visitStaticFunctionGet(
- ast.Send node, MethodElement function, _) {
- return handleStaticFunctionGet(node, function);
- }
-
- @override
- TypeInformation visitStaticGetterGet(ast.Send node, GetterElement getter, _) {
- return handleStaticGetterGet(node, getter);
- }
-
- @override
- TypeInformation visitThisPropertyGet(ast.Send node, Name name, _) {
- return handleDynamicGet(node);
- }
-
- @override
- TypeInformation visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
- return handleStaticFieldGet(node, field);
- }
-
- @override
- TypeInformation visitTopLevelFunctionGet(
- ast.Send node, MethodElement function, _) {
- return handleStaticFunctionGet(node, function);
- }
-
- @override
- TypeInformation visitTopLevelGetterGet(
- ast.Send node, GetterElement getter, _) {
- if (getter.isDeferredLoaderGetter) {
- return types.functionType;
- }
- return handleStaticGetterGet(node, getter);
- }
-
- @override
- TypeInformation visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
- return types.dynamicType;
- }
-
- @override
- TypeInformation visitTopLevelSetterGet(
- ast.Send node, MethodElement setter, _) {
- return types.dynamicType;
- }
-
- @override
- TypeInformation visitUnresolvedGet(ast.Send node, Element element, _) {
- return types.dynamicType;
- }
-
- /// Handle .call invocation on [closure].
- TypeInformation handleCallInvoke(ast.Send node, TypeInformation closure) {
- ArgumentsTypes arguments = analyzeArguments(node.arguments);
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- return handleDynamicSend(
- CallType.access, node, selector, mask, closure, arguments);
- }
-
- @override
- TypeInformation visitExpressionInvoke(ast.Send node, ast.Node expression,
- ast.NodeList arguments, CallStructure callStructure, _) {
- return handleCallInvoke(node, expression.accept(this));
- }
-
- @override
- TypeInformation visitThisInvoke(
- ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
- return handleCallInvoke(node, thisType);
- }
-
- @override
- TypeInformation visitParameterInvoke(
- ast.Send node,
- ParameterElement parameter,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleCallInvoke(node, locals.use(parameter));
- }
-
- @override
- TypeInformation visitLocalVariableInvoke(
- ast.Send node,
- LocalVariableElement variable,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- return handleCallInvoke(node, locals.use(variable));
- }
-
- @override
- TypeInformation visitLocalFunctionInvoke(
- ast.Send node,
- LocalFunctionElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- // This only works for function statements. We need a
- // more sophisticated type system with function types to support
- // more.
- return inferrer.registerCalledMember(node, selector, mask, outermostElement,
- function.callMethod, argumentTypes, sideEffectsBuilder, inLoop);
- }
-
- @override
- TypeInformation visitLocalFunctionIncompatibleInvoke(
- ast.Send node,
- LocalFunctionElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- analyzeArguments(node.arguments);
- return types.dynamicType;
- }
-
- TypeInformation handleStaticSend(ast.Node node, Selector selector,
- TypeMask mask, MemberElement element, ArgumentsTypes arguments) {
- assert(element.isDeclaration);
- assert(!element.isFactoryConstructor ||
- !(element as ConstructorElement).isRedirectingFactory);
- // Erroneous elements may be unresolved, for example missing getters.
- if (Elements.isUnresolved(element)) return types.dynamicType;
- // TODO(herhut): should we follow redirecting constructors here? We would
- // need to pay attention if the constructor is pointing to an erroneous
- // element.
- return inferrer.registerCalledMember(node, selector, mask, outermostElement,
- element, arguments, sideEffectsBuilder, inLoop);
- }
-
- TypeInformation handleDynamicSend(
- CallType callType,
- ast.Node node,
- Selector selector,
- TypeMask mask,
- TypeInformation receiverType,
- ArgumentsTypes arguments) {
- assert(receiverType != null);
- if (types.selectorNeedsUpdate(receiverType, mask)) {
- mask = receiverType == types.dynamicType
- ? null
- : types.newTypedSelector(receiverType, mask);
- inferrer.updateSelectorInMember(
- outermostElement, callType, node, selector, mask);
- }
-
- // If the receiver of the call is a local, we may know more about
- // its type by refining it with the potential targets of the
- // calls.
- ast.Send send = node.asSend();
- bool isConditional = false;
- if (send != null) {
- isConditional = send.isConditional;
- ast.Send receiver = send.receiver?.asSend();
- Element element;
- if (receiver != null && receiver.isPropertyAccess) {
- // We have `local.method()` || `local?.method()`.
- element = elements[receiver];
- } else if (send.receiver == null) {
- // We have `local()`.
- element = elements[send];
- }
- if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
- TypeInformation refinedType = types.refineReceiver(
- selector, mask, receiverType,
- isConditional: send.isConditional);
- LocalElement local = element;
- locals.update(local, refinedType, node, local.type);
- }
- // TODO(johnniwinther): Enable this to improve precision of conditional
- // access. This cannot currently be done because the receiver and the
- // call shares type mask.
- /*if (isConditional) {
- receiverType = types.narrowNotNull(receiverType);
- }*/
- }
-
- return inferrer.registerCalledSelector(callType, node, selector, mask,
- receiverType, outermostElement, arguments, sideEffectsBuilder,
- inLoop: inLoop, isConditional: isConditional);
- }
-
- TypeInformation handleDynamicInvoke(ast.Send node) {
- return _handleDynamicSend(node);
- }
-
- TypeInformation handleDynamicGet(ast.Send node) {
- return _handleDynamicSend(node);
- }
-
- TypeInformation _handleDynamicSend(ast.Send node) {
- Element element = elements[node];
- TypeInformation receiverType;
- bool isCallOnThis = false;
- if (node.receiver == null) {
- if (treatAsInstanceMember(element)) {
- isCallOnThis = true;
- receiverType = thisType;
- }
- } else {
- ast.Node receiver = node.receiver;
- isCallOnThis = isThisOrSuper(receiver);
- receiverType = visit(receiver);
- }
-
- Selector selector = elements.getSelector(node);
- TypeMask mask = memberData.typeOfSend(node);
- if (!isThisExposed && isCallOnThis) {
- checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask));
- }
-
- ArgumentsTypes arguments =
- node.isPropertyAccess ? null : analyzeArguments(node.arguments);
- if (selector.name == '==' || selector.name == '!=') {
- if (types.isNull(receiverType)) {
- potentiallyAddNullCheck(node, node.arguments.head);
- return types.boolType;
- } else if (types.isNull(arguments.positional[0])) {
- potentiallyAddNullCheck(node, node.receiver);
- return types.boolType;
- }
- }
- return handleDynamicSend(
- CallType.access, node, selector, mask, receiverType, arguments);
- }
-
- void recordReturnType(TypeInformation type) {
- MethodElement analyzedMethod = analyzedElement;
- returnType =
- inferrer.addReturnTypeForMethod(analyzedMethod, returnType, type);
- }
-
- TypeInformation synthesizeForwardingCall(
- Spannable node, ConstructorElement element) {
- assert(element.isDeclaration);
- MethodElement function = analyzedElement.implementation;
- FunctionSignature signature = function.functionSignature;
- FunctionSignature calleeSignature = element.functionSignature;
- if (!calleeSignature.isCompatibleWith(signature)) {
- return types.nonNullEmpty();
- }
-
- List<TypeInformation> unnamed = <TypeInformation>[];
- signature.forEachRequiredParameter((FormalElement _element) {
- ParameterElement element = _element;
- assert(locals.use(element) != null);
- unnamed.add(locals.use(element));
- });
-
- Map<String, TypeInformation> named;
- if (signature.optionalParametersAreNamed) {
- named = new Map<String, TypeInformation>();
- signature.forEachOptionalParameter((FormalElement _element) {
- ParameterElement element = _element;
- named[element.name] = locals.use(element);
- });
- } else {
- signature.forEachOptionalParameter((FormalElement _element) {
- ParameterElement element = _element;
- unnamed.add(locals.use(element));
- });
- }
-
- ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named);
- return inferrer.registerCalledMember(node, null, null, outermostElement,
- element, arguments, sideEffectsBuilder, inLoop);
- }
-
- TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
- ConstructorElement element = elements.getRedirectingTargetConstructor(node);
- if (Elements.isMalformed(element)) {
- recordReturnType(types.dynamicType);
- } else {
- // We don't create a selector for redirecting factories, and
- // the send is just a property access. Therefore we must
- // manually create the [ArgumentsTypes] of the call, and
- // manually register [analyzedElement] as a caller of [element].
- TypeInformation mask =
- synthesizeForwardingCall(node.constructorReference, element);
- recordReturnType(mask);
- }
- locals.seenReturnOrThrow = true;
- return null;
- }
-
- TypeInformation visitReturn(ast.Return node) {
- ast.Node expression = node.expression;
- recordReturnType(
- expression == null ? types.nullType : expression.accept(this));
- locals.seenReturnOrThrow = true;
- initializationIsIndefinite();
- return null;
- }
-
- TypeInformation handleForInLoop(
- ast.ForIn node,
- TypeInformation iteratorType,
- Selector currentSelector,
- TypeMask currentMask,
- Selector moveNextSelector,
- TypeMask moveNextMask) {
- handleDynamicSend(CallType.forIn, node, moveNextSelector, moveNextMask,
- iteratorType, new ArgumentsTypes.empty());
- TypeInformation currentType = handleDynamicSend(CallType.forIn, node,
- currentSelector, currentMask, iteratorType, new ArgumentsTypes.empty());
-
- if (node.expression.isThis()) {
- // Any reasonable implementation of an iterator would expose
- // this, so we play it safe and assume it will.
- isThisExposed = true;
- }
-
- ast.Node identifier = node.declaredIdentifier;
- Element element = elements.getForInVariable(node);
- Selector selector = elements.getSelector(identifier);
- TypeMask mask = memberData.typeOfSend(identifier.asSend());
-
- TypeInformation receiverType;
- if (element != null && element.isInstanceMember) {
- receiverType = thisType;
- } else {
- receiverType = types.dynamicType;
- }
-
- handlePlainAssignment(identifier, element, selector, mask, receiverType,
- currentType, node.expression);
- return handleLoop(node, () {
- visit(node.body);
- });
- }
-
- TypeInformation visitAsyncForIn(ast.AsyncForIn node) {
- TypeInformation expressionType = visit(node.expression);
-
- Selector currentSelector = Selectors.current;
- TypeMask currentMask = memberData.typeOfIteratorCurrent(node);
- Selector moveNextSelector = Selectors.moveNext;
- TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node);
-
- ConstructorElement ctor =
- closedWorld.commonElements.streamIteratorConstructor;
-
- /// Synthesize a call to the [StreamIterator] constructor.
- TypeInformation iteratorType = handleStaticSend(
- node, null, null, ctor, new ArgumentsTypes([expressionType], null));
-
- return handleForInLoop(node, iteratorType, currentSelector, currentMask,
- moveNextSelector, moveNextMask);
- }
-
- TypeInformation visitSyncForIn(ast.SyncForIn node) {
- TypeInformation expressionType = visit(node.expression);
- Selector iteratorSelector = Selectors.iterator;
- TypeMask iteratorMask = memberData.typeOfIterator(node);
- Selector currentSelector = Selectors.current;
- TypeMask currentMask = memberData.typeOfIteratorCurrent(node);
- Selector moveNextSelector = Selectors.moveNext;
- TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node);
-
- TypeInformation iteratorType = handleDynamicSend(
- CallType.forIn,
- node,
- iteratorSelector,
- iteratorMask,
- expressionType,
- new ArgumentsTypes.empty());
-
- return handleForInLoop(node, iteratorType, currentSelector, currentMask,
- moveNextSelector, moveNextMask);
- }
-}
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 6d6b2f5..2998bbf 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -18,6 +18,7 @@
import '../native/behavior.dart';
import '../options.dart';
import '../types/constants.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../universe/selector.dart';
import '../universe/side_effects.dart';
@@ -1536,7 +1537,8 @@
@override
visitTryCatch(ir.TryCatch node) {
LocalsHandler saved = _locals;
- _locals = new LocalsHandler.from(_locals, node, useOtherTryBlock: false);
+ _locals = new LocalsHandler.from(_locals, node,
+ isTry: true, useOtherTryBlock: false);
initializationIsIndefinite();
visit(node.body);
saved.mergeDiamondFlow(_locals, null);
@@ -1553,7 +1555,8 @@
@override
visitTryFinally(ir.TryFinally node) {
LocalsHandler saved = _locals;
- _locals = new LocalsHandler.from(_locals, node, useOtherTryBlock: false);
+ _locals = new LocalsHandler.from(_locals, node,
+ isTry: true, useOtherTryBlock: false);
initializationIsIndefinite();
visit(node.body);
saved.mergeDiamondFlow(_locals, null);
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index 1c131cb..8f785fb 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -7,7 +7,7 @@
import '../common/names.dart' show Names;
import '../elements/entities.dart';
import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../types/types.dart' show TypeMask;
+import '../types/masks.dart' show TypeMask;
import '../universe/selector.dart' show Selector;
import 'debug.dart' as debug;
import 'inferrer_engine.dart';
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 184b42e..9a5fdc1 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -10,17 +10,16 @@
import '../compiler.dart';
import '../common_elements.dart';
import '../constants/values.dart';
-import '../elements/elements.dart'
- show ConstructorElement, Elements, MemberElement, ParameterElement;
import '../elements/entities.dart';
import '../elements/names.dart';
import '../js_backend/annotations.dart' as optimizerHints;
-import '../js_backend/mirrors_data.dart';
import '../js_backend/no_such_method_registry.dart';
import '../js_emitter/sorter.dart';
import '../native/behavior.dart' as native;
import '../options.dart';
+import '../types/abstract_value_domain.dart';
import '../types/constants.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../universe/call_structure.dart';
import '../universe/selector.dart';
@@ -32,7 +31,6 @@
import 'locals_handler.dart';
import 'list_tracer.dart';
import 'map_tracer.dart';
-import 'builder.dart';
import 'type_graph_dump.dart';
import 'type_graph_inferrer.dart';
import 'type_graph_nodes.dart';
@@ -60,7 +58,8 @@
ClosedWorld get closedWorld;
ClosedWorldRefiner get closedWorldRefiner;
DiagnosticReporter get reporter;
- CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+ AbstractValueDomain get abstractValueDomain =>
+ closedWorld.abstractValueDomain;
CommonElements get commonElements => closedWorld.commonElements;
// TODO(johnniwinther): This should be part of [ClosedWorld] or
@@ -79,8 +78,7 @@
void analyzeMapAndEnqueue(MapTypeInformation info);
/// Notifies to the inferrer that [analyzedElement] can have return type
- /// [newType]. [currentType] is the type the [ElementGraphBuilder] currently
- /// found.
+ /// [newType]. [currentType] is the type the inference has currently found.
///
/// Returns the new type for [analyzedElement].
TypeInformation addReturnTypeForMethod(
@@ -288,9 +286,6 @@
final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData =
new Map<MemberEntity, GlobalTypeInferenceElementData>();
- // TODO(johnniwinther): This should be accessible throught [closedWorld].
- final MirrorsData mirrorsData;
-
final NoSuchMethodRegistry noSuchMethodRegistry;
final Sorter sorter;
@@ -302,7 +297,6 @@
this._compilerOutput,
this.closedWorld,
this.closedWorldRefiner,
- this.mirrorsData,
this.noSuchMethodRegistry,
this.mainElement,
this.sorter,
@@ -332,7 +326,6 @@
*/
void updateSideEffects(SideEffectsBuilder sideEffectsBuilder,
Selector selector, MemberEntity callee) {
- assert(!(callee is MemberElement && !callee.isDeclaration));
if (callee.isField) {
if (callee.isInstanceMember) {
if (selector.isSetter) {
@@ -402,16 +395,6 @@
GlobalTypeInferenceElementData data = dataOfMember(owner);
assert(validCallType(callType, node));
switch (callType) {
- case CallType.complex:
- if (selector.isSetter || selector.isIndexSet) {
- data.setTypeMask(node, mask);
- } else if (selector.isGetter || selector.isIndex) {
- data.setGetterTypeMaskInComplexSendSet(node, mask);
- } else {
- assert(selector.isOperator);
- data.setOperatorTypeMaskInComplexSendSet(node, mask);
- }
- break;
case CallType.access:
data.setTypeMask(node, mask);
break;
@@ -429,12 +412,10 @@
}
bool checkIfExposesThis(ConstructorEntity element) {
- assert(!(element is ConstructorElement && !element.isDeclaration));
return generativeConstructorsExposingThis.contains(element);
}
void recordExposesThis(ConstructorEntity element, bool exposesThis) {
- assert(!(element is ConstructorElement && !element.isDeclaration));
if (exposesThis) {
generativeConstructorsExposingThis.add(element);
}
@@ -460,7 +441,7 @@
info.bailedOut = false;
info.elementType.inferred = true;
- TypeMask fixedListType = commonMasks.fixedListType;
+ TypeMask fixedListType = abstractValueDomain.fixedListType;
if (info.originalType.forwardTo == fixedListType) {
info.checksGrowable = tracer.callsGrowableMethod;
}
@@ -700,7 +681,6 @@
FunctionEntity lookupCallMethod(ClassEntity cls);
void analyze(MemberEntity element) {
- assert(!(element is MemberElement && !element.isDeclaration));
if (analyzedElements.contains(element)) return;
analyzedElements.add(element);
@@ -901,7 +881,6 @@
void setDefaultTypeOfParameter(Local parameter, TypeInformation type,
{bool isInstanceMember}) {
- assert(!(parameter is ParameterElement && !parameter.isImplementation));
assert(
type != null, failedAt(parameter, "No default type for $parameter."));
TypeInformation existing = defaultTypeOfParameter[parameter];
@@ -928,14 +907,12 @@
}
TypeInformation getDefaultTypeOfParameter(Local parameter) {
- assert(!(parameter is ParameterElement && !parameter.isImplementation));
return defaultTypeOfParameter.putIfAbsent(parameter, () {
return new PlaceholderTypeInformation(types.currentMember);
});
}
bool hasAlreadyComputedTypeOfParameterDefault(Local parameter) {
- assert(!(parameter is ParameterElement && !parameter.isImplementation));
TypeInformation seen = defaultTypeOfParameter[parameter];
return (seen != null && seen is! PlaceholderTypeInformation);
}
@@ -1154,7 +1131,7 @@
} else if (element.isGetter) {
return returnTypeOfMember(element);
} else {
- assert(element is MemberElement && Elements.isUnresolved(element));
+ assert(false, failedAt(element, "Unexpected member $element"));
return types.dynamicType;
}
} else if (element.isGetter || element.isField) {
@@ -1177,7 +1154,7 @@
if ((element.isTopLevel || element.isStatic) && !element.isAssignable) {
return true;
}
- return !mirrorsData.isMemberAccessibleByReflection(element);
+ return true;
}
/// Returns true if global optimizations such as type inferencing can apply to
@@ -1187,8 +1164,7 @@
/// backend calls, but the optimizations don't see those calls.
bool canFunctionParametersBeUsedForGlobalOptimizations(
FunctionEntity function) {
- return !closedWorld.backendUsage.isFunctionUsedByBackend(function) &&
- !mirrorsData.isMemberAccessibleByReflection(function);
+ return !closedWorld.backendUsage.isFunctionUsedByBackend(function);
}
@override
diff --git a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
index dc823ff..7b49435 100644
--- a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
@@ -13,12 +13,12 @@
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
-import '../js_backend/mirrors_data.dart';
import '../js_backend/no_such_method_registry.dart';
import '../js_emitter/sorter.dart';
import '../js_model/locals.dart';
import '../kernel/element_map.dart';
import '../options.dart';
+import '../types/abstract_value_domain.dart';
import '../types/types.dart';
import '../world.dart';
import 'builder_kernel.dart';
@@ -56,7 +56,6 @@
_closureDataLookup,
closedWorld,
closedWorldRefiner,
- _compiler.backend.mirrorsData,
_compiler.backend.noSuchMethodRegistry,
main,
_compiler.backendStrategy.sorter);
@@ -83,14 +82,13 @@
// for closure elements.
inferrer.inferrer.lookupDataOfMember(member),
inferrer,
- isJsInterop,
- dynamicType);
+ isJsInterop);
}
GlobalTypeInferenceParameterResult<ir.Node> createParameterResult(
TypeGraphInferrer<ir.Node> inferrer, Local parameter) {
return new GlobalTypeInferenceParameterResultImpl<ir.Node>(
- parameter, inferrer, dynamicType);
+ parameter, inferrer);
}
}
@@ -109,7 +107,6 @@
this._closureDataLookup,
ClosedWorld closedWorld,
ClosedWorldRefiner closedWorldRefiner,
- MirrorsData mirrorsData,
NoSuchMethodRegistry noSuchMethodRegistry,
FunctionEntity mainElement,
Sorter sorter)
@@ -120,7 +117,6 @@
compilerOutput,
closedWorld,
closedWorldRefiner,
- mirrorsData,
noSuchMethodRegistry,
mainElement,
sorter,
@@ -335,80 +331,65 @@
class KernelGlobalTypeInferenceElementData
extends GlobalTypeInferenceElementData<ir.Node> {
// TODO(johnniwinther): Rename this together with [typeOfSend].
- Map<ir.Node, TypeMask> _sendMap;
+ Map<ir.Node, AbstractValue> _sendMap;
- Map<ir.ForInStatement, TypeMask> _iteratorMap;
- Map<ir.ForInStatement, TypeMask> _currentMap;
- Map<ir.ForInStatement, TypeMask> _moveNextMap;
+ Map<ir.ForInStatement, AbstractValue> _iteratorMap;
+ Map<ir.ForInStatement, AbstractValue> _currentMap;
+ Map<ir.ForInStatement, AbstractValue> _moveNextMap;
@override
- TypeMask typeOfSend(ir.Node node) {
+ AbstractValue typeOfSend(ir.Node node) {
if (_sendMap == null) return null;
return _sendMap[node];
}
@override
- void setCurrentTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
- _currentMap ??= <ir.ForInStatement, TypeMask>{};
+ void setCurrentTypeMask(
+ covariant ir.ForInStatement node, AbstractValue mask) {
+ _currentMap ??= <ir.ForInStatement, AbstractValue>{};
_currentMap[node] = mask;
}
@override
- void setMoveNextTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
- _moveNextMap ??= <ir.ForInStatement, TypeMask>{};
+ void setMoveNextTypeMask(
+ covariant ir.ForInStatement node, AbstractValue mask) {
+ _moveNextMap ??= <ir.ForInStatement, AbstractValue>{};
_moveNextMap[node] = mask;
}
@override
- void setIteratorTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
- _iteratorMap ??= <ir.ForInStatement, TypeMask>{};
+ void setIteratorTypeMask(
+ covariant ir.ForInStatement node, AbstractValue mask) {
+ _iteratorMap ??= <ir.ForInStatement, AbstractValue>{};
_iteratorMap[node] = mask;
}
@override
- TypeMask typeOfIteratorCurrent(covariant ir.ForInStatement node) {
+ AbstractValue typeOfIteratorCurrent(covariant ir.ForInStatement node) {
if (_currentMap == null) return null;
return _currentMap[node];
}
@override
- TypeMask typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
+ AbstractValue typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
if (_moveNextMap == null) return null;
return _moveNextMap[node];
}
@override
- TypeMask typeOfIterator(covariant ir.ForInStatement node) {
+ AbstractValue typeOfIterator(covariant ir.ForInStatement node) {
if (_iteratorMap == null) return null;
return _iteratorMap[node];
}
@override
- void setOperatorTypeMaskInComplexSendSet(ir.Node node, TypeMask mask) {
- throw new UnsupportedError(
- 'KernelGlobalTypeInferenceElementData.setOperatorTypeMaskInComplexSendSet');
- }
-
- @override
- void setGetterTypeMaskInComplexSendSet(ir.Node node, TypeMask mask) {
- throw new UnsupportedError(
- 'KernelGlobalTypeInferenceElementData.setGetterTypeMaskInComplexSendSet');
- }
-
- @override
- void setTypeMask(ir.Node node, TypeMask mask) {
- _sendMap ??= <ir.Node, TypeMask>{};
+ void setTypeMask(ir.Node node, AbstractValue mask) {
+ _sendMap ??= <ir.Node, AbstractValue>{};
_sendMap[node] = mask;
}
@override
- TypeMask typeOfOperator(ir.Node node) {
- throw new UnsupportedError(
- 'KernelGlobalTypeInferenceElementData.typeOfOperator');
- }
-
- @override
- TypeMask typeOfGetter(ir.Node node) {
+ AbstractValue typeOfGetter(ir.Node node) {
if (_sendMap == null) return null;
return _sendMap[node];
}
diff --git a/pkg/compiler/lib/src/inferrer/locals_handler.dart b/pkg/compiler/lib/src/inferrer/locals_handler.dart
index 7b0736a..26b41c7 100644
--- a/pkg/compiler/lib/src/inferrer/locals_handler.dart
+++ b/pkg/compiler/lib/src/inferrer/locals_handler.dart
@@ -5,12 +5,10 @@
library locals_handler;
import 'dart:collection' show IterableMixin;
-
+import 'package:kernel/ast.dart' as ir;
import '../options.dart' show CompilerOptions;
-import '../elements/elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
-import '../tree/tree.dart';
import '../util/util.dart';
import 'inferrer_engine.dart';
import 'type_graph_nodes.dart';
@@ -32,15 +30,22 @@
/// The [Node] that created this scope.
final T block;
- VariableScope(this.block, [parent])
+ /// `true` if this scope is for a try block.
+ final bool isTry;
+
+ VariableScope(this.block, {VariableScope parent, this.isTry})
: this.variables = null,
- this.parent = parent;
+ this.parent = parent {
+ assert(isTry == (block is ir.TryCatch || block is ir.TryFinally),
+ "Unexpected block $block for isTry=$isTry");
+ }
VariableScope.deepCopyOf(VariableScope<T> other)
: variables = other.variables == null
? null
: new Map<Local, TypeInformation>.from(other.variables),
block = other.block,
+ isTry = other.isTry,
parent = other.parent == null
? null
: new VariableScope.deepCopyOf(other.parent);
@@ -50,6 +55,7 @@
? null
: new Map<Local, TypeInformation>.from(other.variables),
block = other.block,
+ isTry = other.isTry,
parent = other.parent;
TypeInformation operator [](Local variable) {
@@ -261,13 +267,14 @@
LocalsHandler(this.inferrer, this.types, this.options, T block,
[this.fieldScope])
- : locals = new VariableScope<T>(block),
+ : locals = new VariableScope<T>(block, isTry: false),
_capturedAndBoxed = new Map<Local, FieldEntity>(),
tryBlock = null;
LocalsHandler.from(LocalsHandler<T> other, T block,
- {bool useOtherTryBlock: true})
- : locals = new VariableScope<T>(block, other.locals),
+ {bool isTry: false, bool useOtherTryBlock: true})
+ : locals =
+ new VariableScope<T>(block, isTry: isTry, parent: other.locals),
fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
_capturedAndBoxed = other._capturedAndBoxed,
types = other.types,
@@ -295,7 +302,6 @@
options = other.options;
TypeInformation use(Local local) {
- assert(!(local is LocalElement && !local.isImplementation));
if (_capturedAndBoxed.containsKey(local)) {
FieldEntity field = _capturedAndBoxed[local];
return inferrer.typeOfMember(field);
@@ -320,7 +326,7 @@
local,
types.allocatePhi(
locals.block, local, types.narrowNotNull(currentType),
- isTry: locals.block is TryStatement),
+ isTry: locals.isTry),
type);
}
locals[local] = type;
@@ -329,7 +335,7 @@
if (_capturedAndBoxed.containsKey(local)) {
inferrer.recordTypeOfField(_capturedAndBoxed[local], type);
} else if (inTryBlock) {
- // We don'TypeInformation know if an assignment in a try block
+ // We don't know if an assignment in a try block
// will be executed, so all assignments in that block are
// potential types after we have left it. We update the parent
// of the try block so that, at exit of the try block, we get
@@ -338,7 +344,7 @@
if (existing != null) {
TypeInformation phiType = types.allocatePhi(
tryBlock.locals.block, local, existing,
- isTry: tryBlock.locals.block is TryStatement);
+ isTry: tryBlock.locals.isTry);
TypeInformation inputType = types.addPhiInput(local, phiType, type);
tryBlock.locals.parent[local] = inputType;
}
@@ -459,7 +465,8 @@
// Use a separate locals handler to perform the merge in, so that Phi
// creation does not invalidate previous type knowledge while we might
// still look it up.
- LocalsHandler<T> merged = new LocalsHandler<T>.from(this, level);
+ LocalsHandler<T> merged =
+ new LocalsHandler<T>.from(this, level, isTry: locals.isTry);
Set<Local> seenLocals = new Setlet<Local>();
bool allBranchesAbort = true;
// Merge all other handlers.
@@ -502,7 +509,7 @@
TypeInformation newType;
if (seen != null && !seen.contains(local)) {
newType = types.allocatePhi(locals.block, local, otherType,
- isTry: locals.block is TryStatement);
+ isTry: locals.isTry);
seen.add(local);
} else {
newType = types.addPhiInput(local, myType, otherType);
@@ -530,8 +537,8 @@
void startLoop(T loop) {
locals.forEachLocal((Local variable, TypeInformation type) {
- TypeInformation newType = types.allocateLoopPhi(loop, variable, type,
- isTry: loop is TryStatement);
+ TypeInformation newType =
+ types.allocateLoopPhi(loop, variable, type, isTry: false);
if (newType != type) {
locals[variable] = newType;
}
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index b1ed67d..032b254 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -6,7 +6,7 @@
import '../common/names.dart' show Identifiers;
import '../elements/entities.dart';
-import '../types/types.dart' show ContainerTypeMask, MapTypeMask;
+import '../types/masks.dart' show ContainerTypeMask, MapTypeMask;
import '../util/util.dart' show Setlet;
import 'debug.dart' as debug;
import 'inferrer_engine.dart';
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index 116eb19..d8242e9 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -4,9 +4,9 @@
library dart2js.inferrer.type_graph_dump;
import '../../compiler_new.dart';
-import '../elements/elements.dart';
import '../elements/entities.dart';
-import '../types/types.dart';
+import '../elements/entity_utils.dart' as utils;
+import '../types/masks.dart';
import 'inferrer_engine.dart';
import 'type_graph_nodes.dart';
import 'debug.dart';
@@ -116,9 +116,8 @@
parts.add(element.name);
}
} else {
- parts.add(Elements
- .operatorNameToIdentifier(element.name)
- .replaceAll(r'$', '-'));
+ parts.add(
+ utils.operatorNameToIdentifier(element.name).replaceAll(r'$', '-'));
}
String filename = parts.where((x) => x != null && x != '').join('.');
if (usedFilenames.add(filename)) return filename;
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index b59bf9f..d6482a3 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -6,15 +6,11 @@
import 'dart:collection' show Queue;
-import '../compiler.dart' show Compiler;
import '../elements/entities.dart';
-import '../tree/tree.dart' as ast show Node;
-import '../types/masks.dart'
- show CommonMasks, ContainerTypeMask, MapTypeMask, TypeMask;
+import '../types/abstract_value_domain.dart';
import '../types/types.dart';
import '../universe/selector.dart' show Selector;
import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
-import 'ast_inferrer_engine.dart';
import 'inferrer_engine.dart';
import 'type_graph_nodes.dart';
@@ -61,9 +57,10 @@
String get name => 'Graph inferrer';
- CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+ AbstractValueDomain get abstractValueDomain =>
+ closedWorld.abstractValueDomain;
- TypeMask get _dynamicType => commonMasks.dynamicType;
+ AbstractValue get _dynamicType => abstractValueDomain.dynamicType;
void analyzeMain(FunctionEntity main) {
inferrer = createInferrerEngineFor(main);
@@ -73,34 +70,34 @@
InferrerEngine<T> createInferrerEngineFor(FunctionEntity main);
- TypeMask getReturnTypeOfMember(MemberEntity element) {
+ AbstractValue getReturnTypeOfMember(MemberEntity element) {
if (_disableTypeInference) return _dynamicType;
// Currently, closure calls return dynamic.
if (element is! FunctionEntity) return _dynamicType;
return inferrer.types.getInferredTypeOfMember(element).type;
}
- TypeMask getReturnTypeOfParameter(Local element) {
+ AbstractValue getReturnTypeOfParameter(Local element) {
if (_disableTypeInference) return _dynamicType;
return _dynamicType;
}
- TypeMask getTypeOfMember(MemberEntity element) {
+ AbstractValue getTypeOfMember(MemberEntity element) {
if (_disableTypeInference) return _dynamicType;
// The inferrer stores the return type for a function, so we have to
// be careful to not return it here.
- if (element is FunctionEntity) return commonMasks.functionType;
+ if (element is FunctionEntity) return abstractValueDomain.functionType;
return inferrer.types.getInferredTypeOfMember(element).type;
}
- TypeMask getTypeOfParameter(Local element) {
+ AbstractValue getTypeOfParameter(Local element) {
if (_disableTypeInference) return _dynamicType;
// The inferrer stores the return type for a function, so we have to
// be careful to not return it here.
return inferrer.types.getInferredTypeOfParameter(element).type;
}
- TypeMask getTypeForNewList(T node) {
+ AbstractValue getTypeForNewList(T node) {
if (_disableTypeInference) return _dynamicType;
return inferrer.types.allocatedLists[node].type;
}
@@ -111,7 +108,7 @@
return info.checksGrowable;
}
- TypeMask getTypeOfSelector(Selector selector, TypeMask mask) {
+ AbstractValue getTypeOfSelector(Selector selector, AbstractValue receiver) {
if (_disableTypeInference) return _dynamicType;
// Bailout for closure calls. We're not tracking types of
// closures.
@@ -119,30 +116,26 @@
if (selector.isSetter || selector.isIndexSet) {
return _dynamicType;
}
- if (inferrer.returnsListElementType(selector, mask)) {
- ContainerTypeMask containerTypeMask = mask;
- TypeMask elementType = containerTypeMask.elementType;
- return elementType == null ? _dynamicType : elementType;
+ if (inferrer.returnsListElementType(selector, receiver)) {
+ return abstractValueDomain.getContainerElementType(receiver);
}
- if (inferrer.returnsMapValueType(selector, mask)) {
- MapTypeMask mapTypeMask = mask;
- TypeMask valueType = mapTypeMask.valueType;
- return valueType == null ? _dynamicType : valueType;
+ if (inferrer.returnsMapValueType(selector, receiver)) {
+ return abstractValueDomain.getMapValueType(receiver);
}
- TypeMask result = const TypeMask.nonNullEmpty();
- if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
- result = inferrer.commonMasks.dynamicType;
+ if (inferrer.closedWorld.includesClosureCall(selector, receiver)) {
+ return abstractValueDomain.dynamicType;
} else {
Iterable<MemberEntity> elements =
- inferrer.closedWorld.locateMembers(selector, mask);
+ inferrer.closedWorld.locateMembers(selector, receiver);
+ List<AbstractValue> types = <AbstractValue>[];
for (MemberEntity element in elements) {
- TypeMask type =
+ AbstractValue type =
inferrer.typeOfMemberWithSelector(element, selector).type;
- result = result.union(type, inferrer.closedWorld);
+ types.add(type);
}
+ return abstractValueDomain.unionOfMany(types);
}
- return result;
}
Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element) {
@@ -164,24 +157,3 @@
inferrer.clear();
}
}
-
-class AstTypeGraphInferrer extends TypeGraphInferrer<ast.Node> {
- final Compiler _compiler;
-
- AstTypeGraphInferrer(
- this._compiler, ClosedWorld closedWorld, closedWorldRefiner,
- {bool disableTypeInference: false})
- : super(closedWorld, closedWorldRefiner,
- disableTypeInference: disableTypeInference);
-
- @override
- InferrerEngine<ast.Node> createInferrerEngineFor(FunctionEntity main) {
- return new AstInferrerEngine(
- _compiler, closedWorld, closedWorldRefiner, main);
- }
-
- @override
- GlobalTypeInferenceResults createResults() {
- return new AstGlobalTypeInferenceResults(this, closedWorld);
- }
-}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index d17c19d..cb9971a 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -10,11 +10,8 @@
import '../common/names.dart' show Identifiers;
import '../constants/values.dart';
-import '../elements/elements.dart'
- show ConstructorElement, LocalElement, MemberElement;
import '../elements/entities.dart';
import '../elements/types.dart';
-import '../tree/tree.dart' as ast show ForIn, Node, Send, SendSet;
import '../types/masks.dart'
show
CommonMasks,
@@ -402,13 +399,7 @@
*/
Map<MemberEntity, Setlet<Object>> _callers;
- MemberTypeInformation._internal(this._member) : super._internal(null) {
- assert(_checkMember(_member));
- }
-
- bool _checkMember(MemberEntity member) {
- return !(member is MemberElement && !member.isDeclaration);
- }
+ MemberTypeInformation._internal(this._member) : super._internal(null);
MemberEntity get member => _member;
@@ -619,19 +610,19 @@
: super._internal(element);
TypeMask handleSpecialCases(InferrerEngine inferrer) {
- CommonMasks commonMasks = inferrer.commonMasks;
+ CommonMasks abstractValueDomain = inferrer.abstractValueDomain;
if (_constructor.isFromEnvironmentConstructor) {
if (_constructor.enclosingClass == inferrer.commonElements.intClass) {
giveUp(inferrer);
- return commonMasks.intType.nullable();
+ return abstractValueDomain.intType.nullable();
} else if (_constructor.enclosingClass ==
inferrer.commonElements.boolClass) {
giveUp(inferrer);
- return commonMasks.boolType.nullable();
+ return abstractValueDomain.boolType.nullable();
} else if (_constructor.enclosingClass ==
inferrer.commonElements.stringClass) {
giveUp(inferrer);
- return commonMasks.stringType.nullable();
+ return abstractValueDomain.stringType.nullable();
}
}
return _handleFunctionCase(_constructor, inferrer);
@@ -688,9 +679,7 @@
: _isInstanceMemberParameter = false,
_isClosureParameter = true,
_isInitializingFormal = false,
- super._internal(context) {
- assert(_checkParameter(_parameter));
- }
+ super._internal(context);
ParameterTypeInformation.static(
MemberTypeInformation context, this._parameter, this._type, this._method,
@@ -698,9 +687,7 @@
: _isInstanceMemberParameter = false,
_isClosureParameter = false,
_isInitializingFormal = isInitializingFormal,
- super._internal(context) {
- assert(_checkParameter(_parameter));
- }
+ super._internal(context);
ParameterTypeInformation.instanceMember(
MemberTypeInformation context,
@@ -711,13 +698,7 @@
: _isInstanceMemberParameter = true,
_isClosureParameter = false,
_isInitializingFormal = false,
- super._withAssignments(context, assignments) {
- assert(_checkParameter(_parameter));
- }
-
- bool _checkParameter(Local parameter) {
- return !(parameter is LocalElement && !parameter.isImplementation);
- }
+ super._withAssignments(context, assignments);
FunctionEntity get method => _method;
@@ -857,18 +838,15 @@
enum CallType {
access,
- complex,
forIn,
}
bool validCallType(CallType callType, Object call) {
switch (callType) {
- case CallType.complex:
- return call is ast.SendSet;
case CallType.access:
- return call is ast.Send || call is ir.Node;
+ return call is ir.Node;
case CallType.forIn:
- return call is ast.ForIn || call is ir.ForInStatement;
+ return call is ir.ForInStatement;
}
throw new StateError('Unexpected call type $callType.');
}
@@ -895,15 +873,7 @@
CallSiteTypeInformation(MemberTypeInformation context, this._call,
this.caller, this.selector, this.mask, this.arguments, this.inLoop)
: super.noAssignments(context) {
- assert(_checkCaller(caller));
- // [_call] is either an AST node or a constructor element in case of a
- // a forwarding constructor _call.
- assert(
- _call is ast.Node || _call is ConstructorElement || _call is ir.Node);
- }
-
- bool _checkCaller(MemberEntity caller) {
- return !(caller is MemberElement && !caller.isDeclaration);
+ assert(_call is ir.Node);
}
String toString() => 'Call site $debugName $type';
@@ -929,13 +899,7 @@
TypeMask mask,
ArgumentsTypes arguments,
bool inLoop)
- : super(context, call, enclosing, selector, mask, arguments, inLoop) {
- assert(_checkCalledElement(calledElement));
- }
-
- bool _checkCalledElement(MemberEntity calledElement) {
- return !(calledElement is MemberElement && !calledElement.isDeclaration);
- }
+ : super(context, call, enclosing, selector, mask, arguments, inLoop);
MemberTypeInformation _getCalledTypeInfo(InferrerEngine inferrer) {
return inferrer.types.getInferredTypeOfMember(calledElement);
@@ -1056,7 +1020,7 @@
TypeMask receiverType = receiver.type;
if (mask != receiverType) {
- return receiverType == inferrer.commonMasks.dynamicType
+ return receiverType == inferrer.abstractValueDomain.dynamicType
? null
: receiverType;
} else {
@@ -1234,7 +1198,7 @@
// for all these targets.
TypeMask result;
if (_hasClosureCallTargets) {
- result = inferrer.commonMasks.dynamicType;
+ result = inferrer.abstractValueDomain.dynamicType;
} else {
result = inferrer.types
.joinTypeMasks(_concreteTargets.map((MemberEntity element) {
diff --git a/pkg/compiler/lib/src/io/multi_information.dart b/pkg/compiler/lib/src/io/multi_information.dart
deleted file mode 100644
index 25c61fe..0000000
--- a/pkg/compiler/lib/src/io/multi_information.dart
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Source information strategy that concurrently builds sourcemaps for each of
-/// child strategies.
-
-library dart2js.dual_source_information;
-
-import '../common.dart';
-import '../elements/entities.dart';
-import '../js/js_source_mapping.dart';
-import '../js/js.dart' as js;
-import '../universe/call_structure.dart';
-import 'code_output.dart' show BufferedCodeOutput;
-import 'source_information.dart';
-
-class MultiSourceInformationStrategy<T>
- implements JavaScriptSourceInformationStrategy<T> {
- final List<JavaScriptSourceInformationStrategy<T>> strategies;
-
- const MultiSourceInformationStrategy(this.strategies);
-
- @override
- SourceInformationBuilder<T> createBuilderForContext(MemberEntity member) {
- return new MultiSourceInformationBuilder<T>(
- strategies.map((s) => s.createBuilderForContext(member)).toList());
- }
-
- @override
- void onComplete() {
- strategies.forEach((s) => s.onComplete());
- }
-
- @override
- SourceInformation buildSourceMappedMarker() {
- return new MultiSourceInformation(
- strategies.map((s) => s.buildSourceMappedMarker()).toList());
- }
-
- @override
- SourceInformationProcessor createProcessor(
- SourceMapperProvider sourceMapperProvider,
- SourceInformationReader reader) {
- return new MultiSourceInformationProcessor(
- new List<SourceInformationProcessor>.generate(strategies.length,
- (int index) {
- return strategies[index].createProcessor(sourceMapperProvider,
- new MultiSourceInformationReader(reader, index));
- }));
- }
-}
-
-class MultiSourceInformationProcessor implements SourceInformationProcessor {
- final List<SourceInformationProcessor> processors;
-
- MultiSourceInformationProcessor(this.processors);
-
- @override
- void onStartPosition(js.Node node, int startPosition) {
- processors.forEach((p) => p.onStartPosition(node, startPosition));
- }
-
- @override
- void onPositions(
- js.Node node, int startPosition, int endPosition, int closingPosition) {
- processors.forEach((p) =>
- p.onPositions(node, startPosition, endPosition, closingPosition));
- }
-
- @override
- void process(js.Node node, BufferedCodeOutput code) {
- processors.forEach((p) => p.process(node, code));
- }
-}
-
-class MultiSourceInformationBuilder<T> implements SourceInformationBuilder<T> {
- final List<SourceInformationBuilder<T>> builders;
-
- MultiSourceInformationBuilder(this.builders);
-
- @override
- SourceInformationBuilder forContext(MemberEntity member) {
- return new MultiSourceInformationBuilder(
- builders.map((b) => b.forContext(member)).toList());
- }
-
- @override
- SourceInformation buildSwitchCase(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildSwitchCase(node)).toList());
- }
-
- @override
- SourceInformation buildSwitch(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildSwitch(node)).toList());
- }
-
- @override
- SourceInformation buildAs(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildAs(node)).toList());
- }
-
- @override
- SourceInformation buildIs(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildIs(node)).toList());
- }
-
- @override
- SourceInformation buildTry(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildTry(node)).toList());
- }
-
- @override
- SourceInformation buildCatch(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildCatch(node)).toList());
- }
-
- @override
- SourceInformation buildBinary(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildBinary(node)).toList());
- }
-
- @override
- SourceInformation buildUnary(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildUnary(node)).toList());
- }
-
- @override
- SourceInformation buildIndexSet(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildIndexSet(node)).toList());
- }
-
- @override
- SourceInformation buildIndex(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildIndex(node)).toList());
- }
-
- @override
- SourceInformation buildForInSet(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildForInSet(node)).toList());
- }
-
- @override
- SourceInformation buildForInCurrent(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildForInCurrent(node)).toList());
- }
-
- @override
- SourceInformation buildForInMoveNext(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildForInMoveNext(node)).toList());
- }
-
- @override
- SourceInformation buildForInIterator(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildForInIterator(node)).toList());
- }
-
- @override
- SourceInformation buildStringInterpolation(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildStringInterpolation(node)).toList());
- }
-
- @override
- SourceInformation buildForeignCode(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildForeignCode(node)).toList());
- }
-
- @override
- SourceInformation buildVariableDeclaration() {
- return new MultiSourceInformation(
- builders.map((b) => b.buildVariableDeclaration()).toList());
- }
-
- @override
- SourceInformation buildAwait(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildAwait(node)).toList());
- }
-
- @override
- SourceInformation buildYield(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildYield(node)).toList());
- }
-
- @override
- SourceInformation buildAsyncBody() {
- return new MultiSourceInformation(
- builders.map((b) => b.buildAsyncBody()).toList());
- }
-
- @override
- SourceInformation buildAsyncExit() {
- return new MultiSourceInformation(
- builders.map((b) => b.buildAsyncExit()).toList());
- }
-
- @override
- SourceInformation buildAssignment(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildAssignment(node)).toList());
- }
-
- @override
- SourceInformation buildThrow(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildThrow(node)).toList());
- }
-
- @override
- SourceInformation buildNew(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildNew(node)).toList());
- }
-
- @override
- SourceInformation buildIf(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildIf(node)).toList());
- }
-
- @override
- SourceInformation buildCall(T receiver, T call) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildCall(receiver, call)).toList());
- }
-
- @override
- SourceInformation buildGet(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildGet(node)).toList());
- }
-
- @override
- SourceInformation buildLoop(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildLoop(node)).toList());
- }
-
- @override
- SourceInformation buildImplicitReturn(MemberEntity element) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildImplicitReturn(element)).toList());
- }
-
- @override
- SourceInformation buildReturn(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildReturn(node)).toList());
- }
-
- @override
- SourceInformation buildCreate(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildCreate(node)).toList());
- }
-
- @override
- SourceInformation buildListLiteral(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildListLiteral(node)).toList());
- }
-
- @override
- SourceInformation buildGeneric(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildGeneric(node)).toList());
- }
-
- @override
- SourceInformation buildDeclaration(MemberEntity member) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildDeclaration(member)).toList());
- }
-
- @override
- SourceInformation buildStub(
- FunctionEntity function, CallStructure callStructure) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildStub(function, callStructure)).toList());
- }
-
- @override
- SourceInformation buildGoto(T node) {
- return new MultiSourceInformation(
- builders.map((b) => b.buildGoto(node)).toList());
- }
-}
-
-class MultiSourceInformation implements SourceInformation {
- final List<SourceInformation> infos;
-
- MultiSourceInformation(this.infos);
-
- @override
- String get shortText => infos.first?.shortText;
-
- @override
- List<SourceLocation> get sourceLocations => infos.first?.sourceLocations;
-
- @override
- SourceLocation get endPosition => infos.first?.endPosition;
-
- @override
- SourceLocation get innerPosition => infos.first?.innerPosition;
-
- @override
- SourceLocation get startPosition => infos.first?.startPosition;
-
- @override
- SourceSpan get sourceSpan => infos.first?.sourceSpan;
-
- String toString() => '$infos';
-}
-
-class MultiSourceInformationReader implements SourceInformationReader {
- final SourceInformationReader reader;
- final int index;
-
- MultiSourceInformationReader(this.reader, this.index);
-
- @override
- SourceInformation getSourceInformation(js.Node node) {
- MultiSourceInformation sourceInformation =
- reader.getSourceInformation(node);
- if (sourceInformation == null) return null;
- return sourceInformation.infos[index];
- }
-}
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 5704c6e..939c1c3 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -8,15 +8,10 @@
library dart2js.source_information.position;
import '../common.dart';
-import '../elements/elements.dart'
- show MemberElement, MethodElement, ResolvedAst, ResolvedAstKind;
import '../js/js.dart' as js;
import '../js/js_debug.dart';
import '../js/js_source_mapping.dart';
-import '../tree/tree.dart' show Node, Send;
-import '../universe/call_structure.dart';
import 'code_output.dart' show BufferedCodeOutput;
-import 'source_file.dart';
import 'source_information.dart';
/// [SourceInformation] that consists of an offset position into the source
@@ -116,16 +111,6 @@
}
}
-class PositionSourceInformationStrategy
- extends AbstractPositionSourceInformationStrategy<Node> {
- const PositionSourceInformationStrategy();
-
- @override
- SourceInformationBuilder<Node> createBuilderForContext(MemberElement member) {
- return new PositionSourceInformationBuilder(member);
- }
-}
-
/// Marker used to tag the root nodes of source-mapped code.
///
/// This is needed to be able to distinguish JavaScript nodes that shouldn't
@@ -144,243 +129,6 @@
SourceSpan get sourceSpan => new SourceSpan(null, null, null);
}
-/// [SourceInformationBuilder] that generates [PositionSourceInformation] from
-/// AST nodes.
-class PositionSourceInformationBuilder
- implements SourceInformationBuilder<Node> {
- final SourceFile sourceFile;
- final String name;
- final ResolvedAst resolvedAst;
-
- PositionSourceInformationBuilder(MemberElement member)
- : this.resolvedAst = member.resolvedAst,
- sourceFile = computeSourceFile(member.resolvedAst),
- name = computeElementNameForSourceMaps(member.resolvedAst.element);
-
- SourceInformation buildDeclaration(MemberElement member) {
- ResolvedAst resolvedAst = member.resolvedAst;
- String name = computeElementNameForSourceMaps(resolvedAst.element);
- SourceFile sourceFile = computeSourceFile(resolvedAst);
- if (resolvedAst.kind != ResolvedAstKind.PARSED) {
- SourceSpan span = resolvedAst.element.sourcePosition;
- return new PositionSourceInformation(
- new OffsetSourceLocation(sourceFile, span.begin, name));
- } else {
- return new PositionSourceInformation(
- new OffsetSourceLocation(
- sourceFile, resolvedAst.node.getBeginToken().charOffset, name),
- new OffsetSourceLocation(
- sourceFile, resolvedAst.node.getEndToken().charOffset, name));
- }
- }
-
- @override
- SourceInformation buildStub(
- MethodElement function, CallStructure callStructure) {
- ResolvedAst resolvedAst = function.resolvedAst;
- String name =
- computeElementNameForSourceMaps(resolvedAst.element, callStructure);
- SourceFile sourceFile = computeSourceFile(resolvedAst);
- SourceSpan span = resolvedAst.element.sourcePosition;
- assert(
- span != null, failedAt(function, "No source position for $function."));
- return new PositionSourceInformation(
- new OffsetSourceLocation(sourceFile, span.begin, name));
- }
-
- /// Builds a source information object pointing the start position of [node].
- SourceInformation buildBegin(Node node) {
- return new PositionSourceInformation(new OffsetSourceLocation(
- sourceFile, node.getBeginToken().charOffset, name));
- }
-
- /// Builds a source information object pointing the end position of [node].
- SourceInformation buildEnd(Node node) {
- return new PositionSourceInformation(new OffsetSourceLocation(
- sourceFile, node.getEndToken().charOffset, name));
- }
-
- @override
- SourceInformation buildGeneric(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildCreate(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildListLiteral(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildReturn(Node node) {
- SourceFile sourceFile = computeSourceFile(resolvedAst);
- SourceLocation startPosition = new OffsetSourceLocation(
- sourceFile, node.getBeginToken().charOffset, name);
- SourceLocation endPosition;
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- endPosition = new OffsetSourceLocation(
- sourceFile, resolvedAst.node.getEndToken().charOffset, name);
- }
- return new PositionSourceInformation(startPosition, endPosition);
- }
-
- @override
- SourceInformation buildImplicitReturn(MemberElement element) {
- if (element.isSynthesized) {
- return new PositionSourceInformation(new OffsetSourceLocation(
- sourceFile, element.position.charOffset, name));
- } else {
- return new PositionSourceInformation(new OffsetSourceLocation(
- sourceFile, element.resolvedAst.node.getEndToken().charOffset, name));
- }
- }
-
- @override
- SourceInformation buildLoop(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildGet(Node node) {
- Node left = node;
- Node right = node;
- Send send = node.asSend();
- if (send != null) {
- right = send.selector;
- }
- // For a read access like `a.b` the first source locations points to the
- // left-most part of the access, `a` in the example, and the second source
- // location points to the 'name' of accessed property, `b` in the
- // example. The latter is needed when both `a` and `b` are compiled into
- // JavaScript invocations.
- return new PositionSourceInformation(
- new OffsetSourceLocation(
- sourceFile, left.getBeginToken().charOffset, name),
- new OffsetSourceLocation(
- sourceFile, right.getBeginToken().charOffset, name));
- }
-
- // TODO(johnniwinther): Clean up the use of this and [buildBinary],
- // [buildIndex], etc.
- @override
- SourceInformation buildCall(Node receiver, Node call) {
- return new PositionSourceInformation(
- new OffsetSourceLocation(
- sourceFile, receiver.getBeginToken().charOffset, name),
- new OffsetSourceLocation(
- sourceFile, call.getBeginToken().charOffset, name));
- }
-
- @override
- SourceInformation buildNew(Node node) {
- return buildBegin(node);
- }
-
- @override
- SourceInformation buildIf(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildThrow(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildAssignment(Node node) => buildBegin(node);
-
- SourceInformation _buildMemberBody() {
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- Node body = resolvedAst.body;
- if (body != null) {
- return buildBegin(body);
- }
- // TODO(johnniwinther): Are there other cases?
- }
- return null;
- }
-
- SourceInformation _buildMemberExit() {
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- Node body = resolvedAst.body;
- if (body != null) {
- return buildEnd(body);
- }
- // TODO(johnniwinther): Are there other cases?
- }
- return null;
- }
-
- @override
- SourceInformation buildVariableDeclaration() {
- return _buildMemberBody();
- }
-
- @override
- SourceInformation buildAwait(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildYield(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildAsyncBody() {
- return _buildMemberBody();
- }
-
- @override
- SourceInformation buildAsyncExit() {
- return _buildMemberExit();
- }
-
- @override
- SourceInformationBuilder forContext(MemberElement member) {
- return new PositionSourceInformationBuilder(member);
- }
-
- @override
- SourceInformation buildForeignCode(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildStringInterpolation(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildForInIterator(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildForInMoveNext(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildForInCurrent(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildForInSet(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildIndex(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildIndexSet(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildBinary(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildUnary(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildTry(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildCatch(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildIs(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildAs(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildSwitch(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildSwitchCase(Node node) => buildBegin(node);
-
- @override
- SourceInformation buildGoto(Node node) => buildBegin(node);
-}
-
/// The start, end and closing offsets for a [js.Node].
class CodePosition {
final int startPosition;
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index 0297bc2..5cbb473 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -6,16 +6,8 @@
import 'package:kernel/ast.dart' show Location;
import '../common.dart';
-import '../elements/elements.dart'
- show
- AstElement,
- CompilationUnitElement,
- LocalElement,
- ResolvedAst,
- ResolvedAstKind;
import '../elements/entities.dart';
import '../js/js.dart' show JavaScriptNodeSourceInformation;
-import '../script.dart';
import '../universe/call_structure.dart';
import 'source_file.dart';
@@ -283,9 +275,7 @@
// when the old frontend is removed.
String computeElementNameForSourceMaps(Entity element,
[CallStructure callStructure]) {
- if (element is AstElement) {
- return _computeAstElementNameForSourceMaps(element, callStructure);
- } else if (element is ClassEntity) {
+ if (element is ClassEntity) {
return element.name;
} else if (element is MemberEntity) {
String suffix = computeStubSuffix(callStructure);
@@ -309,41 +299,6 @@
return element.name;
}
-String _computeAstElementNameForSourceMaps(
- AstElement element, CallStructure callStructure) {
- if (element.isClosure) {
- return computeElementNameForSourceMaps(
- element.enclosingElement, callStructure);
- } else if (element.isClass) {
- return element.name;
- } else if (element.isConstructor || element.isGenerativeConstructorBody) {
- String className = element.enclosingClass.name;
- if (element.name == '') {
- return className;
- }
- return '$className.${element.name}';
- } else if (element.isLocal) {
- LocalElement local = element;
- String name = local.name;
- if (name == '') {
- name = '<anonymous function>';
- }
- String enclosingName =
- computeElementNameForSourceMaps(local.executableContext, callStructure);
- return '$enclosingName.$name';
- } else if (element.enclosingClass != null) {
- String suffix = computeStubSuffix(callStructure);
- if (element.enclosingClass.isClosure) {
- return computeElementNameForSourceMaps(
- element.enclosingClass, callStructure);
- }
- return '${element.enclosingClass.name}.${element.name}$suffix';
- } else {
- String suffix = computeStubSuffix(callStructure);
- return '${element.name}$suffix';
- }
-}
-
/// Compute the suffix used for a parameter stub for [callStructure].
String computeStubSuffix(CallStructure callStructure) {
if (callStructure == null) return '';
@@ -358,35 +313,6 @@
return sb.toString();
}
-/// Computes the [SourceFile] for the source code of [resolvedAst].
-SourceFile computeSourceFile(ResolvedAst resolvedAst) {
- SourceFile sourceFile;
- if (resolvedAst.kind != ResolvedAstKind.PARSED) {
- // Synthesized node. Use the enclosing element for the location.
- sourceFile = resolvedAst.element.compilationUnit.script.file;
- } else {
- Uri uri = resolvedAst.sourceUri;
- AstElement implementation = resolvedAst.element.implementation;
- Script script = implementation.compilationUnit.script;
- if (uri == script.resourceUri) {
- sourceFile = script.file;
- } else {
- // Slow path, happens only for deserialized elements.
- // TODO(johnniwinther): Support a way to get a [SourceFile] from a
- // [Uri].
- for (CompilationUnitElement compilationUnit
- in implementation.library.compilationUnits) {
- Script script = compilationUnit.script;
- if (uri == script.resourceUri) {
- sourceFile = script.file;
- break;
- }
- }
- }
- }
- return sourceFile;
-}
-
class NoSourceLocationMarker extends SourceLocation {
const NoSourceLocationMarker();
diff --git a/pkg/compiler/lib/src/io/start_end_information.dart b/pkg/compiler/lib/src/io/start_end_information.dart
deleted file mode 100644
index 099917d..0000000
--- a/pkg/compiler/lib/src/io/start_end_information.dart
+++ /dev/null
@@ -1,281 +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.
-
-/// Source information system that maps spans of Dart AST nodes to spans of
-/// JavaScript nodes.
-
-library dart2js.source_information.start_end;
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import '../common.dart';
-import '../diagnostics/messages.dart' show MessageTemplate;
-import '../elements/elements.dart'
- show MemberElement, MethodElement, ResolvedAst, ResolvedAstKind;
-import '../js/js.dart' as js;
-import '../js/js_source_mapping.dart';
-import '../tree/tree.dart' show Node, Send;
-import '../universe/call_structure.dart';
-import 'source_file.dart';
-import 'source_information.dart';
-
-/// Source information that contains start source position and optionally an
-/// end source position.
-class StartEndSourceInformation extends SourceInformation {
- @override
- final SourceLocation startPosition;
-
- @override
- final SourceLocation endPosition;
-
- StartEndSourceInformation(this.startPosition, [this.endPosition]);
-
- @override
- List<SourceLocation> get sourceLocations {
- if (endPosition == null) {
- return <SourceLocation>[startPosition];
- } else {
- return <SourceLocation>[startPosition, endPosition];
- }
- }
-
- @override
- SourceSpan get sourceSpan {
- Uri uri = startPosition.sourceUri;
- int begin = startPosition.offset;
- int end = endPosition == null ? begin : endPosition.offset;
- return new SourceSpan(uri, begin, end);
- }
-
- int get hashCode {
- return 0x7FFFFFFF &
- (startPosition.hashCode * 17 + endPosition.hashCode * 19);
- }
-
- bool operator ==(other) {
- if (identical(this, other)) return true;
- if (other is! StartEndSourceInformation) return false;
- return startPosition == other.startPosition &&
- endPosition == other.endPosition;
- }
-
- // TODO(johnniwinther): Inline this in
- // [StartEndSourceInformationBuilder.buildDeclaration].
- static StartEndSourceInformation _computeSourceInformation(
- ResolvedAst resolvedAst,
- [CallStructure callStructure]) {
- String name =
- computeElementNameForSourceMaps(resolvedAst.element, callStructure);
- SourceFile sourceFile = computeSourceFile(resolvedAst);
- int begin;
- int end;
- if (resolvedAst.kind != ResolvedAstKind.PARSED) {
- // Synthesized node. Use the enclosing element for the location.
- begin = end = resolvedAst.element.sourcePosition.begin;
- } else {
- Node node = resolvedAst.node;
- begin = node.getBeginToken().charOffset;
- end = node.getEndToken().charOffset;
- }
- // TODO(johnniwinther): find the right sourceFile here and remove offset
- // checks below.
- SourceLocation sourcePosition, endSourcePosition;
- if (begin < sourceFile.length) {
- sourcePosition = new OffsetSourceLocation(sourceFile, begin, name);
- }
- if (end < sourceFile.length) {
- endSourcePosition = new OffsetSourceLocation(sourceFile, end, name);
- }
- return new StartEndSourceInformation(sourcePosition, endSourcePosition);
- }
-
- /// Create a textual representation of the source information using [uriText]
- /// as the Uri representation.
- String _computeText(String uriText) {
- StringBuffer sb = new StringBuffer();
- sb.write('$uriText:');
- sb.write('[${startPosition.line},${startPosition.column}]');
- if (endPosition != null) {
- sb.write('-[${endPosition.line},${endPosition.column}]');
- }
- return sb.toString();
- }
-
- String get shortText {
- return _computeText(startPosition.sourceUri.pathSegments.last);
- }
-
- String toString() {
- return _computeText('${startPosition.sourceUri}');
- }
-}
-
-class StartEndSourceInformationStrategy
- extends JavaScriptSourceInformationStrategy<Node> {
- const StartEndSourceInformationStrategy();
-
- @override
- SourceInformationBuilder<Node> createBuilderForContext(MemberElement member,
- [CallStructure callStructure]) {
- return new StartEndSourceInformationBuilder(member, callStructure);
- }
-
- @override
- SourceInformationProcessor createProcessor(
- SourceMapperProvider provider, SourceInformationReader reader) {
- return new StartEndSourceInformationProcessor(provider, reader);
- }
-}
-
-class StartEndSourceInformationProcessor extends SourceInformationProcessor {
- /// The id for this source information engine.
- ///
- /// The id is added to the source map file in an extra "engine" property and
- /// serves as a version number for the engine.
- ///
- /// The version history of this engine is:
- ///
- /// v1: The initial version with an id.
- static const String id = 'v1';
-
- final SourceMapper sourceMapper;
- final SourceInformationReader reader;
-
- /// Used to track whether a terminating source location marker has been
- /// registered for the top-most node with source information.
- bool hasRegisteredRoot = false;
-
- /// The root of the tree. Used to add a [NoSourceLocationMarker] to the start
- /// of the output.
- js.Node root;
-
- /// The root of the current subtree with source information. Used to add
- /// [NoSourceLocationMarker] after areas with source information.
- js.Node subRoot;
-
- StartEndSourceInformationProcessor(SourceMapperProvider provider, this.reader)
- : this.sourceMapper = provider.createSourceMapper(id);
-
- void onStartPosition(js.Node node, int startPosition) {
- if (root == null) {
- root = node;
- sourceMapper.register(
- node, startPosition, const NoSourceLocationMarker());
- }
- if (subRoot == null && reader.getSourceInformation(node) != null) {
- subRoot = node;
- }
- }
-
- @override
- void onPositions(
- js.Node node, int startPosition, int endPosition, int closingPosition) {
- StartEndSourceInformation sourceInformation =
- reader.getSourceInformation(node);
- if (sourceInformation != null) {
- sourceMapper.register(
- node, startPosition, sourceInformation.startPosition);
- if (sourceInformation.endPosition != null) {
- sourceMapper.register(node, endPosition, sourceInformation.endPosition);
- }
- if (!hasRegisteredRoot) {
- sourceMapper.register(node, endPosition, null);
- hasRegisteredRoot = true;
- }
- if (node == subRoot) {
- sourceMapper.register(
- node, endPosition, const NoSourceLocationMarker());
- subRoot = null;
- }
- }
- }
-}
-
-/// [SourceInformationBuilder] that generates [PositionSourceInformation].
-class StartEndSourceInformationBuilder extends SourceInformationBuilder<Node> {
- final SourceFile sourceFile;
- final String name;
-
- StartEndSourceInformationBuilder(MemberElement member,
- [CallStructure callStructure])
- : sourceFile = computeSourceFile(member.resolvedAst),
- name = computeElementNameForSourceMaps(
- member.resolvedAst.element, callStructure);
-
- SourceInformation buildDeclaration(MemberElement member) {
- return StartEndSourceInformation
- ._computeSourceInformation(member.resolvedAst);
- }
-
- SourceInformation buildStub(
- MethodElement member, CallStructure callStructure) {
- return StartEndSourceInformation._computeSourceInformation(
- member.resolvedAst, callStructure);
- }
-
- SourceLocation sourceFileLocationForToken(Token token) {
- SourceLocation location =
- new OffsetSourceLocation(sourceFile, token.charOffset, name);
- checkValidSourceFileLocation(location, sourceFile, token.charOffset);
- return location;
- }
-
- void checkValidSourceFileLocation(
- SourceLocation location, SourceFile sourceFile, int offset) {
- if (!location.isValid) {
- throw MessageTemplate.TEMPLATES[MessageKind.INVALID_SOURCE_FILE_LOCATION]
- .message({
- 'offset': offset,
- 'fileName': sourceFile.filename,
- 'length': sourceFile.length
- });
- }
- }
-
- @override
- SourceInformation buildLoop(Node node) {
- return new StartEndSourceInformation(
- sourceFileLocationForToken(node.getBeginToken()),
- sourceFileLocationForToken(node.getEndToken()));
- }
-
- @override
- SourceInformation buildGeneric(Node node) {
- return new StartEndSourceInformation(
- sourceFileLocationForToken(node.getBeginToken()));
- }
-
- @override
- SourceInformation buildCreate(Node node) => buildGeneric(node);
-
- @override
- SourceInformation buildReturn(Node node) => buildGeneric(node);
-
- @override
- SourceInformation buildGet(Node node) => buildGeneric(node);
-
- @override
- SourceInformation buildAssignment(Node node) => buildGeneric(node);
-
- @override
- SourceInformation buildCall(Node receiver, Node call) {
- return buildGeneric(receiver);
- }
-
- @override
- SourceInformation buildAs(Node node) {
- // 'as' is a Send with Operator 'as' for the selector.
- if (node is Send) return buildGeneric(node.selector ?? node);
- return buildGeneric(node);
- }
-
- @override
- SourceInformation buildIf(Node node) => buildGeneric(node);
-
- @override
- SourceInformationBuilder forContext(MemberElement member,
- {SourceInformation sourceInformation}) {
- return new StartEndSourceInformationBuilder(member);
- }
-}
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 936cddf..7a33482 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -415,6 +415,9 @@
// Note that RegExes, js.ArrayInitializer and js.ObjectInitializer are not
// [js.Literal]s.
if (result is js.Literal) return result;
+ if (result is js.VariableUse) {
+ if (result.name == selfName) return result;
+ }
js.Expression tempVar = useTempVar(allocateTempVar());
addStatement(js.js.statement('# = #;', [tempVar, result]));
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 28f2622..7188cf6 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -5,23 +5,17 @@
library js_backend.backend;
import '../common.dart';
-import '../common/backend_api.dart'
- show ForeignResolver, NativeRegistry, ImpactTransformer;
+import '../common/backend_api.dart' show ImpactTransformer;
import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
import '../common/names.dart' show Uris;
-import '../common/resolution.dart' show Resolution, Target;
import '../common/tasks.dart' show CompilerTask;
import '../common_elements.dart' show CommonElements, ElementEnvironment;
import '../compiler.dart' show Compiler;
import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
import '../constants/values.dart';
import '../deferred_load.dart' show DeferredLoadTask, OutputUnitData;
import '../dump_info.dart' show DumpInfoTask;
-import '../elements/elements.dart';
import '../elements/entities.dart';
-import '../elements/names.dart';
-import '../elements/resolution_types.dart';
import '../elements/types.dart';
import '../enqueue.dart'
show
@@ -41,11 +35,9 @@
import '../js_emitter/sorter.dart' show Sorter;
import '../library_loader.dart' show LoadedLibraries;
import '../native/native.dart' as native;
-import '../native/resolver.dart';
import '../ssa/ssa.dart' show SsaFunctionCompiler;
import '../tracer.dart';
-import '../tree/tree.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/class_hierarchy_builder.dart'
show ClassHierarchyBuilder, ClassQueries;
@@ -67,15 +59,11 @@
import 'impact_transformer.dart';
import 'interceptor_data.dart';
import 'js_interop_analysis.dart' show JsInteropAnalysis;
-import 'mirrors_analysis.dart';
-import 'mirrors_data.dart';
import 'namer.dart';
import 'native_data.dart';
import 'no_such_method_registry.dart';
-import 'patch_resolver.dart';
import 'resolution_listener.dart';
import 'runtime_types.dart';
-import 'type_variable_handler.dart';
const VERBOSE_OPTIMIZER_HINTS = false;
@@ -114,11 +102,7 @@
///
/// For a [MethodElement] this means it must be the declaration element.
bool checkFunction(FunctionEntity method) {
- if (method is MethodElement) {
- return method.isDeclaration;
- } else {
- return '$method'.startsWith(jsElementPrefix);
- }
+ return '$method'.startsWith(jsElementPrefix);
}
/// Returns the current cache decision. This should only be used for testing.
@@ -360,7 +344,6 @@
List<CompilerTask> get tasks {
List<CompilerTask> result = functionCompiler.tasks;
result.add(emitter);
- result.add(patchResolverTask);
return result;
}
@@ -373,9 +356,6 @@
/// True if the html library has been loaded.
bool htmlLibraryIsLoaded = false;
- /// Codegen handler for reflective access to type variables.
- TypeVariableCodegenAnalysis _typeVariableCodegenAnalysis;
-
/// Resolution support for generating table of interceptors and
/// constructors for custom elements.
CustomElementsResolutionAnalysis _customElementsResolutionAnalysis;
@@ -390,12 +370,6 @@
/// Support for classifying `noSuchMethod` implementations.
NoSuchMethodRegistry noSuchMethodRegistry;
- /// Resolution support for computing reflectable elements.
- MirrorsResolutionAnalysis _mirrorsResolutionAnalysis;
-
- /// Codegen support for computing reflectable elements.
- MirrorsCodegenAnalysis _mirrorsCodegenAnalysis;
-
/// The compiler task responsible for the compilation of constants for both
/// the frontend and the backend.
final JavaScriptConstantTask constantCompilerTask;
@@ -405,17 +379,13 @@
CodegenImpactTransformer _codegenImpactTransformer;
- PatchResolverTask patchResolverTask;
-
/// The strategy used for collecting and emitting source information.
SourceInformationStrategy sourceInformationStrategy;
NativeDataBuilderImpl _nativeDataBuilder;
NativeDataBuilder get nativeDataBuilder => _nativeDataBuilder;
- final NativeDataResolver _nativeDataResolver;
OneShotInterceptorData _oneShotInterceptorData;
BackendUsageBuilder _backendUsageBuilder;
- MirrorsDataImpl _mirrorsData;
OutputUnitData _outputUnitData;
CheckedModeHelpers _checkedModeHelpers;
@@ -425,8 +395,6 @@
native.NativeResolutionEnqueuer _nativeResolutionEnqueuer;
native.NativeCodegenEnqueuer _nativeCodegenEnqueuer;
- Target _target;
-
Tracer tracer;
JavaScriptBackend(this.compiler,
@@ -436,22 +404,16 @@
bool useNewSourceInfo: false})
: this.sourceInformationStrategy =
compiler.backendStrategy.sourceInformationStrategy,
- constantCompilerTask = new JavaScriptConstantTask(compiler),
- _nativeDataResolver = new NativeDataResolverImpl(compiler) {
+ constantCompilerTask = new JavaScriptConstantTask(compiler) {
CommonElements commonElements = compiler.frontendStrategy.commonElements;
- _target = new JavaScriptBackendTarget(this);
- _mirrorsData = compiler.frontendStrategy.createMirrorsDataBuilder();
_backendUsageBuilder = new BackendUsageBuilderImpl(commonElements);
_checkedModeHelpers = new CheckedModeHelpers();
emitter =
new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter);
jsInteropAnalysis = new JsInteropAnalysis(this);
- _mirrorsResolutionAnalysis =
- compiler.frontendStrategy.createMirrorsResolutionAnalysis(this);
noSuchMethodRegistry = new NoSuchMethodRegistryImpl(
commonElements, compiler.frontendStrategy.createNoSuchMethodResolver());
- patchResolverTask = new PatchResolverTask(compiler);
functionCompiler = new SsaFunctionCompiler(
this, compiler.measurer, sourceInformationStrategy);
}
@@ -462,12 +424,8 @@
DiagnosticReporter get reporter => compiler.reporter;
- Resolution get resolution => compiler.resolution;
-
ImpactCacheDeleter get impactCacheDeleter => compiler.impactCacheDeleter;
- Target get target => _target;
-
/// Resolution support for generating table of interceptors and
/// constructors for custom elements.
CustomElementsResolutionAnalysis get customElementsResolutionAnalysis {
@@ -488,34 +446,8 @@
return _customElementsCodegenAnalysis;
}
- /// Codegen handler for reflective access to type variables.
- TypeVariableCodegenAnalysis get typeVariableCodegenAnalysis {
- assert(
- _typeVariableCodegenAnalysis != null,
- failedAt(NO_LOCATION_SPANNABLE,
- "TypeVariableHandler has not been created yet."));
- return _typeVariableCodegenAnalysis;
- }
-
- MirrorsData get mirrorsData => _mirrorsData;
-
- MirrorsDataBuilder get mirrorsDataBuilder => _mirrorsData;
-
OutputUnitData get outputUnitData => _outputUnitData;
- /// Resolution support for computing reflectable elements.
- MirrorsResolutionAnalysis get mirrorsResolutionAnalysis =>
- _mirrorsResolutionAnalysis;
-
- /// Codegen support for computing reflectable elements.
- MirrorsCodegenAnalysis get mirrorsCodegenAnalysis {
- assert(
- _mirrorsCodegenAnalysis != null,
- failedAt(NO_LOCATION_SPANNABLE,
- "MirrorsCodegenAnalysis has not been created yet."));
- return _mirrorsCodegenAnalysis;
- }
-
OneShotInterceptorData get oneShotInterceptorData {
assert(
_oneShotInterceptorData != null,
@@ -562,31 +494,6 @@
return constantCompilerTask.jsConstantCompiler;
}
- MethodElement resolveExternalFunction(MethodElement element) {
- if (isForeign(compiler.frontendStrategy.commonElements, element)) {
- return element;
- }
- if (_nativeDataResolver.isJsInteropMember(element)) {
- if (element.memberName == const PublicName('[]') ||
- element.memberName == const PublicName('[]=')) {
- reporter.reportErrorMessage(
- element, MessageKind.JS_INTEROP_INDEX_NOT_SUPPORTED);
- }
- return element;
- }
- return patchResolverTask.measure(() {
- return patchResolverTask.resolveExternalFunction(element);
- });
- }
-
- bool isForeign(CommonElements commonElements, Element element) =>
- element.library == commonElements.foreignLibrary;
-
- bool isBackendLibrary(CommonElements commonElements, LibraryElement library) {
- return library == commonElements.interceptorsLibrary ||
- library == commonElements.jsHelperLibrary;
- }
-
Namer determineNamer(
ClosedWorld closedWorld, CodegenWorldBuilder codegenWorldBuilder) {
return compiler.options.enableMinification
@@ -643,47 +550,12 @@
void onResolutionClosedWorld(
ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) {
processAnnotations(closedWorldRefiner);
- mirrorsDataBuilder.computeMembersNeededForReflection(
- compiler.enqueuer.resolution.worldBuilder, closedWorld);
- mirrorsResolutionAnalysis.onResolutionComplete();
}
void onDeferredLoadComplete(OutputUnitData data) {
_outputUnitData = compiler.backendStrategy.convertOutputUnitData(data);
}
- /// Called when resolving a call to a foreign function.
- native.NativeBehavior resolveForeignCall(Send node, Element element,
- CallStructure callStructure, ForeignResolver resolver) {
- if (element.name == JS) {
- return _nativeDataResolver.resolveJsCall(node, resolver);
- } else if (element.name == JS_EMBEDDED_GLOBAL) {
- return _nativeDataResolver.resolveJsEmbeddedGlobalCall(node, resolver);
- } else if (element.name == JS_BUILTIN) {
- return _nativeDataResolver.resolveJsBuiltinCall(node, resolver);
- } else if (element.name == JS_INTERCEPTOR_CONSTANT) {
- // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names
- // a class that will be instantiated outside the program by attaching a
- // native class dispatch record referencing the interceptor.
- if (!node.argumentsNode.isEmpty) {
- Node argument = node.argumentsNode.nodes.head;
- ConstantExpression constant = resolver.getConstant(argument);
- if (constant != null && constant.kind == ConstantExpressionKind.TYPE) {
- TypeConstantExpression typeConstant = constant;
- if (typeConstant.type is ResolutionInterfaceType) {
- resolver.registerInstantiatedType(typeConstant.type);
- // No native behavior for this call.
- return null;
- }
- }
- }
- reporter.reportErrorMessage(
- node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
- }
- // No native behavior for this call.
- return null;
- }
-
ResolutionEnqueuer createResolutionEnqueuer(
CompilerTask task, Compiler compiler) {
ElementEnvironment elementEnvironment =
@@ -694,17 +566,11 @@
compiler.frontendStrategy.createRuntimeTypesNeedBuilder();
BackendImpacts impacts =
new BackendImpacts(compiler.options, commonElements);
- TypeVariableResolutionAnalysis typeVariableResolutionAnalysis =
- new TypeVariableResolutionAnalysis(
- compiler.frontendStrategy.elementEnvironment,
- impacts,
- _backendUsageBuilder);
_nativeResolutionEnqueuer = new native.NativeResolutionEnqueuer(
compiler.options,
elementEnvironment,
commonElements,
compiler.frontendStrategy.dartTypes,
- _backendUsageBuilder,
compiler.frontendStrategy.createNativeClassFinder(nativeBasicData));
_nativeDataBuilder = new NativeDataBuilderImpl(nativeBasicData);
_customElementsResolutionAnalysis = new CustomElementsResolutionAnalysis(
@@ -724,7 +590,6 @@
nativeBasicData,
_nativeResolutionEnqueuer,
_backendUsageBuilder,
- mirrorsDataBuilder,
customElementsResolutionAnalysis,
rtiNeedBuilder,
classHierarchyBuilder);
@@ -746,11 +611,8 @@
nativeBasicData,
interceptorDataBuilder,
_backendUsageBuilder,
- mirrorsDataBuilder,
noSuchMethodRegistry,
customElementsResolutionAnalysis,
- mirrorsResolutionAnalysis,
- typeVariableResolutionAnalysis,
_nativeResolutionEnqueuer,
compiler.deferredLoadTask),
compiler.frontendStrategy.createResolutionWorldBuilder(
@@ -780,9 +642,6 @@
CommonElements commonElements = closedWorld.commonElements;
BackendImpacts impacts =
new BackendImpacts(compiler.options, commonElements);
- _typeVariableCodegenAnalysis = new TypeVariableCodegenAnalysis(
- closedWorld.elementEnvironment, this, commonElements, mirrorsData);
- _mirrorsCodegenAnalysis = mirrorsResolutionAnalysis.close();
_customElementsCodegenAnalysis = new CustomElementsCodegenAnalysis(
constantSystem,
commonElements,
@@ -810,8 +669,6 @@
closedWorld.backendUsage,
closedWorld.rtiNeed,
customElementsCodegenAnalysis,
- typeVariableCodegenAnalysis,
- mirrorsCodegenAnalysis,
nativeCodegenEnqueuer));
}
@@ -868,8 +725,6 @@
* Invariant: [element] must be a declaration element.
*/
String getGeneratedCode(MemberEntity element) {
- assert(!(element is MemberElement && !element.isDeclaration),
- failedAt(element));
return jsAst.prettyPrint(generatedCode[element],
enableMinification: compiler.options.enableMinification);
}
@@ -878,39 +733,6 @@
int assembleProgram(ClosedWorld closedWorld) {
int programSize = emitter.assembleProgram(namer, closedWorld);
closedWorld.noSuchMethodData.emitDiagnostic(reporter);
- int totalMethodCount = generatedCode.length;
- // TODO(redemption): Support `preMirrorsMethodCount` for entities.
- if (mirrorsCodegenAnalysis.preMirrorsMethodCount != null &&
- totalMethodCount != mirrorsCodegenAnalysis.preMirrorsMethodCount) {
- int mirrorCount =
- totalMethodCount - mirrorsCodegenAnalysis.preMirrorsMethodCount;
- double percentage = (mirrorCount / totalMethodCount) * 100;
- DiagnosticMessage hint = reporter.createMessage(
- closedWorld.elementEnvironment.mainLibrary,
- MessageKind.MIRROR_BLOAT, {
- 'count': mirrorCount,
- 'total': totalMethodCount,
- 'percentage': percentage.round()
- });
-
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- for (LibraryElement library in compiler.libraryLoader.libraries) {
- if (library.isInternalLibrary) continue;
- for (ImportElement import in library.imports) {
- LibraryElement importedLibrary = import.importedLibrary;
- if (importedLibrary != closedWorld.commonElements.mirrorsLibrary)
- continue;
- MessageKind kind =
- compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(library)
- ? MessageKind.MIRROR_IMPORT
- : MessageKind.MIRROR_IMPORT_NO_USAGE;
- reporter.withCurrentElement(library, () {
- infos.add(reporter.createMessage(import, kind));
- });
- }
- }
- reporter.reportHint(hint, infos);
- }
return programSize;
}
@@ -1013,22 +835,10 @@
tracer.close();
}
- // Does this element belong in the output
- bool shouldOutput(Element element) => true;
-
/// Returns `true` if the `native` pseudo keyword is supported for [library].
bool canLibraryUseNative(LibraryEntity library) =>
native.maybeEnableNative(library.canonicalUri);
- bool isTargetSpecificLibrary(LibraryElement library) {
- Uri canonicalUri = library.canonicalUri;
- if (canonicalUri == Uris.dart__js_helper ||
- canonicalUri == Uris.dart__interceptors) {
- return true;
- }
- return false;
- }
-
/// Process backend specific annotations.
// TODO(johnniwinther): Merge this with [AnnotationProcessor] and use
// [ElementEnvironment.getMemberMetadata] in [AnnotationProcessor].
@@ -1049,12 +859,6 @@
CommonElements commonElements,
MemberEntity element,
ClosedWorldRefiner closedWorldRefiner) {
- if (element is MemberElement && element.isMalformed) {
- // Elements that are marked as malformed during parsing or resolution
- // might be registered here. These should just be ignored.
- return;
- }
-
bool hasNoInline = false;
bool hasForceInline = false;
@@ -1309,9 +1113,6 @@
impact.apply(visitor);
} else {
impact.apply(visitor);
- if (impactSource is Element) {
- impactCacheDeleter.uncacheWorldImpact(impactSource);
- }
}
} else if (impactUse == DeferredLoadTask.IMPACT_USE) {
impact.apply(visitor);
@@ -1332,55 +1133,6 @@
}
}
-class JavaScriptBackendTarget extends Target {
- final JavaScriptBackend _backend;
-
- JavaScriptBackendTarget(this._backend);
-
- CommonElements get _commonElements =>
- _backend.compiler.frontendStrategy.commonElements;
-
- @override
- bool isTargetSpecificLibrary(LibraryElement element) {
- return _backend.isTargetSpecificLibrary(element);
- }
-
- @override
- void resolveNativeMember(MemberElement element, NativeRegistry registry) {
- return _backend._nativeDataResolver.resolveNativeMember(element, registry);
- }
-
- @override
- MethodElement resolveExternalFunction(MethodElement element) {
- return _backend.resolveExternalFunction(element);
- }
-
- @override
- dynamic resolveForeignCall(Send node, Element element,
- CallStructure callStructure, ForeignResolver resolver) {
- return _backend.resolveForeignCall(node, element, callStructure, resolver);
- }
-
- @override
- bool isDefaultNoSuchMethod(MethodElement element) {
- return _commonElements.isDefaultNoSuchMethodImplementation(element);
- }
-
- @override
- ClassElement defaultSuperclass(ClassElement element) {
- return _commonElements.getDefaultSuperclass(
- element, _backend.frontendStrategy.nativeBasicData);
- }
-
- @override
- bool isNativeClass(ClassEntity element) =>
- _backend.compiler.frontendStrategy.nativeBasicData.isNativeClass(element);
-
- @override
- bool isForeign(Element element) =>
- _backend.isForeign(_commonElements, element);
-}
-
class SuperMemberData {
/// A set of member that are called from subclasses via `super`.
final Set<MemberEntity> _aliasedSuperMembers = new Setlet<MemberEntity>();
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index ed8dced..8af1da3 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -4,7 +4,6 @@
import '../common.dart';
import '../common_elements.dart';
-import '../elements/elements.dart' show Element;
import '../elements/entities.dart';
import '../elements/types.dart';
import '../util/util.dart' show Setlet;
@@ -144,7 +143,8 @@
bool _isValidBackendUse(Entity element) {
if (_isValidEntity(element)) return true;
- if (element is Element) {
+ // TODO(redemption): Support these checks on kernel based elements:
+ /*if (element is Element) {
assert(element.isDeclaration,
failedAt(element, "Backend use $element must be the declaration."));
if (element.implementationLibrary.isPatch ||
@@ -154,15 +154,13 @@
element.sourcePosition.uri.path
.contains('_internal/js_runtime/lib/')) ||
element.library == _commonElements.jsHelperLibrary ||
- element.library == _commonElements.interceptorsLibrary ||
- element.library == _commonElements.isolateHelperLibrary) {
+ element.library == _commonElements.interceptorsLibrary) {
// TODO(johnniwinther): We should be more precise about these.
return true;
} else {
return false;
}
- }
- // TODO(redemption): Support remaining checks on [Entity]s.
+ }*/
return true;
}
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
index 4aec501..ed231cc 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -4,9 +4,7 @@
import '../common.dart';
import '../common_elements.dart';
-import '../elements/elements.dart' show ErroneousElement;
import '../elements/entities.dart';
-import '../elements/resolution_types.dart' show MalformedType;
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
@@ -36,20 +34,6 @@
}
}
-class MalformedCheckedModeHelper extends CheckedModeHelper {
- const MalformedCheckedModeHelper(String name) : super(name);
-
- CallStructure get callStructure => CallStructure.TWO_ARGS;
-
- void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
- HTypeConversion node, List<jsAst.Expression> arguments) {
- // TODO(redemption): Support malformed types in [types.dart].
- MalformedType type = node.typeExpression;
- ErroneousElement element = type.element;
- arguments.add(js.escapedString(element.message));
- }
-}
-
class PropertyCheckedModeHelper extends CheckedModeHelper {
const PropertyCheckedModeHelper(String name) : super(name);
@@ -127,7 +111,6 @@
/// All the checked mode helpers.
static const List<CheckedModeHelper> helpers = const <CheckedModeHelper>[
- const MalformedCheckedModeHelper('checkMalformedType'),
const CheckedModeHelper('stringTypeCast'),
const CheckedModeHelper('stringTypeCheck'),
const CheckedModeHelper('doubleTypeCast'),
@@ -215,11 +198,6 @@
DartType type, CommonElements commonElements,
{bool typeCast, bool nativeCheckOnly}) {
assert(!type.isTypedef);
- if (type.isMalformed) {
- // The same error is thrown for type test and type cast of a malformed
- // type so we only need one check method.
- return 'checkMalformedType';
- }
if (type.isTypeVariable) {
return typeCast
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 39c2fb4..461bd279 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -18,9 +18,7 @@
import 'backend_impact.dart';
import 'backend_usage.dart';
import 'custom_elements_analysis.dart';
-import 'mirrors_analysis.dart';
import 'runtime_types.dart';
-import 'type_variable_handler.dart';
class CodegenEnqueuerListener extends EnqueuerListener {
final ElementEnvironment _elementEnvironment;
@@ -31,8 +29,6 @@
final RuntimeTypesNeed _rtiNeed;
final CustomElementsCodegenAnalysis _customElementsAnalysis;
- final TypeVariableCodegenAnalysis _typeVariableCodegenAnalysis;
- final MirrorsCodegenAnalysis _mirrorsAnalysis;
final NativeCodegenEnqueuer _nativeEnqueuer;
@@ -45,8 +41,6 @@
this._backendUsage,
this._rtiNeed,
this._customElementsAnalysis,
- this._typeVariableCodegenAnalysis,
- this._mirrorsAnalysis,
this._nativeEnqueuer);
@override
@@ -110,7 +104,6 @@
// Return early if any elements are added to avoid counting the elements as
// due to mirrors.
enqueuer.applyImpact(_customElementsAnalysis.flush());
- enqueuer.applyImpact(_typeVariableCodegenAnalysis.flush());
if (_backendUsage.isNoSuchMethodUsed && !_isNoSuchMethodUsed) {
enqueuer.applyImpact(
@@ -120,7 +113,6 @@
if (!enqueuer.queueIsEmpty) return false;
- _mirrorsAnalysis.onQueueEmpty(enqueuer, recentClasses);
return true;
}
@@ -226,9 +218,6 @@
WorldImpact _processClass(ClassEntity cls) {
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
- if (_elementEnvironment.isGenericClass(cls)) {
- _typeVariableCodegenAnalysis.registerClassWithTypeVariables(cls);
- }
if (cls == _commonElements.closureClass) {
_impacts.closureClass.registerImpact(impactBuilder, _elementEnvironment);
}
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index b0ccafa..26f845e 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -5,13 +5,8 @@
import '../compile_time_constants.dart';
import '../compiler.dart' show Compiler;
import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../elements/elements.dart';
+import '../constant_system_dart.dart';
import '../elements/entities.dart';
-import '../elements/visitor.dart' show BaseElementVisitor;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart';
import 'constant_system_javascript.dart';
/// [ConstantCompilerTask] for compilation of constants for the JavaScript
@@ -22,89 +17,18 @@
/// [DartConstantCompiler] for the frontend interpretation of the constants and
/// to a [JavaScriptConstantCompiler] for the backend interpretation.
class JavaScriptConstantTask extends ConstantCompilerTask {
- DartConstantCompiler dartConstantCompiler;
+ ConstantSystem dartConstantSystem;
JavaScriptConstantCompiler jsConstantCompiler;
JavaScriptConstantTask(Compiler compiler)
- : this.dartConstantCompiler = new DartConstantCompiler(compiler),
- this.jsConstantCompiler = new JavaScriptConstantCompiler(compiler),
+ : this.dartConstantSystem = const DartConstantSystem(),
+ this.jsConstantCompiler = new JavaScriptConstantCompiler(),
super(compiler.measurer);
String get name => 'ConstantHandler';
@override
- ConstantSystem get constantSystem => dartConstantCompiler.constantSystem;
-
- @override
- bool hasConstantValue(ConstantExpression expression) {
- return dartConstantCompiler.hasConstantValue(expression);
- }
-
- @override
- ConstantValue getConstantValue(ConstantExpression expression) {
- return dartConstantCompiler.getConstantValue(expression);
- }
-
- @override
- ConstantValue getConstantValueForVariable(VariableElement element) {
- return dartConstantCompiler.getConstantValueForVariable(element);
- }
-
- @override
- ConstantExpression compileConstant(VariableElement element) {
- return measure(() {
- // TODO(het): Only report errors from one of the constant compilers
- ConstantExpression result = dartConstantCompiler.compileConstant(element);
- jsConstantCompiler.compileConstant(element);
- return result;
- });
- }
-
- @override
- void evaluate(ConstantExpression constant) {
- return measure(() {
- dartConstantCompiler.evaluate(constant);
- jsConstantCompiler.evaluate(constant);
- });
- }
-
- @override
- ConstantExpression compileVariable(VariableElement element) {
- return measure(() {
- return jsConstantCompiler.compileVariable(element);
- });
- }
-
- ConstantExpression compileNode(Node node, TreeElements elements,
- {bool enforceConst: true}) {
- return measure(() {
- ConstantExpression result = dartConstantCompiler
- .compileNode(node, elements, enforceConst: enforceConst);
- jsConstantCompiler.compileNode(node, elements,
- enforceConst: enforceConst);
- return result;
- });
- }
-
- ConstantExpression compileMetadata(
- MetadataAnnotation metadata, Node node, TreeElements elements) {
- return measure(() {
- ConstantExpression constant =
- dartConstantCompiler.compileMetadata(metadata, node, elements);
- jsConstantCompiler.compileMetadata(metadata, node, elements);
- return constant;
- });
- }
-
- // TODO(johnniwinther): Remove this when values are computed from the
- // expressions.
- @override
- void copyConstantValues(covariant JavaScriptConstantTask task) {
- jsConstantCompiler.constantValueMap
- .addAll(task.jsConstantCompiler.constantValueMap);
- dartConstantCompiler.constantValueMap
- .addAll(task.dartConstantCompiler.constantValueMap);
- }
+ ConstantSystem get constantSystem => dartConstantSystem;
}
/**
@@ -112,40 +36,14 @@
* constants, initializations of global and static fields, and default values of
* optional parameters for the JavaScript interpretation of constants.
*/
-class JavaScriptConstantCompiler extends ConstantCompilerBase
- implements BackendConstantEnvironment {
+class JavaScriptConstantCompiler implements BackendConstantEnvironment {
// TODO(johnniwinther): Move this to the backend constant handler.
/** Caches the statics where the initial value cannot be eagerly compiled. */
final Set<FieldEntity> lazyStatics = new Set<FieldEntity>();
- // Constants computed for constant expressions.
- final Map<Node, ConstantExpression> nodeConstantMap =
- new Map<Node, ConstantExpression>();
+ JavaScriptConstantCompiler();
- // Constants computed for metadata.
- // TODO(johnniwinther): Remove this when no longer used by
- // poi/forget_element_test.
- final Map<MetadataAnnotation, ConstantExpression> metadataConstantMap =
- new Map<MetadataAnnotation, ConstantExpression>();
-
- JavaScriptConstantCompiler(Compiler compiler)
- : super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM);
-
- ConstantExpression compileVariableWithDefinitions(
- VariableElement element, TreeElements definitions,
- {bool isConst: false, bool checkType: true}) {
- if (!isConst && lazyStatics.contains(element)) {
- return null;
- }
- ConstantExpression value = super.compileVariableWithDefinitions(
- element, definitions,
- isConst: isConst, checkType: checkType);
- if (!isConst && value == null) {
- FieldElement field = element;
- registerLazyStatic(field);
- }
- return value;
- }
+ ConstantSystem get constantSystem => JAVA_SCRIPT_CONSTANT_SYSTEM;
@override
void registerLazyStatic(FieldEntity element) {
@@ -155,82 +53,4 @@
List<FieldEntity> getLazilyInitializedFieldsForEmission() {
return new List<FieldEntity>.from(lazyStatics);
}
-
- ConstantExpression compileNode(Node node, TreeElements elements,
- {bool enforceConst: true}) {
- return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
- }
-
- ConstantExpression compileNodeWithDefinitions(
- Node node, TreeElements definitions,
- {bool isConst: true}) {
- ConstantExpression constant = nodeConstantMap[node];
- if (constant != null && getConstantValue(constant) != null) {
- return constant;
- }
- constant =
- super.compileNodeWithDefinitions(node, definitions, isConst: isConst);
- if (constant != null) {
- nodeConstantMap[node] = constant;
- }
- return constant;
- }
-
- ConstantValue getConstantValueForNode(Node node, TreeElements definitions) {
- return getConstantValue(getConstantForNode(node, definitions));
- }
-
- ConstantExpression getConstantForNode(Node node, TreeElements definitions) {
- ConstantExpression constant = nodeConstantMap[node];
- if (constant != null) {
- return constant;
- }
- return definitions.getConstant(node);
- }
-
- ConstantValue getConstantValueForMetadata(MetadataAnnotation metadata) {
- return getConstantValue(metadata.constant);
- }
-
- @override
- ConstantExpression compileMetadata(
- MetadataAnnotation metadata, Node node, TreeElements elements) {
- ConstantExpression constant =
- super.compileMetadata(metadata, node, elements);
- metadataConstantMap[metadata] = constant;
- return constant;
- }
-}
-
-class ForgetConstantElementVisitor
- extends BaseElementVisitor<dynamic, JavaScriptConstantCompiler> {
- const ForgetConstantElementVisitor();
-
- void visitElement(Element e, JavaScriptConstantCompiler constants) {
- for (MetadataAnnotation data in e.implementation.metadata) {
- constants.metadataConstantMap.remove(data);
- if (data.hasNode) {
- data.node.accept(new ForgetConstantNodeVisitor(constants));
- }
- }
- }
-
- void visitFunctionElement(
- FunctionElement e, JavaScriptConstantCompiler constants) {
- super.visitFunctionElement(e, constants);
- if (e.hasFunctionSignature) {
- e.functionSignature.forEachParameter((p) => visit(p, constants));
- }
- }
-}
-
-class ForgetConstantNodeVisitor extends Visitor {
- final JavaScriptConstantCompiler constants;
-
- ForgetConstantNodeVisitor(this.constants);
-
- void visitNode(Node node) {
- node.visitChildren(this);
- constants.nodeConstantMap.remove(node);
- }
}
diff --git a/pkg/compiler/lib/src/js_backend/element_strategy.dart b/pkg/compiler/lib/src/js_backend/element_strategy.dart
deleted file mode 100644
index c233ee8..0000000
--- a/pkg/compiler/lib/src/js_backend/element_strategy.dart
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.js_backend.element_strategy;
-
-import '../backend_strategy.dart';
-import '../closure.dart' show ClosureConversionTask, ClosureTask;
-import '../common.dart';
-import '../common/codegen.dart';
-import '../common/tasks.dart';
-import '../common/work.dart';
-import '../compiler.dart';
-import '../deferred_load.dart' show OutputUnitData;
-import '../elements/elements.dart';
-import '../enqueue.dart';
-import '../inferrer/type_graph_inferrer.dart' show AstTypeGraphInferrer;
-import '../io/multi_information.dart' show MultiSourceInformationStrategy;
-import '../io/position_information.dart' show PositionSourceInformationStrategy;
-import '../io/source_information.dart';
-import '../io/start_end_information.dart'
- show StartEndSourceInformationStrategy;
-import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy;
-import '../js_backend/backend.dart';
-import '../js_backend/native_data.dart';
-import '../js_emitter/sorter.dart';
-import '../resolution/resolution_strategy.dart';
-import '../ssa/builder.dart';
-import '../ssa/ssa.dart';
-import '../types/types.dart';
-import '../options.dart';
-import '../universe/world_builder.dart';
-import '../universe/world_impact.dart';
-import '../world.dart';
-
-/// Strategy for using the [Element] model from the resolver as the backend
-/// model.
-class ElementBackendStrategy extends ComputeSpannableMixin
- implements BackendStrategy {
- final Compiler _compiler;
- final ClosureConversionTask closureDataLookup;
- SourceInformationStrategy _sourceInformationStrategy;
-
- ElementBackendStrategy(this._compiler)
- : closureDataLookup = new ClosureTask(_compiler);
-
- ClosedWorldRefiner createClosedWorldRefiner(
- covariant ClosedWorldImpl closedWorld) =>
- closedWorld;
-
- Sorter get sorter => const ElementSorter();
-
- @override
- CodegenWorldBuilder createCodegenWorldBuilder(
- NativeBasicData nativeBasicData,
- ClosedWorld closedWorld,
- SelectorConstraintsStrategy selectorConstraintsStrategy) {
- return new ElementCodegenWorldBuilderImpl(
- _compiler.backend.constants,
- closedWorld.elementEnvironment,
- nativeBasicData,
- closedWorld,
- selectorConstraintsStrategy);
- }
-
- @override
- OutputUnitData convertOutputUnitData(OutputUnitData data) => data;
-
- @override
- WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) {
- return new ElementCodegenWorkItemBuilder(
- _compiler.backend, closedWorld, _compiler.options);
- }
-
- @override
- SsaBuilder createSsaBuilder(CompilerTask task, JavaScriptBackend backend,
- SourceInformationStrategy sourceInformationStrategy) {
- return new SsaAstBuilder(task, backend, sourceInformationStrategy);
- }
-
- SourceInformationStrategy get sourceInformationStrategy {
- return _sourceInformationStrategy ??= createSourceInformationStrategy(
- generateSourceMap: _compiler.options.generateSourceMap,
- useMultiSourceInfo: _compiler.options.useMultiSourceInfo,
- useNewSourceInfo: _compiler.options.useNewSourceInfo);
- }
-
- static SourceInformationStrategy createSourceInformationStrategy(
- {bool generateSourceMap: false,
- bool useMultiSourceInfo: false,
- bool useNewSourceInfo: false}) {
- if (!generateSourceMap) return const JavaScriptSourceInformationStrategy();
- if (useMultiSourceInfo) {
- if (useNewSourceInfo) {
- return const MultiSourceInformationStrategy(const [
- const PositionSourceInformationStrategy(),
- const StartEndSourceInformationStrategy()
- ]);
- } else {
- return const MultiSourceInformationStrategy(const [
- const StartEndSourceInformationStrategy(),
- const PositionSourceInformationStrategy()
- ]);
- }
- } else if (useNewSourceInfo) {
- return const PositionSourceInformationStrategy();
- } else {
- return const StartEndSourceInformationStrategy();
- }
- }
-
- @override
- TypesInferrer createTypesInferrer(ClosedWorldRefiner closedWorldRefiner,
- {bool disableTypeInference: false}) {
- return new AstTypeGraphInferrer(
- _compiler, closedWorldRefiner.closedWorld, closedWorldRefiner,
- disableTypeInference: disableTypeInference);
- }
-}
-
-/// Builder that creates the work item necessary for the code generation of a
-/// [MemberElement].
-class ElementCodegenWorkItemBuilder extends WorkItemBuilder {
- final JavaScriptBackend _backend;
- final ClosedWorld _closedWorld;
- final CompilerOptions _options;
-
- ElementCodegenWorkItemBuilder(
- this._backend, this._closedWorld, this._options);
-
- @override
- WorkItem createWorkItem(MemberElement element) {
- assert(element.isDeclaration, failedAt(element));
- // Don't generate code for foreign elements.
- if (_backend.isForeign(_closedWorld.commonElements, element)) return null;
- if (element.isAbstract) return null;
-
- // Codegen inlines field initializers. It only needs to generate
- // code for checked setters.
- if (element.isField && element.isInstanceMember) {
- if (!_options.enableTypeAssertions ||
- element.enclosingElement.isClosure) {
- return null;
- }
- }
- return new ElementCodegenWorkItem(_backend, _closedWorld, element);
- }
-}
-
-class ElementCodegenWorkItem extends CodegenWorkItem {
- CodegenRegistry registry;
- final ResolvedAst resolvedAst;
- final JavaScriptBackend _backend;
- final ClosedWorld _closedWorld;
-
- factory ElementCodegenWorkItem(JavaScriptBackend backend,
- ClosedWorld closedWorld, MemberElement element) {
- // If this assertion fails, the resolution callbacks of the backend may be
- // missing call of form registry.registerXXX. Alternatively, the code
- // generation could spuriously be adding dependencies on things we know we
- // don't need.
- assert(element.hasResolvedAst,
- failedAt(element, "$element has no resolved ast."));
- ResolvedAst resolvedAst = element.resolvedAst;
- return new ElementCodegenWorkItem.internal(
- resolvedAst, backend, closedWorld);
- }
-
- ElementCodegenWorkItem.internal(
- this.resolvedAst, this._backend, this._closedWorld);
-
- MemberElement get element => resolvedAst.element;
-
- WorldImpact run() {
- registry = new CodegenRegistry(_closedWorld.elementEnvironment, element);
- return _backend.codegen(this, _closedWorld);
- }
-
- String toString() => 'CodegenWorkItem(${resolvedAst.element})';
-}
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index e2d67ea..cbb30a5 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -19,9 +19,7 @@
}
_FieldNamingScope names;
- if (element is BoxFieldElement) {
- names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
- } else if (element is JRecordField) {
+ if (element is JRecordField) {
names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
} else {
ClassEntity cls = element.enclosingClass;
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index 4fb3ac1..70e8d1a 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -6,7 +6,6 @@
import '../universe/class_hierarchy_builder.dart' show ClassHierarchyBuilder;
-import '../closure.dart';
import '../common.dart';
import '../common_elements.dart';
import '../common/backend_api.dart' show ImpactTransformer;
@@ -29,7 +28,6 @@
import 'checked_mode_helpers.dart';
import 'custom_elements_analysis.dart';
import 'interceptor_data.dart';
-import 'mirrors_data.dart';
import 'namer.dart';
import 'native_data.dart';
import 'runtime_types.dart';
@@ -42,7 +40,6 @@
final NativeBasicData _nativeBasicData;
final NativeResolutionEnqueuer _nativeResolutionEnqueuer;
final BackendUsageBuilder _backendUsageBuilder;
- final MirrorsDataBuilder _mirrorsDataBuilder;
final CustomElementsResolutionAnalysis _customElementsResolutionAnalysis;
final RuntimeTypesNeedBuilder _rtiNeedBuilder;
final ClassHierarchyBuilder _classHierarchyBuilder;
@@ -55,7 +52,6 @@
this._nativeBasicData,
this._nativeResolutionEnqueuer,
this._backendUsageBuilder,
- this._mirrorsDataBuilder,
this._customElementsResolutionAnalysis,
this._rtiNeedBuilder,
this._classHierarchyBuilder);
@@ -243,9 +239,6 @@
if (worldImpact.constSymbolNames.isNotEmpty) {
registerImpact(_impacts.constSymbol);
- for (String constSymbolName in worldImpact.constSymbolNames) {
- _mirrorsDataBuilder.registerConstSymbol(constSymbolName);
- }
}
for (StaticUse staticUse in worldImpact.staticUses) {
@@ -432,11 +425,6 @@
if (_rtiNeed.methodNeedsSignature(callMethod)) {
_impacts.computeSignature
.registerImpact(transformed, _elementEnvironment);
- } else if (callMethod is SynthesizedCallMethodElementX) {
- if (_rtiNeed.localFunctionNeedsSignature(callMethod.expression)) {
- _impacts.computeSignature
- .registerImpact(transformed, _elementEnvironment);
- }
}
}
}
diff --git a/pkg/compiler/lib/src/js_backend/interceptor_data.dart b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
index 87fc04e..079aa91 100644
--- a/pkg/compiler/lib/src/js_backend/interceptor_data.dart
+++ b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
@@ -9,7 +9,7 @@
import '../elements/entities.dart';
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
-import '../types/types.dart' show TypeMask;
+import '../types/masks.dart' show TypeMask;
import '../universe/selector.dart';
import '../world.dart' show ClosedWorld;
import 'namer.dart';
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index aa31961..ab26bfb 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -11,4 +11,3 @@
export 'custom_elements_analysis.dart';
export 'namer.dart';
export 'no_such_method_registry.dart';
-export 'type_variable_handler.dart';
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 6fdc0ba..1869f4d 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -5,8 +5,7 @@
/// Analysis to determine how to generate code for typed JavaScript interop.
library compiler.src.js_backend.js_interop_analysis;
-import '../elements/resolution_types.dart'
- show ResolutionDartType, ResolutionDynamicType, ResolutionFunctionType;
+import '../elements/types.dart';
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
import '../universe/selector.dart' show Selector;
@@ -44,13 +43,17 @@
return new jsAst.Block(statements);
}
- ResolutionFunctionType buildJsFunctionType() {
+ FunctionType buildJsFunctionType() {
// TODO(jacobr): consider using codegenWorldBuilder.isChecks to determine the
// range of positional arguments that need to be supported by JavaScript
// function types.
- return new ResolutionFunctionType.synthesized(
- const ResolutionDynamicType(),
- [],
- new List<ResolutionDartType>.filled(16, const ResolutionDynamicType()));
+ return new FunctionType(
+ const DynamicType(),
+ const <DartType>[],
+ new List<DartType>.filled(16, const DynamicType()),
+ const <String>[],
+ const <DartType>[],
+ const <FunctionTypeVariable>[],
+ null);
}
}
diff --git a/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart b/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart
deleted file mode 100644
index 8682242..0000000
--- a/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.mirrors_handler;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../compiler.dart';
-import '../constants/values.dart';
-import '../diagnostics/diagnostic_listener.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../enqueue.dart';
-import '../universe/selector.dart';
-import '../universe/use.dart';
-import '../universe/world_impact.dart';
-import 'backend.dart';
-import 'constant_handler_javascript.dart';
-import 'mirrors_data.dart';
-
-abstract class MirrorsResolutionAnalysis {
- void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses);
-
- void onResolutionComplete();
-
- /// Close this analysis and create the [MirrorsCodegenAnalysis] for the
- /// collected data.
- MirrorsCodegenAnalysis close();
-}
-
-abstract class MirrorsCodegenAnalysis {
- void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses);
-
- /// Number of methods compiled before considering reflection.
- int get preMirrorsMethodCount;
-}
-
-class MirrorsResolutionAnalysisImpl implements MirrorsResolutionAnalysis {
- final JavaScriptBackend _backend;
- final MirrorsHandler handler;
-
- /// Set of elements for which metadata has been registered as dependencies.
- final Set<Element> _registeredMetadata = new Set<Element>();
-
- /// List of constants from metadata. If metadata must be preserved,
- /// these constants must be registered.
- final List<Dependency> _metadataConstants = <Dependency>[];
-
- StagedWorldImpactBuilder _impactBuilder = new StagedWorldImpactBuilder();
-
- MirrorsResolutionAnalysisImpl(this._backend, Resolution resolution)
- : handler = new MirrorsHandler(_backend, resolution);
-
- DiagnosticReporter get _reporter => _backend.reporter;
- Compiler get _compiler => _backend.compiler;
- JavaScriptConstantCompiler get _constants => _backend.constants;
- MirrorsData get _mirrorsData => _backend.mirrorsData;
-
- /// Returns all static fields that are referenced through
- /// `mirrorsData.targetsUsed`. If the target is a library or class all nested
- /// static fields are included too.
- Iterable<Element> _findStaticFieldTargets() {
- List<Element> staticFields = <Element>[];
-
- void addFieldsInContainer(ScopeContainerElement container) {
- container.forEachLocalMember((Element member) {
- if (!member.isInstanceMember && member.isField) {
- staticFields.add(member);
- } else if (member.isClass) {
- addFieldsInContainer(member);
- }
- });
- }
-
- for (MemberElement target in _mirrorsData.membersInMirrorsUsedTargets) {
- if (target.isField) {
- staticFields.add(target);
- }
- }
- for (ClassElement target in _mirrorsData.classesInMirrorsUsedTargets) {
- addFieldsInContainer(target);
- }
- for (LibraryElement target in _mirrorsData.librariesInMirrorsUsedTargets) {
- addFieldsInContainer(target);
- }
- return staticFields;
- }
-
- /// Compute the impact for elements that are matched by the mirrors used
- /// annotation or, in lack thereof, all elements.
- WorldImpact _computeImpactForReflectiveElements(
- Iterable<ClassEntity> recents,
- Iterable<ClassEntity> processedClasses,
- Iterable<LibraryElement> loadedLibraries) {
- handler.enqueueReflectiveElements(
- recents, processedClasses, loadedLibraries);
- return handler.flush();
- }
-
- /// Compute the impact for the static fields that have been marked as used by
- /// reflective usage through `MirrorsUsed`.
- WorldImpact _computeImpactForReflectiveStaticFields(
- Iterable<Element> elements) {
- handler.enqueueReflectiveStaticFields(elements);
- return handler.flush();
- }
-
- void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
- if (_mirrorsData.isTreeShakingDisabled) {
- enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses,
- enqueuer.processedClasses, _compiler.libraryLoader.libraries));
- } else if (_mirrorsData.membersInMirrorsUsedTargets.isNotEmpty ||
- _mirrorsData.classesInMirrorsUsedTargets.isNotEmpty ||
- _mirrorsData.librariesInMirrorsUsedTargets.isNotEmpty) {
- // Add all static elements (not classes) that have been requested for
- // reflection. If there is no mirror-usage these are probably not
- // necessary, but the backend relies on them being resolved.
- enqueuer.applyImpact(
- _computeImpactForReflectiveStaticFields(_findStaticFieldTargets()));
- }
-
- if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.');
-
- if (_mirrorsData.mustRetainMetadata) {
- _reporter.log('Retaining metadata.');
-
- for (LibraryEntity library in _compiler.libraryLoader.libraries) {
- _mirrorsData.retainMetadataOfLibrary(library,
- addForEmission: !enqueuer.isResolutionQueue);
- }
-
- if (!enqueuer.queueIsClosed) {
- /// Register the constant value of [metadata] as live in resolution.
- void registerMetadataConstant(MetadataAnnotation metadata) {
- ConstantValue constant =
- _constants.getConstantValueForMetadata(metadata);
- Dependency dependency =
- new Dependency(constant, metadata.annotatedElement);
- _metadataConstants.add(dependency);
- _impactBuilder.registerConstantUse(new ConstantUse.mirrors(constant));
- }
-
- // TODO(johnniwinther): We should have access to all recently processed
- // elements and process these instead.
- processMetadata(enqueuer.processedEntities, registerMetadataConstant);
- } else {
- for (Dependency dependency in _metadataConstants) {
- _impactBuilder.registerConstantUse(
- new ConstantUse.mirrors(dependency.constant));
- }
- _metadataConstants.clear();
- }
- enqueuer.applyImpact(_impactBuilder.flush());
- }
- }
-
- /// Call [registerMetadataConstant] on all metadata from [entities].
- void processMetadata(
- Iterable<Entity> entities, void onMetadata(MetadataAnnotation metadata)) {
- void processLibraryMetadata(LibraryElement library) {
- if (_registeredMetadata.add(library)) {
- library.metadata.forEach(onMetadata);
- library.entryCompilationUnit.metadata.forEach(onMetadata);
- for (ImportElement import in library.imports) {
- import.metadata.forEach(onMetadata);
- }
- }
- }
-
- void processElementMetadata(Element element) {
- if (_registeredMetadata.add(element)) {
- element.metadata.forEach(onMetadata);
- if (element.isFunction) {
- FunctionElement function = element;
- for (ParameterElement parameter in function.parameters) {
- parameter.metadata.forEach(onMetadata);
- }
- }
- if (element.enclosingClass != null) {
- // Only process library of top level fields/methods
- // (and not for classes).
- // TODO(johnniwinther): Fix this: We are missing some metadata on
- // libraries (example: in co19/Language/Metadata/before_export_t01).
- if (element.enclosingElement is ClassElement) {
- // Use [enclosingElement] instead of [enclosingClass] to ensure that
- // we process patch class metadata for patch and injected members.
- processElementMetadata(element.enclosingElement);
- }
- } else {
- processLibraryMetadata(element.library);
- }
- }
- }
-
- entities.forEach((member) => processElementMetadata(member));
- }
-
- void onResolutionComplete() {
- _registeredMetadata.clear();
- }
-
- MirrorsCodegenAnalysis close() => new MirrorsCodegenAnalysisImpl(
- _backend, handler._resolution, _metadataConstants);
-}
-
-class MirrorsCodegenAnalysisImpl implements MirrorsCodegenAnalysis {
- final JavaScriptBackend _backend;
- final MirrorsHandler handler;
-
- StagedWorldImpactBuilder _impactBuilder = new StagedWorldImpactBuilder();
-
- /// List of constants from metadata. If metadata must be preserved,
- /// these constants must be registered.
- final List<Dependency> _metadataConstants;
-
- /// Number of methods compiled before considering reflection.
- int preMirrorsMethodCount = 0;
-
- MirrorsCodegenAnalysisImpl(
- this._backend, Resolution resolution, this._metadataConstants)
- : handler = new MirrorsHandler(_backend, resolution);
-
- DiagnosticReporter get _reporter => _backend.reporter;
- Compiler get _compiler => _backend.compiler;
- JavaScriptConstantCompiler get _constants => _backend.constants;
- MirrorsData get _mirrorsData => _backend.mirrorsData;
-
- /// Compute the impact for elements that are matched by the mirrors used
- /// annotation or, in lack thereof, all elements.
- WorldImpact _computeImpactForReflectiveElements(
- Iterable<ClassEntity> recents,
- Iterable<ClassEntity> processedClasses,
- Iterable<LibraryElement> loadedLibraries) {
- handler.enqueueReflectiveElements(
- recents, processedClasses, loadedLibraries);
- return handler.flush();
- }
-
- void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
- if (preMirrorsMethodCount == 0) {
- preMirrorsMethodCount = _backend.generatedCode.length;
- }
- if (_mirrorsData.isTreeShakingDisabled) {
- enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses,
- enqueuer.processedClasses, _compiler.libraryLoader.libraries));
- }
-
- if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.');
-
- if (_mirrorsData.mustRetainMetadata) {
- _reporter.log('Retaining metadata.');
-
- (_compiler.libraryLoader.libraries as Iterable<LibraryElement>)
- .forEach(_mirrorsData.retainMetadataOfLibrary);
-
- for (Dependency dependency in _metadataConstants) {
- _impactBuilder
- .registerConstantUse(new ConstantUse.mirrors(dependency.constant));
- }
- _metadataConstants.clear();
- enqueuer.applyImpact(_impactBuilder.flush());
- }
- }
-}
-
-class MirrorsHandler {
- static final TRACE_MIRROR_ENQUEUING =
- const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
-
- final JavaScriptBackend _backend;
- final Resolution _resolution;
-
- bool hasEnqueuedReflectiveElements = false;
- bool hasEnqueuedReflectiveStaticFields = false;
-
- StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
-
- MirrorsHandler(this._backend, this._resolution);
-
- DiagnosticReporter get _reporter => _resolution.reporter;
-
- WorldImpact flush() => impactBuilder.flush();
-
- void _logEnqueueReflectiveAction(action, [msg = ""]) {
- if (TRACE_MIRROR_ENQUEUING) {
- print("MIRROR_ENQUEUE (R): $action $msg");
- }
- }
-
- /**
- * Decides whether an element should be included to satisfy requirements
- * of the mirror system.
- *
- * During resolution, we have to resort to matching elements against the
- * [MirrorsUsed] pattern, as we do not have a complete picture of the world,
- * yet.
- */
- bool _shouldIncludeLibraryDueToMirrors(LibraryElement element,
- {bool includedEnclosing}) {
- return includedEnclosing ||
- _backend.mirrorsData.isLibraryRequiredByMirrorSystem(element);
- }
-
- bool _shouldIncludeClassDueToMirrors(ClassElement element,
- {bool includedEnclosing}) {
- return includedEnclosing ||
- _backend.mirrorsData.isClassRequiredByMirrorSystem(element);
- }
-
- bool _shouldIncludeMemberDueToMirrors(MemberElement element,
- {bool includedEnclosing}) {
- return includedEnclosing ||
- _backend.mirrorsData.isMemberRequiredByMirrorSystem(element);
- }
-
- /// Enqueue the constructor [ctor] if it is required for reflection.
- ///
- /// [enclosingWasIncluded] provides a hint whether the enclosing element was
- /// needed for reflection.
- void _enqueueReflectiveConstructor(ConstructorElement constructor,
- {bool enclosingWasIncluded}) {
- assert(constructor.isDeclaration);
- if (_shouldIncludeMemberDueToMirrors(constructor,
- includedEnclosing: enclosingWasIncluded)) {
- if (constructor.isFromEnvironmentConstructor) return;
- _logEnqueueReflectiveAction(constructor);
- ClassElement cls = constructor.enclosingClass;
- impactBuilder
- .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType));
- impactBuilder.registerStaticUse(new StaticUse.mirrorUse(constructor));
- }
- }
-
- /// Enqueue the member [element] if it is required for reflection.
- ///
- /// [enclosingWasIncluded] provides a hint whether the enclosing element was
- /// needed for reflection.
- void _enqueueReflectiveMember(
- MemberElement element, bool enclosingWasIncluded) {
- assert(element.isDeclaration);
- if (_shouldIncludeMemberDueToMirrors(element,
- includedEnclosing: enclosingWasIncluded)) {
- _logEnqueueReflectiveAction(element);
- if (Elements.isStaticOrTopLevel(element)) {
- impactBuilder.registerStaticUse(new StaticUse.mirrorUse(element));
- } else if (element.isInstanceMember) {
- // We need to enqueue all members matching this one in subclasses, as
- // well.
- // TODO(herhut): Use TypedSelector.subtype for enqueueing
- DynamicUse dynamicUse =
- new DynamicUse(new Selector.fromElement(element));
- impactBuilder.registerDynamicUse(dynamicUse);
- if (element.isField) {
- DynamicUse dynamicUse =
- new DynamicUse(new Selector.setter(element.memberName.setter));
- impactBuilder.registerDynamicUse(dynamicUse);
- }
- }
- }
- }
-
- /// Enqueue the member [element] if it is required for reflection.
- ///
- /// [enclosingWasIncluded] provides a hint whether the enclosing element was
- /// needed for reflection.
- void _enqueueReflectiveElementsInClass(
- ClassElement cls, Iterable<ClassEntity> recents,
- {bool enclosingWasIncluded}) {
- assert(cls.isDeclaration);
- if (cls.library.isInternalLibrary || cls.isInjected) return;
- bool includeClass = _shouldIncludeClassDueToMirrors(cls,
- includedEnclosing: enclosingWasIncluded);
- if (includeClass) {
- _logEnqueueReflectiveAction(cls, "register");
- ClassElement declaration = cls.declaration;
- declaration.ensureResolved(_resolution);
- impactBuilder.registerTypeUse(
- new TypeUse.mirrorInstantiation(declaration.rawType));
- }
- // If the class is never instantiated, we know nothing of it can possibly
- // be reflected upon.
- // TODO(herhut): Add a warning if a mirrors annotation cannot hit.
- if (recents.contains(cls.declaration)) {
- _logEnqueueReflectiveAction(cls, "members");
- cls.constructors.forEach((Element element) {
- _enqueueReflectiveConstructor(element.declaration,
- enclosingWasIncluded: includeClass);
- });
- cls.forEachClassMember((Member member) {
- _enqueueReflectiveMember(member.element, includeClass);
- });
- }
- }
-
- /// Set of classes that need to be considered for reflection although not
- /// otherwise visible during resolution.
- Iterable<ClassEntity> get _classesRequiredForReflection {
- // TODO(herhut): Clean this up when classes needed for rti are tracked.
- return [
- _resolution.commonElements.closureClass,
- _resolution.commonElements.jsIndexableClass
- ];
- }
-
- /// Enqueue special classes that might not be visible by normal means or that
- /// would not normally be enqueued:
- ///
- /// [Closure] is treated specially as it is the superclass of all closures.
- /// Although it is in an internal library, we mark it as reflectable. Note
- /// that none of its methods are reflectable, unless reflectable by
- /// inheritance.
- void _enqueueReflectiveSpecialClasses() {
- Iterable<ClassElement> classes = _classesRequiredForReflection;
- for (ClassElement cls in classes) {
- if (_backend.mirrorsData.isClassReferencedFromMirrorSystem(cls)) {
- _logEnqueueReflectiveAction(cls);
- cls.ensureResolved(_resolution);
- impactBuilder
- .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType));
- }
- }
- }
-
- /// Enqueue all local members of the library [lib] if they are required for
- /// reflection.
- void _enqueueReflectiveElementsInLibrary(
- LibraryElement lib, Iterable<ClassEntity> recents) {
- assert(lib.isDeclaration);
- bool includeLibrary =
- _shouldIncludeLibraryDueToMirrors(lib, includedEnclosing: false);
- lib.forEachLocalMember((Element member) {
- if (member.isInjected) return;
- if (member.isClass) {
- ClassElement cls = member;
- cls.ensureResolved(_resolution);
- do {
- _enqueueReflectiveElementsInClass(cls, recents,
- enclosingWasIncluded: includeLibrary);
- cls = cls.superclass;
- } while (cls != null && cls.isUnnamedMixinApplication);
- } else if (member.isTypedef) {
- TypedefElement typedef = member;
- typedef.ensureResolved(_resolution);
- } else {
- _enqueueReflectiveMember(member, includeLibrary);
- }
- });
- }
-
- /// Enqueue all elements that are matched by the mirrors used
- /// annotation or, in lack thereof, all elements.
- // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly.
- void enqueueReflectiveElements(
- Iterable<ClassEntity> recents,
- Iterable<ClassEntity> processedClasses,
- Iterable<LibraryElement> loadedLibraries) {
- if (!hasEnqueuedReflectiveElements) {
- _logEnqueueReflectiveAction("!START enqueueAll");
- // First round of enqueuing, visit everything that is visible to
- // also pick up static top levels, etc.
- // Also, during the first round, consider all classes that have been seen
- // as recently seen, as we do not know how many rounds of resolution might
- // have run before tree shaking is disabled and thus everything is
- // enqueued.
- recents = processedClasses.toSet();
- _reporter.log('Enqueuing everything');
- for (LibraryElement lib in loadedLibraries) {
- _enqueueReflectiveElementsInLibrary(lib, recents);
- }
- _enqueueReflectiveSpecialClasses();
- hasEnqueuedReflectiveElements = true;
- hasEnqueuedReflectiveStaticFields = true;
- _logEnqueueReflectiveAction("!DONE enqueueAll");
- } else if (recents.isNotEmpty) {
- // Keep looking at new classes until fixpoint is reached.
- _logEnqueueReflectiveAction("!START enqueueRecents");
- recents.forEach((ClassEntity _cls) {
- ClassElement cls = _cls;
- _enqueueReflectiveElementsInClass(cls, recents,
- enclosingWasIncluded: _shouldIncludeLibraryDueToMirrors(cls.library,
- includedEnclosing: false));
- });
- _logEnqueueReflectiveAction("!DONE enqueueRecents");
- }
- }
-
- /// Enqueue the static fields that have been marked as used by reflective
- /// usage through `MirrorsUsed`.
- // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly.
- void enqueueReflectiveStaticFields(Iterable<Element> elements) {
- if (hasEnqueuedReflectiveStaticFields) return;
- hasEnqueuedReflectiveStaticFields = true;
- for (Element element in elements) {
- _enqueueReflectiveMember(element, true);
- }
- }
-}
-
-/// Records that [constant] is used by the element behind [registry].
-class Dependency {
- final ConstantValue constant;
- final Element annotatedElement;
-
- const Dependency(this.constant, this.annotatedElement);
-
- String toString() => '$annotatedElement:${constant.toStructuredText()}';
-}
diff --git a/pkg/compiler/lib/src/js_backend/mirrors_data.dart b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
deleted file mode 100644
index fe94bca..0000000
--- a/pkg/compiler/lib/src/js_backend/mirrors_data.dart
+++ /dev/null
@@ -1,708 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import '../common.dart';
-import '../common_elements.dart';
-import '../compiler.dart';
-import '../constants/values.dart';
-import '../elements/elements.dart' show AbstractFieldElement, Element;
-import '../elements/entities.dart';
-import '../elements/names.dart';
-import '../elements/types.dart';
-import '../world.dart';
-import '../universe/world_builder.dart';
-import '../util/emptyset.dart';
-
-abstract class MirrorsData {
- /// True if a call to preserveMetadataMarker has been seen. This means that
- /// metadata must be retained for dart:mirrors to work correctly.
- // resolution-empty-queue
- bool get mustRetainMetadata;
-
- /// True if any metadata has been retained. This is slightly different from
- /// [mustRetainMetadata] and tells us if any metadata was retained. For
- /// example, if [mustRetainMetadata] is true but there is no metadata in the
- /// program, this variable will stil be false.
- // emitter
- bool get hasRetainedMetadata;
-
- /// True if a call to preserveLibraryNames has been seen.
- // emitter
- bool get mustRetainLibraryNames;
-
- /// True if a call to preserveNames has been seen.
- // resolution-empty-queue
- bool get mustPreserveNames;
-
- /// True if a call to disableTreeShaking has been seen.
- bool get isTreeShakingDisabled;
-
- /// Set of symbols that the user has requested for reflection.
- Iterable<String> get symbolsUsed;
-
- /// The members that the user has requested for reflection through the
- /// 'targets' property of a `MirrorsUsed` annotation.
- Iterable<MemberEntity> get membersInMirrorsUsedTargets;
-
- /// The classes that the user has requested for reflection through the
- /// 'targets' property of a `MirrorsUsed` annotation.
- Iterable<ClassEntity> get classesInMirrorsUsedTargets;
-
- /// The libraries that the user has requested for reflection through the
- /// 'targets' property of a `MirrorsUsed` annotation.
- Iterable<LibraryEntity> get librariesInMirrorsUsedTargets;
-
- /// Should the getter for [element] that would normally not be generated due
- /// to tree-shaking be retained for reflection?
- bool shouldRetainGetter(FieldEntity element);
-
- /// Should the setter for [element] that would normally not be generated due
- /// to tree-shaking be retained for reflection?
- bool shouldRetainSetter(FieldEntity element);
-
- /// Should [name] be retained for reflection?
- bool shouldRetainName(String name);
-
- /// Returns `true` if the class [element] is covered by a `MirrorsUsed`
- /// annotation.
- ///
- /// Note that it might still be ok to tree shake the element away if no
- /// reflection is used in the program (and thus [isTreeShakingDisabled] is
- /// still false). Therefore _do not_ use this predicate to decide inclusion
- /// in the tree, use [requiredByMirrorSystem] instead.
- bool isClassReferencedFromMirrorSystem(ClassEntity element);
-
- /// Returns `true` if the member [element] is covered by a `MirrorsUsed`
- /// annotation.
- ///
- /// Note that it might still be ok to tree shake the element away if no
- /// reflection is used in the program (and thus [isTreeShakingDisabled] is
- /// still false). Therefore _do not_ use this predicate to decide inclusion
- /// in the tree, use [requiredByMirrorSystem] instead.
- bool isMemberReferencedFromMirrorSystem(MemberEntity element);
-
- /// Returns `true` if the library [element] is covered by a `MirrorsUsed`
- /// annotation.
- bool isLibraryReferencedFromMirrorSystem(LibraryEntity element);
-
- /// Returns `true` if the typedef [element] needs reflection information at
- /// runtime.
- ///
- /// This property is used to tag emitted elements with a marker which is
- /// checked by the runtime system to throw an exception if an element is
- /// accessed (invoked, get, set) that is not accessible for the reflective
- /// system.
- bool isTypedefAccessibleByReflection(TypedefEntity element);
-
- /// Returns `true` if the class [element] needs reflection information at
- /// runtime.
- ///
- /// This property is used to tag emitted elements with a marker which is
- /// checked by the runtime system to throw an exception if an element is
- /// accessed (invoked, get, set) that is not accessible for the reflective
- /// system.
- bool isClassAccessibleByReflection(ClassEntity element);
-
- /// Returns `true` if the member [element] needs reflection information at
- /// runtime.
- ///
- /// This property is used to tag emitted elements with a marker which is
- /// checked by the runtime system to throw an exception if an element is
- /// accessed (invoked, get, set) that is not accessible for the reflective
- /// system.
- bool isMemberAccessibleByReflection(MemberEntity element);
-
- bool retainMetadataOfLibrary(LibraryEntity element,
- {bool addForEmission: true});
- bool retainMetadataOfTypedef(TypedefEntity element);
- bool retainMetadataOfClass(ClassEntity element);
- bool retainMetadataOfMember(MemberEntity element);
-
- /// Returns true if this element has to be enqueued due to
- /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if
- /// normal tree shaking is still active ([isTreeShakingDisabled] is false).
- bool isLibraryRequiredByMirrorSystem(LibraryEntity element);
- bool isClassRequiredByMirrorSystem(ClassEntity element);
- bool isMemberRequiredByMirrorSystem(MemberEntity element);
- bool isClassResolved(ClassEntity element);
-}
-
-abstract class MirrorsDataBuilder {
- void registerUsedMember(MemberEntity member);
-
- /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed
- /// annotations. The arguments corresponds to the unions of the corresponding
- /// fields of the annotations.
- void registerMirrorUsage(
- Set<String> symbols, Set<Element> targets, Set<Element> metaTargets);
-
- /// Called when `const Symbol(name)` is seen.
- void registerConstSymbol(String name);
-
- void maybeMarkClosureAsNeededForReflection(
- ClassEntity closureClass, FunctionEntity callMethod, Local localFunction);
-
- void computeMembersNeededForReflection(
- ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld);
-}
-
-abstract class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
- /// True if a call to preserveMetadataMarker has been seen. This means that
- /// metadata must be retained for dart:mirrors to work correctly.
- bool mustRetainMetadata = false;
-
- /// True if any metadata has been retained. This is slightly different from
- /// [mustRetainMetadata] and tells us if any metadata was retained. For
- /// example, if [mustRetainMetadata] is true but there is no metadata in the
- /// program, this variable will stil be false.
- bool hasRetainedMetadata = false;
-
- /// True if a call to preserveLibraryNames has been seen.
- bool mustRetainLibraryNames = false;
-
- /// True if a call to preserveNames has been seen.
- bool mustPreserveNames = false;
-
- /// True if a call to disableTreeShaking has been seen.
- bool isTreeShakingDisabled = false;
-
- /// True if there isn't sufficient @MirrorsUsed data.
- bool hasInsufficientMirrorsUsed = false;
-
- /// Set of symbols that the user has requested for reflection.
- final Set<String> symbolsUsed = new Set<String>();
-
- /// Set of elements that the user has requested for reflection.
- final Set<MemberEntity> membersInMirrorsUsedTargets = new Set<MemberEntity>();
- final Set<ClassEntity> classesInMirrorsUsedTargets = new Set<ClassEntity>();
- final Set<LibraryEntity> librariesInMirrorsUsedTargets =
- new Set<LibraryEntity>();
- final Set<TypedefEntity> _typedefsInMirrorsUsedTargets =
- new Set<TypedefEntity>();
-
- /// List of annotations provided by user that indicate that the annotated
- /// element must be retained.
- final Set<ClassEntity> metaTargetsUsed = new Set<ClassEntity>();
-
- // TODO(johnniwinther): Avoid the need for this.
- final Compiler _compiler;
-
- final ElementEnvironment _elementEnvironment;
- final CommonElements _commonElements;
-
- MirrorsDataImpl(
- this._compiler, this._elementEnvironment, this._commonElements);
-
- void registerUsedMember(MemberEntity member) {
- if (member == _commonElements.disableTreeShakingMarker) {
- isTreeShakingDisabled = true;
- } else if (member == _commonElements.preserveNamesMarker) {
- mustPreserveNames = true;
- } else if (member == _commonElements.preserveMetadataMarker) {
- mustRetainMetadata = true;
- } else if (member == _commonElements.preserveLibraryNamesMarker) {
- mustRetainLibraryNames = true;
- }
- }
-
- bool shouldRetainGetter(FieldEntity element) {
- return isTreeShakingDisabled && isMemberAccessibleByReflection(element);
- }
-
- bool shouldRetainSetter(FieldEntity element) {
- return isTreeShakingDisabled && isMemberAccessibleByReflection(element);
- }
-
- /// Should [name] be retained for reflection?
- bool shouldRetainName(String name) {
- if (hasInsufficientMirrorsUsed) return mustPreserveNames;
- if (name == '') return false;
- return symbolsUsed.contains(name);
- }
-
- @override
- bool retainMetadataOfMember(MemberEntity element) {
- if (mustRetainMetadata) {
- hasRetainedMetadata = true;
- if (isMemberReferencedFromMirrorSystem(element)) {
- _addConstantsForEmission(
- getMemberMetadata(element, includeParameterMetadata: true));
- return true;
- }
- }
- return false;
- }
-
- @override
- bool retainMetadataOfClass(ClassEntity element) {
- if (mustRetainMetadata) {
- hasRetainedMetadata = true;
- if (isClassReferencedFromMirrorSystem(element)) {
- _addConstantsForEmission(getClassMetadata(element));
- return true;
- }
- }
- return false;
- }
-
- @override
- bool retainMetadataOfTypedef(TypedefEntity element) {
- if (mustRetainMetadata) {
- hasRetainedMetadata = true;
- if (_isTypedefReferencedFromMirrorSystem(element)) {
- _addConstantsForEmission(getTypedefMetadata(element));
- return true;
- }
- }
- return false;
- }
-
- @override
- bool retainMetadataOfLibrary(LibraryEntity element,
- {bool addForEmission: true}) {
- if (mustRetainMetadata) {
- hasRetainedMetadata = true;
- if (isLibraryReferencedFromMirrorSystem(element)) {
- Iterable<ConstantValue> constants = getLibraryMetadata(element);
- if (addForEmission) {
- _addConstantsForEmission(constants);
- }
- return true;
- }
- }
- return false;
- }
-
- Iterable<ConstantValue> getLibraryMetadata(LibraryEntity element) {
- return _elementEnvironment.getLibraryMetadata(element);
- }
-
- Iterable<ConstantValue> getClassMetadata(ClassEntity element) {
- return _elementEnvironment.getClassMetadata(element);
- }
-
- Iterable<ConstantValue> getMemberMetadata(MemberEntity element,
- {bool includeParameterMetadata}) {
- return _elementEnvironment.getMemberMetadata(element,
- includeParameterMetadata: includeParameterMetadata);
- }
-
- Iterable<ConstantValue> getTypedefMetadata(TypedefEntity element) {
- return _elementEnvironment.getTypedefMetadata(element);
- }
-
- void _addConstantsForEmission(Iterable<ConstantValue> constants) {
- for (ConstantValue constant in constants) {
- CodegenWorldBuilder worldBuilder = _compiler.codegenWorldBuilder;
- worldBuilder.addCompileTimeConstantForEmission(constant);
- }
- }
-
- /// Sets of elements that are needed by reflection. Computed using
- /// [computeMembersNeededForReflection] on first use.
- Set<ClassEntity> _classesNeededForReflection;
- Set<TypedefEntity> _typedefsNeededForReflection;
- Set<MemberEntity> _membersNeededForReflection;
- Set<Local> _closuresNeededForReflection;
-
- /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed
- /// annotations. The arguments corresponds to the unions of the corresponding
- /// fields of the annotations.
- // TODO(redemption): Change type of [metaTargets] to `Set<ClassEntity>`.
- void registerMirrorUsage(
- Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) {
- if (symbols == null && targets == null && metaTargets == null) {
- // The user didn't specify anything, or there are imports of
- // 'dart:mirrors' without @MirrorsUsed.
- hasInsufficientMirrorsUsed = true;
- return;
- }
- if (symbols != null) symbolsUsed.addAll(symbols);
- if (targets != null) {
- for (Element target in targets) {
- if (target.isAbstractField) {
- AbstractFieldElement field = target;
- if (field.getter != null) {
- membersInMirrorsUsedTargets.add(field.getter);
- }
- if (field.setter != null) {
- membersInMirrorsUsedTargets.add(field.setter);
- }
- } else if (target.isClass) {
- classesInMirrorsUsedTargets.add(target as ClassEntity);
- } else if (target.isTypedef) {
- _typedefsInMirrorsUsedTargets.add(target as TypedefEntity);
- } else if (target.isLibrary) {
- librariesInMirrorsUsedTargets.add(target as LibraryEntity);
- } else if (target != null) {
- membersInMirrorsUsedTargets.add(target as MemberEntity);
- }
- }
- }
- if (metaTargets != null) {
- for (dynamic element in metaTargets) {
- if (element is ClassEntity) {
- metaTargetsUsed.add(element);
- }
- }
- }
- }
-
- @override
- bool isClassAccessibleByReflection(ClassEntity element) {
- return _classesNeededForReflection.contains(_getDartClass(element));
- }
-
- @override
- bool isTypedefAccessibleByReflection(TypedefEntity element) {
- return _typedefsNeededForReflection.contains(element);
- }
-
- ClassEntity _getDartClass(ClassEntity cls) {
- if (cls == _commonElements.jsIntClass) {
- return _commonElements.intClass;
- } else if (cls == _commonElements.jsBoolClass) {
- return _commonElements.boolClass;
- } else if (cls == _commonElements.jsNumberClass) {
- return _commonElements.numClass;
- } else if (cls == _commonElements.jsDoubleClass) {
- return _commonElements.doubleClass;
- } else if (cls == _commonElements.jsStringClass) {
- return _commonElements.stringClass;
- } else if (cls == _commonElements.jsArrayClass) {
- return _commonElements.listClass;
- } else if (cls == _commonElements.jsNullClass) {
- return _commonElements.nullClass;
- } else {
- return cls;
- }
- }
-
- bool isMemberAccessibleByReflection(MemberEntity element) {
- return _membersNeededForReflection.contains(element);
- }
-
- /// Returns true if this element has to be enqueued due to
- /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if
- /// normal tree shaking is still active ([isTreeShakingDisabled] is false).
- bool isLibraryRequiredByMirrorSystem(LibraryEntity element) {
- return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
- _libraryMatchesMirrorsMetaTarget(element) ||
- librariesInMirrorsUsedTargets.contains(element);
- }
-
- bool isClassRequiredByMirrorSystem(ClassEntity element) {
- return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
- _classMatchesMirrorsMetaTarget(element) ||
- classesInMirrorsUsedTargets.contains(element);
- }
-
- bool isMemberRequiredByMirrorSystem(MemberEntity element) {
- return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
- _memberMatchesMirrorsMetaTarget(element) ||
- membersInMirrorsUsedTargets.contains(element);
- }
-
- @override
- bool isLibraryReferencedFromMirrorSystem(LibraryEntity element) {
- return _libraryReferencedFromMirrorSystem(element);
- }
-
- @override
- bool isMemberReferencedFromMirrorSystem(MemberEntity element) {
- if (_memberReferencedFromMirrorSystem(element)) return true;
- if (element.enclosingClass != null) {
- return isClassReferencedFromMirrorSystem(element.enclosingClass);
- } else {
- return isLibraryReferencedFromMirrorSystem(element.library);
- }
- }
-
- @override
- bool isClassReferencedFromMirrorSystem(ClassEntity element) {
- return _classReferencedFromMirrorSystem(element) ||
- isLibraryReferencedFromMirrorSystem(element.library);
- }
-
- bool _isTypedefReferencedFromMirrorSystem(TypedefEntity element) {
- return _typedefReferencedFromMirrorSystem(element) ||
- isLibraryReferencedFromMirrorSystem(element.library);
- }
-
- bool _memberReferencedFromMirrorSystem(MemberEntity element) {
- return hasInsufficientMirrorsUsed ||
- _memberMatchesMirrorsMetaTarget(element) ||
- membersInMirrorsUsedTargets.contains(element);
- }
-
- bool _classReferencedFromMirrorSystem(ClassEntity element) {
- return hasInsufficientMirrorsUsed ||
- _classMatchesMirrorsMetaTarget(element) ||
- classesInMirrorsUsedTargets.contains(element);
- }
-
- bool _typedefReferencedFromMirrorSystem(TypedefEntity element) {
- return hasInsufficientMirrorsUsed ||
- _typedefMatchesMirrorsMetaTarget(element) ||
- _typedefsInMirrorsUsedTargets.contains(element);
- }
-
- bool _libraryReferencedFromMirrorSystem(LibraryEntity element) {
- return hasInsufficientMirrorsUsed ||
- _libraryMatchesMirrorsMetaTarget(element) ||
- librariesInMirrorsUsedTargets.contains(element);
- }
-
- bool _libraryMatchesMirrorsMetaTarget(LibraryEntity element) {
- if (metaTargetsUsed.isEmpty) return false;
- return _matchesMirrorsMetaTarget(getLibraryMetadata(element));
- }
-
- bool _classMatchesMirrorsMetaTarget(ClassEntity element) {
- if (metaTargetsUsed.isEmpty) return false;
- return _matchesMirrorsMetaTarget(getClassMetadata(element));
- }
-
- bool _memberMatchesMirrorsMetaTarget(MemberEntity element) {
- if (metaTargetsUsed.isEmpty) return false;
- return _matchesMirrorsMetaTarget(
- getMemberMetadata(element, includeParameterMetadata: false));
- }
-
- bool _typedefMatchesMirrorsMetaTarget(TypedefEntity element) {
- if (metaTargetsUsed.isEmpty) return false;
- return _matchesMirrorsMetaTarget(getTypedefMetadata(element));
- }
-
- /**
- * Returns `true` if the element is needed because it has an annotation
- * of a type that is used as a meta target for reflection.
- */
- bool _matchesMirrorsMetaTarget(Iterable<ConstantValue> constants) {
- if (metaTargetsUsed.isEmpty) return false;
- for (ConstantValue constant in constants) {
- DartType type = constant.getType(_commonElements);
- if (type is InterfaceType && metaTargetsUsed.contains(type.element))
- return true;
- }
- return false;
- }
-
- void createImmutableSets() {
- _classesNeededForReflection = const ImmutableEmptySet<ClassEntity>();
- _typedefsNeededForReflection = const ImmutableEmptySet<TypedefEntity>();
- _membersNeededForReflection = const ImmutableEmptySet<MemberEntity>();
- _closuresNeededForReflection = const ImmutableEmptySet<Local>();
- }
-
- bool isLibraryInternal(LibraryEntity library) {
- return library.canonicalUri.scheme == 'dart' &&
- library.canonicalUri.path.startsWith('_');
- }
-
- /// Whether [cls] is 'injected'.
- ///
- /// An injected class is declared in a patch library with no corresponding
- /// class in the origin library.
- // TODO(redemption): Detect injected classes from .dill.
- bool isClassInjected(ClassEntity cls) => false;
-
- bool isClassResolved(ClassEntity cls) => true;
-
- void forEachConstructor(
- ClassEntity cls, void f(ConstructorEntity constructor)) {
- _elementEnvironment.forEachConstructor(cls, f);
- }
-
- void forEachClassMember(
- ClassEntity cls, void f(MemberEntity member, Name memberName)) {
- _elementEnvironment.forEachClassMember(cls,
- (ClassEntity declarer, MemberEntity member) {
- if (member.isSetter) {
- f(member, member.memberName.setter);
- } else {
- f(member, member.memberName.getter);
- }
- });
- }
-
- /**
- * Visits all classes and computes whether its members are needed for
- * reflection.
- *
- * We have to precompute this set as we cannot easily answer the need for
- * reflection locally when looking at the member: We lack the information by
- * which classes a member is inherited. Called after resolution is complete.
- *
- * We filter out private libraries here, as their elements should not
- * be visible by reflection unless some other interfaces makes them
- * accessible.
- */
- void computeMembersNeededForReflection(
- ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) {
- if (_membersNeededForReflection != null) return;
- if (!closedWorld.backendUsage.isMirrorsUsed || true) {
- createImmutableSets();
- return;
- }
- // TODO(johnniwinther): Remove this:
- _classesNeededForReflection = new Set<ClassEntity>();
- _typedefsNeededForReflection = new Set<TypedefEntity>();
- _membersNeededForReflection = new Set<MemberEntity>();
- _closuresNeededForReflection = new Set<Local>();
-
- // Compute a mapping from class to the closures it contains, so we
- // can include the correct ones when including the class.
- Map<ClassEntity, List<Local>> classToClosuresMap =
- new Map<ClassEntity, List<Local>>();
- Map<Local, MemberEntity> closureToMemberMap =
- new Map<Local, MemberEntity>();
- worldBuilder.forEachLocalFunction((MemberEntity member, Local closure) {
- closureToMemberMap[closure] = member;
- classToClosuresMap
- .putIfAbsent(member.enclosingClass, () => [])
- .add(closure);
- });
- bool foundClosure = false;
- for (ClassEntity cls in worldBuilder.directlyInstantiatedClasses) {
- // Do not process internal classes.
- if (isLibraryInternal(cls.library) || isClassInjected(cls)) continue;
- if (isClassReferencedFromMirrorSystem(cls)) {
- Set<Name> memberNames = new Set<Name>();
- // 1) the class (should be resolved)
- assert(isClassResolved(cls), failedAt(cls));
- _classesNeededForReflection.add(cls);
- // 2) its constructors (if resolved)
- forEachConstructor(cls, (ConstructorEntity constructor) {
- if (worldBuilder.isMemberUsed(constructor)) {
- _membersNeededForReflection.add(constructor);
- }
- });
- // 3) all members, including fields via getter/setters (if resolved)
- forEachClassMember(cls, (MemberEntity member, Name memberName) {
- if (worldBuilder.isMemberUsed(member)) {
- memberNames.add(memberName);
- _membersNeededForReflection.add(member);
- }
- });
- // 4) all overriding members of subclasses/subtypes (should be resolved)
- if (closedWorld.hasAnyStrictSubtype(cls)) {
- closedWorld.forEachStrictSubtypeOf(cls, (ClassEntity subcls) {
- forEachClassMember(subcls, (MemberEntity member, Name memberName) {
- if (memberNames.contains(memberName)) {
- // TODO(20993): find out why this assertion fails.
- // assert(worldBuilder.isMemberUsed(member.element),
- // failedAt(member.element));
- if (worldBuilder.isMemberUsed(member)) {
- _membersNeededForReflection.add(member);
- }
- }
- });
- });
- }
- // 5) all its closures
- List<Local> closures = classToClosuresMap[cls];
- if (closures != null) {
- _closuresNeededForReflection.addAll(closures);
- foundClosure = true;
- }
- } else {
- // check members themselves
- forEachConstructor(cls, (ConstructorEntity element) {
- if (!worldBuilder.isMemberUsed(element)) return;
- if (_memberReferencedFromMirrorSystem(element)) {
- _membersNeededForReflection.add(element);
- }
- });
- forEachClassMember(cls, (MemberEntity member, _) {
- if (!worldBuilder.isMemberUsed(member)) return;
- if (_memberReferencedFromMirrorSystem(member)) {
- _membersNeededForReflection.add(member);
- }
- });
- // Also add in closures. Those might be reflectable is their enclosing
- // member is.
- List<Local> closures = classToClosuresMap[cls];
- if (closures != null) {
- for (Local closure in closures) {
- MemberEntity member = closureToMemberMap[closure];
- if (_memberReferencedFromMirrorSystem(member)) {
- _closuresNeededForReflection.add(closure);
- foundClosure = true;
- }
- }
- }
- }
- }
- // We also need top-level non-class elements like static functions and
- // global fields. We use the resolution queue to decide which elements are
- // part of the live world.
- for (LibraryEntity lib in _elementEnvironment.libraries) {
- if (isLibraryInternal(lib)) continue;
- _elementEnvironment.forEachLibraryMember(lib, (MemberEntity member) {
- if (worldBuilder.isMemberUsed(member) &&
- isMemberReferencedFromMirrorSystem(member)) {
- _membersNeededForReflection.add(member);
- }
- });
- }
- // And closures inside top-level elements that do not have a surrounding
- // class. These will be in the [:null:] bucket of the [classToClosureMap].
- if (classToClosuresMap.containsKey(null)) {
- for (Local closure in classToClosuresMap[null]) {
- if (isMemberReferencedFromMirrorSystem(closureToMemberMap[closure])) {
- _closuresNeededForReflection.add(closure);
- foundClosure = true;
- }
- }
- }
- // As we do not think about closures as classes, yet, we have to make sure
- // their superclasses are available for reflection manually.
- if (foundClosure) {
- ClassEntity cls = _commonElements.closureClass;
- _classesNeededForReflection.add(cls);
- }
- Set<FunctionEntity> closurizedMembers = worldBuilder.closurizedMembers;
- if (closurizedMembers.any(_membersNeededForReflection.contains)) {
- ClassEntity cls = _commonElements.boundClosureClass;
- _classesNeededForReflection.add(cls);
- }
- // Add typedefs.
- for (TypedefEntity element in closedWorld.allTypedefs) {
- if (_isTypedefReferencedFromMirrorSystem(element)) {
- _typedefsNeededForReflection.add(element);
- }
- }
- // Register all symbols of reflectable elements
- for (ClassEntity element in _classesNeededForReflection) {
- symbolsUsed.add(element.name);
- }
- for (TypedefEntity element in _typedefsNeededForReflection) {
- symbolsUsed.add(element.name);
- }
- for (MemberEntity element in _membersNeededForReflection) {
- symbolsUsed.add(element.name);
- }
- for (Local element in _closuresNeededForReflection) {
- symbolsUsed.add(element.name);
- }
- }
-
- // TODO(20791): compute closure classes after resolution and move this code to
- // [computeMembersNeededForReflection].
- void maybeMarkClosureAsNeededForReflection(ClassEntity closureClass,
- FunctionEntity callMethod, Local localFunction) {
- if (!_closuresNeededForReflection.contains(localFunction)) return;
- _membersNeededForReflection.add(callMethod);
- _classesNeededForReflection.add(closureClass);
- }
-
- /// Called when `const Symbol(name)` is seen.
- void registerConstSymbol(String name) {
- symbolsUsed.add(name);
- if (name.endsWith('=')) {
- symbolsUsed.add(name.substring(0, name.length - 1));
- }
- }
-}
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index f671f25..b732c81 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -15,12 +15,10 @@
import '../constants/values.dart';
import '../common_elements.dart' show CommonElements, ElementEnvironment;
import '../diagnostics/invariant.dart' show DEBUG_MODE;
-import '../elements/elements.dart' show Element, Elements, MemberElement;
import '../elements/entities.dart';
import '../elements/entity_utils.dart' as utils;
import '../elements/jumps.dart';
import '../elements/names.dart';
-import '../elements/resolution_types.dart';
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
import '../js_model/closure.dart';
@@ -769,7 +767,7 @@
}
String _proposeNameForConstructorBody(ConstructorBodyEntity method) {
- String name = Elements.reconstructConstructorNameSourceString(method);
+ String name = utils.reconstructConstructorNameSourceString(method);
// We include the method suffix on constructor bodies. It has no purpose,
// but this way it produces the same names as previous versions of the
// Namer class did.
@@ -1118,12 +1116,6 @@
Entity element, String proposeName(Entity element)) {
// TODO(asgerf): We can reuse more short names if we disambiguate with
// a separate namespace for each of the global holder objects.
- if (element is Element) {
- // Ensures we only work on declarations. Non-[Element] entities do not
- // have the declaration/implementation separation.
- Element e = element;
- element = e.declaration;
- }
jsAst.Name newName = userGlobals[element];
if (newName == null) {
String proposedName = proposeName(element);
@@ -1562,21 +1554,6 @@
bool _isPropertyOfStaticStateHolder(MemberEntity element) {
// TODO(ahe): Make sure this method's documentation is always true and
// remove the word "intend".
- if (element is MemberElement) {
- // TODO(johnniwinther): Clean up this method to have a single semantics on
- // entities.
- return
- // TODO(ahe): Re-write these tests to be positive (so it only returns
- // true for static/top-level mutable fields). Right now, a number of
- // other elements, such as bound closures also live in
- // [staticStateHolder].
- !element.isAccessor &&
- !element.isClass &&
- !element.isTypedef &&
- !element.isConstructor &&
- !element.isFunction &&
- !element.isLibrary;
- }
return element.isField;
}
@@ -1669,12 +1646,12 @@
String get futureOrTypeTag => r'type';
- Map<ResolutionFunctionType, jsAst.Name> functionTypeNameMap =
- new HashMap<ResolutionFunctionType, jsAst.Name>();
+ Map<FunctionType, jsAst.Name> functionTypeNameMap =
+ new HashMap<FunctionType, jsAst.Name>();
FunctionTypeNamer _functionTypeNamer;
- jsAst.Name getFunctionTypeName(ResolutionFunctionType functionType) {
+ jsAst.Name getFunctionTypeName(FunctionType functionType) {
return functionTypeNameMap.putIfAbsent(functionType, () {
_functionTypeNamer ??= new FunctionTypeNamer(rtiEncoder);
String proposedName = _functionTypeNamer.computeName(functionType);
@@ -2260,39 +2237,49 @@
}
}
-class FunctionTypeNamer extends BaseResolutionDartTypeVisitor {
+class FunctionTypeNamer extends BaseDartTypeVisitor {
final RuntimeTypesEncoder rtiEncoder;
StringBuffer sb;
FunctionTypeNamer(this.rtiEncoder);
- String computeName(ResolutionDartType type) {
+ String computeName(DartType type) {
sb = new StringBuffer();
visit(type);
return sb.toString();
}
- visit(covariant ResolutionDartType type, [_]) {
+ visit(DartType type, [_]) {
type.accept(this, null);
}
- visitType(covariant ResolutionDartType type, _) {
- sb.write(type.name);
+ visitType(DartType type, _) {}
+
+ visitInterfaceType(InterfaceType type, _) {
+ sb.write(type.element.name);
}
- visitFunctionType(covariant ResolutionFunctionType type, _) {
+ visitTypedefType(TypedefType type, _) {
+ sb.write(type.element.name);
+ }
+
+ visitTypeVariableType(TypeVariableType type, _) {
+ sb.write(type.element.name);
+ }
+
+ visitFunctionType(FunctionType type, _) {
if (rtiEncoder.isSimpleFunctionType(type)) {
sb.write('args${type.parameterTypes.length}');
return;
}
visit(type.returnType);
sb.write('_');
- for (ResolutionDartType parameter in type.parameterTypes) {
+ for (DartType parameter in type.parameterTypes) {
sb.write('_');
visit(parameter);
}
bool first = false;
- for (ResolutionDartType parameter in type.optionalParameterTypes) {
+ for (DartType parameter in type.optionalParameterTypes) {
if (!first) {
sb.write('_');
}
@@ -2302,7 +2289,7 @@
}
if (!type.namedParameterTypes.isEmpty) {
first = false;
- for (ResolutionDartType parameter in type.namedParameterTypes) {
+ for (DartType parameter in type.namedParameterTypes) {
if (!first) {
sb.write('_');
}
diff --git a/pkg/compiler/lib/src/js_backend/patch_resolver.dart b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
deleted file mode 100644
index 6c55ad3..0000000
--- a/pkg/compiler/lib/src/js_backend/patch_resolver.dart
+++ /dev/null
@@ -1,193 +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 dart2js.js_backend.patch_resolver;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart';
-import '../tree/tree.dart';
-
-class PatchResolverTask extends CompilerTask {
- final Compiler compiler;
- PatchResolverTask(Compiler compiler)
- : compiler = compiler,
- super(compiler.measurer);
-
- DiagnosticReporter get reporter => compiler.reporter;
-
- Resolution get resolution => compiler.resolution;
-
- String get name => 'JavaScript patch resolver';
-
- FunctionElement resolveExternalFunction(FunctionElementX element) {
- if (element.isPatched) {
- FunctionElementX patch = element.patch;
- reporter.withCurrentElement(patch, () {
- patch.computeType(resolution);
- });
- checkMatchingPatchSignatures(element, patch);
- element = patch;
- } else {
- if (element.isConstructor) {
- // Note: currently we allow a couple external methods without a patch,
- // namely the *.fromEnvironment const constructors in int, bool, and
- // String. In the future we might also represent native DOM methods in
- // dart:html this way.
- ConstructorElementX constructor = element;
- if (constructor.isFromEnvironmentConstructor) return element;
- }
- reporter.reportErrorMessage(
- element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
- }
- return element;
- }
-
- void checkMatchingPatchParameters(FunctionElement origin,
- List<Element> originParameters, List<Element> patchParameters) {
- bool isUnnamedListConstructor = origin is ConstructorElement &&
- resolution.commonElements.isUnnamedListConstructor(origin);
-
- assert(originParameters.length == patchParameters.length);
- for (int index = 0; index < originParameters.length; index++) {
- ParameterElementX originParameter = originParameters[index];
- ParameterElementX patchParameter = patchParameters[index];
- // TODO(johnniwinther): Remove the conditional patching when we never
- // resolve the same method twice.
- if (!originParameter.isPatched) {
- originParameter.applyPatch(patchParameter);
- } else {
- assert(originParameter.patch == patchParameter,
- failedAt(origin, "Inconsistent repatch of $originParameter."));
- }
- ResolutionDartType originParameterType =
- originParameter.computeType(resolution);
- ResolutionDartType patchParameterType =
- patchParameter.computeType(resolution);
- if (originParameterType != patchParameterType) {
- reporter.reportError(
- reporter.createMessage(
- originParameter, MessageKind.PATCH_PARAMETER_TYPE_MISMATCH, {
- 'methodName': origin.name,
- 'parameterName': originParameter.name,
- 'originParameterType': originParameterType,
- 'patchParameterType': patchParameterType
- }),
- <DiagnosticMessage>[
- reporter.createMessage(
- patchParameter,
- MessageKind.PATCH_POINT_TO_PARAMETER,
- {'parameterName': patchParameter.name}),
- ]);
- } else {
- // Hack: Use unparser to test parameter equality. This only works
- // because we are restricting patch uses and the approach cannot be used
- // elsewhere.
-
- // The node contains the type, so there is a potential overlap.
- // Therefore we only check the text if the types are identical.
- String originParameterText = originParameter.node.toString();
- String patchParameterText = patchParameter.node.toString();
- if (originParameterText != patchParameterText
- // We special case the list constructor because of the
- // optional parameter.
- &&
- !isUnnamedListConstructor) {
- reporter.reportError(
- reporter.createMessage(
- originParameter, MessageKind.PATCH_PARAMETER_MISMATCH, {
- 'methodName': origin.name,
- 'originParameter': originParameterText,
- 'patchParameter': patchParameterText
- }),
- <DiagnosticMessage>[
- reporter.createMessage(
- patchParameter,
- MessageKind.PATCH_POINT_TO_PARAMETER,
- {'parameterName': patchParameter.name}),
- ]);
- }
- }
- }
- }
-
- void checkMatchingPatchSignatures(
- FunctionElement origin, FunctionElement patch) {
- // TODO(johnniwinther): Show both origin and patch locations on errors.
- FunctionExpression originTree = origin.node;
- FunctionSignature originSignature = origin.functionSignature;
- FunctionExpression patchTree = patch.node;
- FunctionSignature patchSignature = patch.functionSignature;
-
- if ('${originTree.typeVariables}' != '${patchTree.typeVariables}') {
- reporter.withCurrentElement(patch, () {
- Node errorNode = patchTree.typeVariables != null
- ? patchTree.typeVariables
- : patchTree;
- reporter.reportError(
- reporter.createMessage(
- errorNode,
- MessageKind.PATCH_TYPE_VARIABLES_MISMATCH,
- {'methodName': origin.name}),
- [reporter.createMessage(origin, MessageKind.THIS_IS_THE_METHOD)]);
- });
- }
- if (originSignature.type.returnType != patchSignature.type.returnType) {
- reporter.withCurrentElement(patch, () {
- Node errorNode =
- patchTree.returnType != null ? patchTree.returnType : patchTree;
- reporter.reportErrorMessage(
- errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, {
- 'methodName': origin.name,
- 'originReturnType': originSignature.type.returnType,
- 'patchReturnType': patchSignature.type.returnType
- });
- });
- }
- if (originSignature.requiredParameterCount !=
- patchSignature.requiredParameterCount) {
- reporter.withCurrentElement(patch, () {
- reporter.reportErrorMessage(
- patchTree, MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH, {
- 'methodName': origin.name,
- 'originParameterCount': originSignature.requiredParameterCount,
- 'patchParameterCount': patchSignature.requiredParameterCount
- });
- });
- } else {
- checkMatchingPatchParameters(origin, originSignature.requiredParameters,
- patchSignature.requiredParameters);
- }
- if (originSignature.optionalParameterCount != 0 &&
- patchSignature.optionalParameterCount != 0) {
- if (originSignature.optionalParametersAreNamed !=
- patchSignature.optionalParametersAreNamed) {
- reporter.withCurrentElement(patch, () {
- reporter.reportErrorMessage(
- patchTree,
- MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
- {'methodName': origin.name});
- });
- }
- }
- if (originSignature.optionalParameterCount !=
- patchSignature.optionalParameterCount) {
- reporter.withCurrentElement(patch, () {
- reporter.reportErrorMessage(
- patchTree, MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH, {
- 'methodName': origin.name,
- 'originParameterCount': originSignature.optionalParameterCount,
- 'patchParameterCount': patchSignature.optionalParameterCount
- });
- });
- } else {
- checkMatchingPatchParameters(origin, originSignature.optionalParameters,
- patchSignature.optionalParameters);
- }
- }
-}
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index d0ecf6e..3f97095 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -23,11 +23,8 @@
import 'checked_mode_helpers.dart';
import 'custom_elements_analysis.dart';
import 'interceptor_data.dart';
-import 'mirrors_analysis.dart';
-import 'mirrors_data.dart';
import 'native_data.dart' show NativeBasicData;
import 'no_such_method_registry.dart';
-import 'type_variable_handler.dart';
class ResolutionEnqueuerListener extends EnqueuerListener {
// TODO(johnniwinther): Avoid the need for this.
@@ -41,12 +38,9 @@
final NativeBasicData _nativeData;
final InterceptorDataBuilder _interceptorData;
final BackendUsageBuilder _backendUsage;
- final MirrorsDataBuilder _mirrorsDataBuilder;
final NoSuchMethodRegistry _noSuchMethodRegistry;
final CustomElementsResolutionAnalysis _customElementsAnalysis;
- final MirrorsResolutionAnalysis _mirrorsAnalysis;
- final TypeVariableResolutionAnalysis _typeVariableResolutionAnalysis;
final NativeResolutionEnqueuer _nativeEnqueuer;
@@ -61,11 +55,8 @@
this._nativeData,
this._interceptorData,
this._backendUsage,
- this._mirrorsDataBuilder,
this._noSuchMethodRegistry,
this._customElementsAnalysis,
- this._mirrorsAnalysis,
- this._typeVariableResolutionAnalysis,
this._nativeEnqueuer,
this._deferredLoadTask);
@@ -166,8 +157,6 @@
// due to mirrors.
enqueuer.applyImpact(_customElementsAnalysis.flush(),
impactSource: _customElementsAnalysis);
- enqueuer.applyImpact(_typeVariableResolutionAnalysis.flush(),
- impactSource: _typeVariableResolutionAnalysis);
for (ClassEntity cls in recentClasses) {
MemberEntity element = _elementEnvironment.lookupLocalClassMember(
@@ -191,7 +180,6 @@
if (!enqueuer.queueIsEmpty) return false;
- _mirrorsAnalysis.onQueueEmpty(enqueuer, recentClasses);
return true;
}
@@ -260,16 +248,36 @@
@override
WorldImpact registerUsedElement(MemberEntity member) {
WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl();
- _mirrorsDataBuilder.registerUsedMember(member);
_customElementsAnalysis.registerStaticUse(member);
- if (member.isFunction && member.isInstanceMember) {
- FunctionEntity method = member;
- ClassEntity cls = method.enclosingClass;
+ if (member.isFunction) {
+ FunctionEntity function = member;
+ if (function.isExternal) {
+ FunctionType functionType =
+ _elementEnvironment.getFunctionType(function);
- if (method.name == Identifiers.call &&
- _elementEnvironment.isGenericClass(cls)) {
- worldImpact.addImpact(_registerComputeSignature());
+ var allParameterTypes = <DartType>[]
+ ..addAll(functionType.parameterTypes)
+ ..addAll(functionType.optionalParameterTypes)
+ ..addAll(functionType.namedParameterTypes);
+ for (var type in allParameterTypes) {
+ if (type.isFunctionType || type.isTypedef) {
+ var closureConverter = _commonElements.closureConverter;
+ worldImpact.registerStaticUse(
+ new StaticUse.implicitInvoke(closureConverter));
+ _backendUsage.registerBackendFunctionUse(closureConverter);
+ _backendUsage.registerGlobalFunctionDependency(closureConverter);
+ break;
+ }
+ }
+ }
+ if (function.isInstanceMember) {
+ ClassEntity cls = function.enclosingClass;
+
+ if (function.name == Identifiers.call &&
+ _elementEnvironment.isGenericClass(cls)) {
+ worldImpact.addImpact(_registerComputeSignature());
+ }
}
}
_backendUsage.registerUsedMember(member);
@@ -304,9 +312,6 @@
WorldImpact _processClass(ClassEntity cls) {
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
- if (_elementEnvironment.isGenericClass(cls)) {
- _typeVariableResolutionAnalysis.registerClassWithTypeVariables(cls);
- }
// TODO(johnniwinther): Extract an `implementationClassesOf(...)` function
// for these into [CommonElements] or [BackendImpacts].
// Register any helper that will be needed by the backend.
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index ab2f509..2364c42 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -6,15 +6,8 @@
import '../common/names.dart' show Identifiers;
import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../elements/elements.dart' show ClassElement;
import '../elements/entities.dart';
import '../elements/names.dart';
-import '../elements/resolution_types.dart'
- show
- MalformedType,
- MethodTypeVariableType,
- ResolutionDartTypeVisitor,
- ResolutionTypedefType;
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
@@ -39,7 +32,7 @@
}
typedef jsAst.Expression OnVariableCallback(TypeVariableType variable);
-typedef bool ShouldEncodeTypedefCallback(ResolutionTypedefType variable);
+typedef bool ShouldEncodeTypedefCallback(TypedefType variable);
/// Interface for the classes and methods that need runtime types.
abstract class RuntimeTypesNeed {
@@ -758,29 +751,6 @@
}
}
-class _ResolutionRuntimeTypesNeed extends RuntimeTypesNeedImpl {
- _ResolutionRuntimeTypesNeed(
- ElementEnvironment elementEnvironment,
- BackendUsage backendUsage,
- Set<ClassEntity> classesNeedingTypeArguments,
- Set<FunctionEntity> methodsNeedingSignature,
- Set<FunctionEntity> methodsNeedingTypeArguments,
- Set<Local> localFunctionsNeedingSignature,
- Set<Local> localFunctionsNeedingTypeArguments,
- Set<Selector> selectorsNeedingTypeArguments)
- : super(
- elementEnvironment,
- backendUsage,
- classesNeedingTypeArguments,
- methodsNeedingSignature,
- methodsNeedingTypeArguments,
- localFunctionsNeedingSignature,
- localFunctionsNeedingTypeArguments,
- selectorsNeedingTypeArguments);
-
- bool checkClass(ClassElement cls) => cls.isDeclaration;
-}
-
class TypeVariableTests {
List<RtiNode> _nodes = <RtiNode>[];
Map<ClassEntity, ClassNode> _classes = <ClassEntity, ClassNode>{};
@@ -1369,8 +1339,6 @@
RuntimeTypesNeedBuilderImpl(this._elementEnvironment, DartTypes types)
: super(types);
- bool checkClass(covariant ClassEntity cls) => true;
-
@override
void registerClassUsingTypeVariableLiteral(ClassEntity cls) {
classesUsingTypeVariableLiterals.add(cls);
@@ -1417,7 +1385,6 @@
processedEntities.add(entity);
if (entity is ClassEntity) {
ClassEntity cls = entity;
- assert(checkClass(cls));
if (!_elementEnvironment.isGenericClass(cls)) return;
if (classesNeedingTypeArguments.contains(cls)) return;
classesNeedingTypeArguments.add(cls);
@@ -1636,35 +1603,6 @@
}
}
-class ResolutionRuntimeTypesNeedBuilderImpl
- extends RuntimeTypesNeedBuilderImpl {
- ResolutionRuntimeTypesNeedBuilderImpl(
- ElementEnvironment elementEnvironment, DartTypes types)
- : super(elementEnvironment, types);
-
- bool checkClass(ClassElement cls) => cls.isDeclaration;
-
- RuntimeTypesNeed _createRuntimeTypesNeed(
- ElementEnvironment elementEnvironment,
- BackendUsage backendUsage,
- Set<ClassEntity> classesNeedingTypeArguments,
- Set<FunctionEntity> methodsNeedingSignature,
- Set<FunctionEntity> methodsNeedingTypeArguments,
- Set<Local> localFunctionsNeedingSignature,
- Set<Local> localFunctionsNeedingTypeArguments,
- Set<Selector> selectorsNeedingTypeArguments) {
- return new _ResolutionRuntimeTypesNeed(
- _elementEnvironment,
- backendUsage,
- classesNeedingTypeArguments,
- methodsNeedingSignature,
- methodsNeedingTypeArguments,
- localFunctionsNeedingSignature,
- localFunctionsNeedingTypeArguments,
- selectorsNeedingTypeArguments);
- }
-}
-
class _RuntimeTypesChecks implements RuntimeTypesChecks {
final RuntimeTypesSubstitutions _substitutions;
final TypeChecks requiredChecks;
@@ -2105,7 +2043,7 @@
}
class TypeRepresentationGenerator
- implements ResolutionDartTypeVisitor<jsAst.Expression, Emitter> {
+ implements DartTypeVisitor<jsAst.Expression, Emitter> {
final Namer namer;
final NativeBasicData _nativeData;
// If true, compile using strong mode.
@@ -2129,9 +2067,8 @@
ShouldEncodeTypedefCallback encodeTypedef) {
assert(typedefBindings == null);
this.onVariable = onVariable;
- this.shouldEncodeTypedef = (encodeTypedef != null)
- ? encodeTypedef
- : (ResolutionTypedefType type) => false;
+ this.shouldEncodeTypedef =
+ (encodeTypedef != null) ? encodeTypedef : (TypedefType type) => false;
jsAst.Expression representation = visit(type, emitter);
this.onVariable = null;
this.shouldEncodeTypedef = null;
@@ -2302,17 +2239,11 @@
return new jsAst.ObjectInitializer(properties);
}
- jsAst.Expression visitMalformedType(MalformedType type, Emitter emitter) {
- // Treat malformed types as dynamic at runtime.
- return getDynamicValue();
- }
-
jsAst.Expression visitVoidType(VoidType type, Emitter emitter) {
return _strongMode ? getVoidValue() : getDynamicValue();
}
- jsAst.Expression visitTypedefType(
- ResolutionTypedefType type, Emitter emitter) {
+ jsAst.Expression visitTypedefType(TypedefType type, Emitter emitter) {
bool shouldEncode = shouldEncodeTypedef(type);
DartType unaliasedType = type.unaliased;
@@ -2340,9 +2271,7 @@
// inputs to correspond to type variables AND typedefs.
typedefBindings = <TypeVariableType, jsAst.Expression>{};
type.forEachTypeVariable((TypeVariableType variable) {
- if (variable is! MethodTypeVariableType) {
- typedefBindings[variable] = onVariable(variable);
- }
+ typedefBindings[variable] = onVariable(variable);
});
}
@@ -2412,7 +2341,7 @@
}
}
-class ArgumentCollector extends ResolutionDartTypeVisitor<dynamic, bool> {
+class ArgumentCollector extends DartTypeVisitor<dynamic, bool> {
final Set<ClassEntity> classes = new Set<ClassEntity>();
void addClass(ClassEntity cls) {
@@ -2431,7 +2360,7 @@
}
}
- visitTypedefType(ResolutionTypedefType type, bool isTypeArgument) {
+ visitTypedefType(TypedefType type, bool isTypeArgument) {
collect(type.unaliased, isTypeArgument: isTypeArgument);
}
@@ -2448,8 +2377,7 @@
}
}
-class FunctionArgumentCollector
- extends ResolutionDartTypeVisitor<dynamic, bool> {
+class FunctionArgumentCollector extends DartTypeVisitor<dynamic, bool> {
final Set<ClassEntity> classes = new Set<ClassEntity>();
FunctionArgumentCollector();
@@ -2464,7 +2392,7 @@
}
}
- visitTypedefType(ResolutionTypedefType type, bool inFunctionType) {
+ visitTypedefType(TypedefType type, bool inFunctionType) {
collect(type.unaliased, inFunctionType: inFunctionType);
}
@@ -2547,7 +2475,7 @@
'TypeCheck(cls=$cls,needsIs=$needsIs,substitution=$substitution)';
}
-class TypeVisitor extends ResolutionDartTypeVisitor<void, bool> {
+class TypeVisitor extends DartTypeVisitor<void, bool> {
Set<FunctionTypeVariable> _visitedFunctionTypeVariables =
new Set<FunctionTypeVariable>();
diff --git a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
deleted file mode 100644
index 81a3f76..0000000
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import '../common_elements.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../deferred_load.dart' show OutputUnit;
-import '../elements/entities.dart';
-import '../elements/types.dart';
-import '../js/js.dart' as jsAst;
-import '../js_emitter/js_emitter.dart'
- show CodeEmitterTask, MetadataCollector, Placeholder;
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/use.dart' show ConstantUse;
-import '../universe/world_impact.dart';
-import 'backend.dart';
-import 'backend_usage.dart' show BackendUsageBuilder;
-import 'backend_impact.dart';
-import 'mirrors_data.dart';
-
-/// Resolution analysis that prepares for the construction of TypeVariable
-/// constants needed at runtime.
-class TypeVariableResolutionAnalysis {
- final ElementEnvironment _elementEnvironment;
- final BackendImpacts _impacts;
- final BackendUsageBuilder _backendUsageBuilder;
-
- /**
- * Set to 'true' on first encounter of a class with type variables.
- */
- bool _seenClassesWithTypeVariables = false;
-
- /// Impact builder used for the resolution world computation.
- final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
-
- TypeVariableResolutionAnalysis(
- this._elementEnvironment, this._impacts, this._backendUsageBuilder);
-
- /// Compute the [WorldImpact] for the type variables registered since last
- /// flush.
- WorldImpact flush() {
- return impactBuilder.flush();
- }
-
- void registerClassWithTypeVariables(ClassEntity cls) {
- // On first encounter, we have to ensure that the support classes get
- // resolved.
- if (!_seenClassesWithTypeVariables) {
- _impacts.typeVariableMirror
- .registerImpact(impactBuilder, _elementEnvironment);
- _backendUsageBuilder.processBackendImpact(_impacts.typeVariableMirror);
- _seenClassesWithTypeVariables = true;
- }
- }
-}
-
-/// Codegen handler that creates TypeVariable constants needed at runtime.
-class TypeVariableCodegenAnalysis {
- final ElementEnvironment _elementEnvironment;
- final JavaScriptBackend _backend;
- final CommonElements _commonElements;
- final MirrorsData _mirrorsData;
-
- /**
- * Maps a class element to a list with indices that point to type variables
- * constants for each of the class' type variables.
- */
- Map<ClassEntity, List<jsAst.Expression>> _typeVariables =
- new Map<ClassEntity, List<jsAst.Expression>>();
-
- /**
- * Maps a TypeVariableType to the index pointing to the constant representing
- * the corresponding type variable at runtime.
- */
- Map<TypeVariableEntity, jsAst.Expression> _typeVariableConstants =
- new Map<TypeVariableEntity, jsAst.Expression>();
-
- /// Impact builder used for the codegen world computation.
- final StagedWorldImpactBuilder _impactBuilder =
- new StagedWorldImpactBuilder();
-
- TypeVariableCodegenAnalysis(this._elementEnvironment, this._backend,
- this._commonElements, this._mirrorsData);
-
- CodeEmitterTask get _task => _backend.emitter;
- MetadataCollector get _metadataCollector => _task.metadataCollector;
-
- /// Compute the [WorldImpact] for the type variables registered since last
- /// flush.
- WorldImpact flush() {
- return _impactBuilder.flush();
- }
-
- void registerClassWithTypeVariables(ClassEntity cls) {
- if (_mirrorsData.isClassAccessibleByReflection(cls)) {
- processTypeVariablesOf(cls);
- }
- }
-
- void processTypeVariablesOf(ClassEntity cls) {
- // Do not process classes twice.
- if (_typeVariables.containsKey(cls)) return;
-
- List<jsAst.Expression> constants = <jsAst.Expression>[];
-
- InterfaceType thisType = _elementEnvironment.getThisType(cls);
- for (TypeVariableType currentTypeVariable in thisType.typeArguments) {
- TypeVariableEntity typeVariableElement = currentTypeVariable.element;
-
- // TODO(sigmund): use output unit for `cls` (Issue #31032)
- OutputUnit outputUnit = _backend.outputUnitData.mainOutputUnit;
- jsAst.Expression boundIndex = _metadataCollector.reifyType(
- _elementEnvironment.getTypeVariableBound(typeVariableElement),
- outputUnit);
- ConstantValue boundValue = new SyntheticConstantValue(
- SyntheticConstantKind.TYPEVARIABLE_REFERENCE, boundIndex);
- ClassEntity typeVariableClass = _commonElements.typeVariableClass;
- ConstantExpression constant = new ConstructedConstantExpression(
- _elementEnvironment.getThisType(typeVariableClass),
- _commonElements.typeVariableConstructor,
- const CallStructure.unnamed(3), [
- new TypeConstantExpression(
- _elementEnvironment.getRawType(cls), cls.name),
- new StringConstantExpression(typeVariableElement.name),
- new SyntheticConstantExpression(boundValue)
- ]);
-
- _backend.constants.evaluate(constant);
- ConstantValue value = _backend.constants.getConstantValue(constant);
- _impactBuilder
- .registerConstantUse(new ConstantUse.typeVariableMirror(value));
- constants.add(_reifyTypeVariableConstant(
- value, currentTypeVariable.element, outputUnit));
- }
- _typeVariables[cls] = constants;
- }
-
- /**
- * Adds [c] to [emitter.metadataCollector] and returns the index pointing to
- * the entry.
- *
- * If the corresponding type variable has already been encountered an
- * entry in the list has already been reserved and the constant is added
- * there, otherwise a new entry for [c] is created.
- */
- jsAst.Expression _reifyTypeVariableConstant(
- ConstantValue c, TypeVariableEntity variable, OutputUnit outputUnit) {
- jsAst.Expression name = _task.constantReference(c);
- jsAst.Expression result =
- _metadataCollector.reifyExpression(name, outputUnit);
- if (_typeVariableConstants.containsKey(variable)) {
- Placeholder placeholder = _typeVariableConstants[variable];
- placeholder.bind(result);
- }
- _typeVariableConstants[variable] = result;
- return result;
- }
-
- /**
- * Returns the index pointing to the constant in [emitter.metadataCollector]
- * representing this type variable.
- *
- * If the constant has not yet been constructed, an entry is allocated in
- * the global metadata list and the index pointing to this entry is returned.
- * When the corresponding constant is constructed later,
- * [reifyTypeVariableConstant] will be called and the constant will be added
- * on the allocated entry.
- */
- jsAst.Expression reifyTypeVariable(TypeVariableEntity variable) {
- if (_typeVariableConstants.containsKey(variable)) {
- return _typeVariableConstants[variable];
- }
-
- Placeholder placeholder =
- _metadataCollector.getMetadataPlaceholder(variable);
- return _typeVariableConstants[variable] = placeholder;
- }
-
- List<jsAst.Expression> typeVariablesOf(ClassEntity classElement) {
- List<jsAst.Expression> result = _typeVariables[classElement];
- if (result == null) {
- result = const <jsAst.Expression>[];
- }
- return result;
- }
-}
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 003771e..00bfaf7 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -150,8 +150,8 @@
// 'is$' method.
typeTestRegistry.computeRequiredTypeChecks(backend.rtiChecksBuilder);
// Compute the classes needed by RTI.
- typeTestRegistry.computeRtiNeededClasses(backend.rtiSubstitutions,
- backend.mirrorsData, backend.generatedCode.keys);
+ typeTestRegistry.computeRtiNeededClasses(
+ backend.rtiSubstitutions, backend.generatedCode.keys);
}
/// Creates the [Emitter] for this task.
@@ -162,17 +162,10 @@
backend.nativeCodegenEnqueuer);
_emitter =
_emitterFactory.createEmitter(this, namer, closedWorld, sorter);
- metadataCollector = new MetadataCollector(
- compiler.options,
- compiler.reporter,
- _emitter,
- backend.constants,
- backend.typeVariableCodegenAnalysis,
- backend.mirrorsData,
- backend.rtiEncoder,
- codegenWorldBuilder);
+ metadataCollector = new MetadataCollector(compiler.options,
+ compiler.reporter, _emitter, backend.rtiEncoder, codegenWorldBuilder);
typeTestRegistry = new TypeTestRegistry(compiler.options,
- codegenWorldBuilder, closedWorld, closedWorld.elementEnvironment);
+ codegenWorldBuilder, closedWorld.elementEnvironment);
});
}
@@ -194,7 +187,6 @@
backend.constants,
closedWorld.nativeData,
closedWorld.rtiNeed,
- backend.mirrorsData,
closedWorld.interceptorData,
backend.superMemberData,
typeTestRegistry.rtiChecks,
@@ -209,8 +201,7 @@
backend.sourceInformationStrategy,
compiler.backendStrategy.sorter,
typeTestRegistry.rtiNeededClasses,
- closedWorld.elementEnvironment.mainFunction,
- isMockCompilation: compiler.isMockCompilation);
+ closedWorld.elementEnvironment.mainFunction);
int size = emitter.emitProgram(programBuilder);
// TODO(floitsch): we shouldn't need the `neededClasses` anymore.
neededClasses = programBuilder.collector.neededClasses;
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index fcd705d..da2cc06 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -5,15 +5,8 @@
library dart2js.js_emitter.constant_ordering;
import '../constants/values.dart';
-import '../elements/elements.dart' show Elements;
import '../elements/entities.dart'
- show Entity, ClassEntity, FieldEntity, MemberEntity, TypedefEntity;
-import '../elements/resolution_types.dart'
- show
- GenericType,
- ResolutionDartType,
- ResolutionFunctionType,
- ResolutionTypeKind;
+ show ClassEntity, FieldEntity, LibraryEntity, MemberEntity, TypedefEntity;
import '../elements/types.dart';
import '../js_backend/js_backend.dart' show SyntheticConstantKind;
import 'sorter.dart' show Sorter;
@@ -60,10 +53,8 @@
return 0;
}
- static int compareElements(Entity a, Entity b) {
- int r = a.name.compareTo(b.name);
- if (r != 0) return r;
- return Elements.compareByPosition(a, b);
+ int compareLibraries(LibraryEntity a, LibraryEntity b) {
+ return _sorter.compareLibrariesByLocation(a, b);
}
int compareClasses(ClassEntity a, ClassEntity b) {
@@ -84,45 +75,7 @@
return _sorter.compareTypedefsByLocation(a, b);
}
- static int _compareResolutionDartTypes(
- ResolutionDartType a, ResolutionDartType 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(_compareResolutionDartTypes, aGeneric.typeArguments,
- bGeneric.typeArguments);
- if (r != 0) return r;
- }
- if (a is ResolutionFunctionType && b is ResolutionFunctionType) {
- int r = compareLists(
- _compareResolutionDartTypes, a.parameterTypes, b.parameterTypes);
- if (r != 0) return r;
- r = compareLists(_compareResolutionDartTypes, a.optionalParameterTypes,
- b.optionalParameterTypes);
- if (r != 0) return r;
- r = _ConstantOrdering.compareLists((String a, String b) => a.compareTo(b),
- a.namedParameters, b.namedParameters);
- if (r != 0) return r;
- r = compareLists(_compareResolutionDartTypes, a.namedParameterTypes,
- b.namedParameterTypes);
- if (r != 0) return r;
- return _compareResolutionDartTypes(a.returnType, b.returnType);
- }
-
- throw 'unexpected compareDartTypes $a $b';
- }
-
int compareDartTypes(DartType a, DartType b) {
- if (a is ResolutionDartType && b is ResolutionDartType) {
- // TODO(redemption): Remove this path.
- return _compareResolutionDartTypes(a, b);
- }
return _dartTypeOrdering.compare(a, b);
}
@@ -230,8 +183,10 @@
int visitDeferred(DeferredConstantValue a, DeferredConstantValue b) {
int r = compareValues(a.referenced, b.referenced);
if (r != 0) return r;
- // TODO(sra): What kind of Entity is `prefix`?
- return compareElements(a.import, b.import);
+ r = a.import.name.compareTo(b.import.name);
+ if (r != 0) return r;
+ return compareLibraries(
+ a.import.enclosingLibrary, b.import.enclosingLibrary);
}
int visitDeferredGlobal(
@@ -295,7 +250,6 @@
const _DartTypeKindVisitor();
static int kind(DartType type) {
- assert(_usesLegacyOrder);
return type.accept(const _DartTypeKindVisitor(), null);
}
@@ -305,24 +259,6 @@
int visitInterfaceType(covariant InterfaceType type, _) => 1;
int visitTypedefType(covariant TypedefType type, _) => 2;
int visitDynamicType(covariant DynamicType type, _) => 5;
-
- // Check that the ordering of different kinds of type is consistent with
- // ResolutionDartTypes.
- // TODO(redemption): Remove this check.
- static bool _usesLegacyOrder = () {
- var v = const _DartTypeKindVisitor();
- assert(
- v.visitFunctionType(null, null) == ResolutionTypeKind.FUNCTION.index);
- assert(
- v.visitInterfaceType(null, null) == ResolutionTypeKind.INTERFACE.index);
- assert(v.visitTypedefType(null, null) == ResolutionTypeKind.TYPEDEF.index);
- assert(v.visitTypeVariableType(null, null) ==
- ResolutionTypeKind.TYPE_VARIABLE.index);
- // There is no analogue of ResolutionTypeKind.MALFORMED_TYPE.
- assert(v.visitDynamicType(null, null) == ResolutionTypeKind.DYNAMIC.index);
- assert(v.visitVoidType(null, null) == ResolutionTypeKind.VOID.index);
- return true;
- }();
}
class _DartTypeOrdering extends DartTypeVisitor<int, DartType> {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index f9a75b1..ee51d11 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -7,15 +7,11 @@
import '../../common.dart';
import '../../common/names.dart' show Names;
import '../../common_elements.dart';
-import '../../elements/resolution_types.dart' show ResolutionDartType;
import '../../deferred_load.dart' show OutputUnit;
-import '../../elements/elements.dart' show ClassElement, FieldElement;
import '../../elements/entities.dart';
import '../../js/js.dart' as jsAst;
import '../../js/js.dart' show js;
import '../../js_backend/js_backend.dart' show CompoundName, Namer;
-import '../../universe/selector.dart' show Selector;
-import '../../util/util.dart' show equalElements;
import '../../world.dart' show ClosedWorld;
import '../js_emitter.dart' hide Emitter, EmitterFactory;
import '../model.dart';
@@ -38,9 +34,6 @@
void emitClass(Class cls, ClassBuilder enclosingBuilder, Fragment fragment) {
ClassEntity classElement = cls.element;
- assert(!(classElement is ClassElement && !classElement.isDeclaration),
- failedAt(classElement));
-
emitter.needsClassSupport = true;
ClassEntity superclass = _elementEnvironment.getSuperClass(classElement);
@@ -123,8 +116,6 @@
fields = container.staticFieldsForReflection;
}
- var fieldMetadata = <jsAst.Expression>[];
- bool hasMetadata = false;
bool fieldsAdded = false;
for (Field field in fields) {
@@ -142,16 +133,6 @@
// accessors at runtime.
bool needsFieldsForConstructor = !emitStatics && !classIsNative;
if (needsFieldsForConstructor || needsAccessor) {
- dynamic metadata =
- task.metadataCollector.buildFieldMetadataFunction(fieldElement);
- if (metadata != null) {
- hasMetadata = true;
- } else {
- metadata = new jsAst.LiteralNull();
- }
- fieldMetadata.add(metadata);
- recordMangledField(fieldElement, accessorName,
- namer.privateName(fieldElement.memberName));
List<jsAst.Literal> fieldNameParts = <jsAst.Literal>[];
if (!needsAccessor) {
// Emit field for constructor generation.
@@ -185,26 +166,6 @@
fieldNameParts.add(
js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]));
}
- // Fields can only be reflected if their declaring class is reflectable
- // (as they are only accessible via [ClassMirror.declarations]).
- // However, set/get operations can be performed on them, so they are
- // reflectable in some sense, which leads to [isAccessibleByReflection]
- // reporting `true`.
- if (backend.mirrorsData.isMemberAccessibleByReflection(fieldElement)) {
- fieldNameParts.add(new jsAst.LiteralString('-'));
- if (fieldElement.isTopLevel ||
- backend.mirrorsData
- .isClassAccessibleByReflection(fieldElement.enclosingClass)) {
- // TODO(redemption): Support field entities.
- FieldElement element = fieldElement;
- ResolutionDartType type = element.type;
- // TODO(sigmund): use output unit for `element` (Issue #31032)
- OutputUnit outputUnit =
- compiler.backend.outputUnitData.mainOutputUnit;
- fieldNameParts
- .add(task.metadataCollector.reifyType(type, outputUnit));
- }
- }
jsAst.Literal fieldNameAst = js.concatenateStrings(fieldNameParts);
builder.addField(fieldNameAst);
// Add 1 because adding a field to the class also requires a comma
@@ -213,9 +174,6 @@
}
}
- if (hasMetadata) {
- builder.fieldMetadata = fieldMetadata;
- }
return fieldsAdded;
}
@@ -230,8 +188,6 @@
jsAst.Name setterName = method.name;
compiler.dumpInfoTask
.registerEntityAst(member, builder.addProperty(setterName, code));
- generateReflectionDataForFieldGetterOrSetter(member, setterName, builder,
- isGetter: false);
}
}
@@ -266,8 +222,6 @@
*/
void emitInstanceMembers(Class cls, ClassBuilder builder) {
ClassEntity classElement = cls.element;
- assert(!(classElement is ClassElement && !classElement.isDeclaration),
- failedAt(classElement));
if (cls.onlyForRti || cls.isMixinApplication) return;
@@ -315,28 +269,6 @@
ClassEntity classEntity = cls.element;
jsAst.Name className = cls.name;
- var metadata =
- task.metadataCollector.buildClassMetadataFunction(classEntity);
- if (metadata != null) {
- classBuilder.addPropertyByName("@", metadata);
- }
-
- if (backend.mirrorsData.isClassAccessibleByReflection(classEntity)) {
- // TODO(redemption): Handle class entities.
- ClassElement classElement = classEntity;
- List<ResolutionDartType> typeVars = classElement.typeVariables;
- Iterable typeVariableProperties =
- emitter.typeVariableCodegenAnalysis.typeVariablesOf(classElement);
-
- ClassElement superclass = classElement.superclass;
- bool hasSuper = superclass != null;
- if ((!typeVariableProperties.isEmpty && !hasSuper) ||
- (hasSuper && !equalElements(superclass.typeVariables, typeVars))) {
- classBuilder.addPropertyByName(
- '<>', new jsAst.ArrayInitializer(typeVariableProperties.toList()));
- }
- }
-
List<jsAst.Property> statics = new List<jsAst.Property>();
ClassBuilder staticsBuilder =
new ClassBuilder.forStatics(classEntity, namer);
@@ -371,45 +303,11 @@
String reflectionName =
emitter.getReflectionClassName(classEntity, className);
if (reflectionName != null) {
- if (!backend.mirrorsData.isClassAccessibleByReflection(classEntity) ||
- cls.onlyForRti) {
- // TODO(herhut): Fix use of reflection name here.
- enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0));
- } else {
- // TODO(sigmund): use output unit for `classEntity` (Issue #31032)
- OutputUnit outputUnit = compiler.backend.outputUnitData.mainOutputUnit;
- // TODO(redemption): Handle class entities.
- ClassElement classElement = classEntity;
- List<jsAst.Expression> types = <jsAst.Expression>[];
- if (classElement.supertype != null) {
- types.add(task.metadataCollector
- .reifyType(classElement.supertype, outputUnit));
- }
- for (ResolutionDartType interface in classElement.interfaces) {
- types.add(task.metadataCollector.reifyType(interface, outputUnit));
- }
- // TODO(herhut): Fix use of reflection name here.
- enclosingBuilder.addPropertyByName(
- "+$reflectionName", new jsAst.ArrayInitializer(types));
- }
+ // TODO(herhut): Fix use of reflection name here.
+ enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0));
}
}
- void recordMangledField(
- FieldEntity member, jsAst.Name accessorName, String memberName) {
- if (!backend.mirrorsData.shouldRetainGetter(member)) return;
- String previousName;
- if (member.isInstanceMember) {
- previousName = emitter.mangledFieldNames
- .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName);
- } else {
- previousName = emitter.mangledGlobalFieldNames
- .putIfAbsent(accessorName, () => memberName);
- }
- assert(previousName == memberName,
- failedAt(member, '$previousName != ${memberName}'));
- }
-
void emitGetterForCSP(FieldEntity member, jsAst.Name fieldName,
jsAst.Name accessorName, ClassBuilder builder) {
jsAst.Expression function =
@@ -423,11 +321,6 @@
emitter
.cspPrecompiledFunctionFor(outputUnit)
.add(js('#.prototype.# = #', [className, getterName, function]));
- if (backend.mirrorsData.isMemberAccessibleByReflection(member)) {
- emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
- '#.prototype.#.${namer.reflectableField} = 1',
- [className, getterName]));
- }
}
void emitSetterForCSP(FieldEntity member, jsAst.Name fieldName,
@@ -443,26 +336,5 @@
emitter
.cspPrecompiledFunctionFor(outputUnit)
.add(js('#.prototype.# = #', [className, setterName, function]));
- if (backend.mirrorsData.isMemberAccessibleByReflection(member)) {
- emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
- '#.prototype.#.${namer.reflectableField} = 1',
- [className, setterName]));
- }
- }
-
- void generateReflectionDataForFieldGetterOrSetter(
- MemberEntity member, jsAst.Name name, ClassBuilder builder,
- {bool isGetter}) {
- Selector selector = isGetter
- ? new Selector.getter(member.memberName.getter)
- : new Selector.setter(member.memberName.setter);
- String reflectionName = emitter.getReflectionSelectorName(selector, name);
- if (reflectionName != null) {
- var reflectable = js(
- backend.mirrorsData.isMemberAccessibleByReflection(member)
- ? '1'
- : '0');
- builder.addPropertyByName('+$reflectionName', reflectable);
- }
}
}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
index 2ded0af..144f886 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
@@ -4,12 +4,8 @@
library dart2js.js_emitter.full_emitter.container_builder;
-import '../../constants/values.dart';
import '../../deferred_load.dart' show OutputUnit;
-import '../../elements/elements.dart'
- show Element, MetadataAnnotation, MethodElement;
import '../../elements/entities.dart';
-import '../../elements/entity_utils.dart' as utils;
import '../../elements/names.dart';
import '../../js/js.dart' as jsAst;
import '../../js/js.dart' show js;
@@ -32,15 +28,13 @@
jsAst.Expression code = method.code;
bool needsStubs = method.parameterStubs.isNotEmpty;
bool canBeApplied = method.canBeApplied;
- bool canBeReflected = method.canBeReflected;
bool canTearOff = method.needsTearOff;
jsAst.Name tearOffName = method.tearOffName;
bool isClosure = method is InstanceMethod && method.isClosureCallMethod;
jsAst.Name superAlias = method is InstanceMethod ? method.aliasName : null;
bool hasSuperAlias = superAlias != null;
jsAst.Expression memberTypeExpression = method.functionType;
- bool needStructuredInfo =
- canTearOff || canBeReflected || canBeApplied || hasSuperAlias;
+ bool needStructuredInfo = canTearOff || canBeApplied || hasSuperAlias;
bool isIntercepted = false;
if (method is InstanceMethod) {
@@ -102,8 +96,7 @@
expressions.add(code);
- bool onlyNeedsSuperAlias =
- !(canTearOff || canBeReflected || canBeApplied || needsStubs);
+ bool onlyNeedsSuperAlias = !(canTearOff || canBeApplied || needsStubs);
if (onlyNeedsSuperAlias) {
jsAst.ArrayInitializer arrayInit =
@@ -155,50 +148,16 @@
..add(js.number(optionalParameterCount))
..add(memberTypeExpression == null ? js("null") : memberTypeExpression);
- if (canBeReflected || canBeApplied) {
+ if (canBeApplied) {
expressions.addAll(
task.metadataCollector.reifyDefaultArguments(member, outputUnit));
- if (member is MethodElement) {
- member.functionSignature.forEachParameter((Element parameter) {
- expressions.add(
- task.metadataCollector.reifyName(parameter.name, outputUnit));
- if (backend.mirrorsData.mustRetainMetadata) {
- Iterable<jsAst.Expression> metadataIndices =
- parameter.metadata.map((MetadataAnnotation annotation) {
- ConstantValue constant =
- backend.constants.getConstantValueForMetadata(annotation);
- codegenWorldBuilder.addCompileTimeConstantForEmission(constant);
- return task.metadataCollector
- .reifyMetadata(annotation, outputUnit);
- });
- expressions
- .add(new jsAst.ArrayInitializer(metadataIndices.toList()));
- }
- });
- } else {
- codegenWorldBuilder.forEachParameter(member, (_, String name, _2) {
- expressions.add(task.metadataCollector.reifyName(name, outputUnit));
- });
- // TODO(redemption): Support retaining mirrors metadata.
- }
+ codegenWorldBuilder.forEachParameter(member, (_, String name, _2) {
+ expressions.add(task.metadataCollector.reifyName(name, outputUnit));
+ });
}
Name memberName = member.memberName;
- if (canBeReflected) {
- jsAst.LiteralString reflectionName;
- if (member.isConstructor) {
- // TODO(herhut): This registers name as a mangled name. Do we need this
- // given that we use a different name below?
- emitter.getReflectionMemberName(member, name);
- reflectionName = new jsAst.LiteralString(
- '"new ${utils.reconstructConstructorName(member)}"');
- } else {
- reflectionName = js.string(namer.privateName(memberName));
- }
- expressions
- ..add(reflectionName)
- ..addAll(task.metadataCollector.computeMetadata(member, outputUnit));
- } else if (isClosure && canBeApplied) {
+ if (isClosure && canBeApplied) {
expressions.add(js.string(namer.privateName(memberName)));
}
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 e333f45..bdc35cd 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -4,7 +4,6 @@
library dart2js.js_emitter.full_emitter;
-import 'dart:collection' show HashMap;
import 'dart:convert';
import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
@@ -18,9 +17,6 @@
import '../../common_elements.dart' show CommonElements, ElementEnvironment;
import '../../deferred_load.dart' show OutputUnit, OutputUnitData;
import '../../elements/entities.dart';
-import '../../elements/entity_utils.dart' as utils;
-import '../../elements/types.dart';
-import '../../elements/names.dart';
import '../../hash/sha1.dart' show Hasher;
import '../../io/code_output.dart';
import '../../io/location_provider.dart' show LocationCollector;
@@ -28,15 +24,9 @@
import '../../js/js.dart' as jsAst;
import '../../js/js.dart' show js;
import '../../js_backend/js_backend.dart'
- show
- ConstantEmitter,
- JavaScriptBackend,
- Namer,
- SetterName,
- TypeVariableCodegenAnalysis;
+ show ConstantEmitter, JavaScriptBackend, Namer;
import '../../js_backend/native_data.dart';
import '../../universe/call_structure.dart' show CallStructure;
-import '../../universe/selector.dart' show Selector;
import '../../universe/world_builder.dart' show CodegenWorldBuilder;
import '../../util/uri_extras.dart' show relativize;
import '../../world.dart' show ClosedWorld;
@@ -90,7 +80,6 @@
// collector.
Map<OutputUnit, List<FieldEntity>> outputStaticNonFinalFieldLists;
Map<OutputUnit, Set<LibraryEntity>> outputLibraryLists;
- List<TypedefEntity> typedefsNeededForReflection;
final ContainerBuilder containerBuilder;
final ClassEmitter classEmitter;
@@ -124,15 +113,8 @@
Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>();
String classesCollector;
- final Map<jsAst.Name, String> mangledFieldNames =
- new HashMap<jsAst.Name, String>();
- final Map<jsAst.Name, String> mangledGlobalFieldNames =
- new HashMap<jsAst.Name, String>();
- final Set<jsAst.Name> recordedMangledNames = new Set<jsAst.Name>();
JavaScriptBackend get backend => compiler.backend;
- TypeVariableCodegenAnalysis get typeVariableCodegenAnalysis =>
- backend.typeVariableCodegenAnalysis;
String get _ => space;
String get space => compiler.options.enableMinification ? "" : " ";
@@ -416,156 +398,17 @@
/// An anonymous mixin application has no reflection name.
///
/// This is used by js_mirrors.dart.
+ // TODO(johnniwinther): Do we still need this when js_mirrors is deleted?
String getReflectionClassName(ClassEntity cls, jsAst.Name mangledName) {
- String name = cls.name;
- if (backend.mirrorsData.shouldRetainName(name) ||
- // Make sure to retain names of common native types.
- _isNativeTypeNeedingReflectionName(cls)) {
- // TODO(ahe): Enable the next line when I can tell the difference between
- // an instance method and a global. They may have the same mangled name.
- // if (recordedMangledNames.contains(mangledName)) return null;
- recordedMangledNames.add(mangledName);
- if (cls.isClosure) {
- // Closures are synthesized and their name might conflict with existing
- // globals. Assign an illegal name, and make sure they don't clash
- // with each other.
- return " $name";
- }
- if (_elementEnvironment.isUnnamedMixinApplication(cls)) return null;
+ // Make sure to retain names of common native types.
+ if (_isNativeTypeNeedingReflectionName(cls)) {
+ assert(!cls.isClosure);
+ assert(!_elementEnvironment.isUnnamedMixinApplication(cls));
return cls.name;
}
return null;
}
- /// Returns the "reflection name" of a [MemberEntity], if needed.
- ///
- /// The reflection name of a getter 'foo' is 'foo'.
- /// The reflection name of a setter 'foo' is 'foo='.
- /// The reflection name of a method 'foo' is 'foo:N:M:O', where N is the
- /// number of required arguments, M is the number of optional arguments, and
- /// O is the named arguments.
- /// The reflection name of a constructor is similar to a regular method but
- /// starts with 'new '.
- ///
- /// This is used by js_mirrors.dart.
- String getReflectionMemberName(MemberEntity member, jsAst.Name mangledName) {
- String name = member.name;
- if (backend.mirrorsData.shouldRetainName(name) ||
- // Make sure to retain names of unnamed constructors.
- (name == '' &&
- backend.mirrorsData.isMemberAccessibleByReflection(member))) {
- // TODO(ahe): Enable the next line when I can tell the difference between
- // an instance method and a global. They may have the same mangled name.
- // if (recordedMangledNames.contains(mangledName)) return null;
- recordedMangledNames.add(mangledName);
- return getReflectionMemberNameInternal(member, mangledName);
- }
- return null;
- }
-
- String getReflectionMemberNameInternal(
- MemberEntity member, jsAst.Name mangledName) {
- if (member is ConstructorBodyEntity) {
- return null;
- }
- if (member.isGetter) {
- return _getReflectionGetterName(member.memberName);
- } else if (member.isSetter) {
- return _getReflectionSetterName(member.memberName, mangledName);
- } else if (member.isConstructor) {
- ConstructorEntity constructor = member;
- String name = utils.reconstructConstructorName(constructor);
- return _getReflectionCallStructureName(
- name, constructor.parameterStructure.callStructure);
- } else if (member.isFunction) {
- FunctionEntity function = member;
- return _getReflectionFunctionName(
- member.memberName, function.parameterStructure.callStructure);
- }
- throw reporter.internalError(
- member, 'Do not know how to reflect on this $member.');
- }
-
- /// Returns the "reflection name" of a [Selector], if needed.
- ///
- /// The reflection name of a getter 'foo' is 'foo'.
- /// The reflection name of a setter 'foo' is 'foo='.
- /// The reflection name of a method 'foo' is 'foo:N:M:O', where N is the
- /// number of required arguments, M is the number of optional arguments, and
- /// O is the named arguments.
- ///
- /// This is used by js_mirrors.dart.
- String getReflectionSelectorName(Selector selector, jsAst.Name mangledName) {
- String name = selector.name;
- if (backend.mirrorsData.shouldRetainName(name)) {
- // TODO(ahe): Enable the next line when I can tell the difference between
- // an instance method and a global. They may have the same mangled name.
- // if (recordedMangledNames.contains(mangledName)) return null;
- recordedMangledNames.add(mangledName);
- if (selector.isGetter) {
- return _getReflectionGetterName(selector.memberName);
- } else if (selector.isSetter) {
- return _getReflectionSetterName(selector.memberName, mangledName);
- } else {
- return _getReflectionFunctionName(
- selector.memberName, selector.callStructure);
- }
- }
- return null;
- }
-
- /// Returns the "reflection name" of a [TypedefEntity], if needed.
- ///
- /// The reflection name of typedef 'F' is 'F'.
- ///
- /// This is used by js_mirrors.dart.
- String getReflectionTypedefName(
- TypedefEntity typedef, jsAst.Name mangledName) {
- String name = typedef.name;
- if (backend.mirrorsData.shouldRetainName(name)) {
- // TODO(ahe): Enable the next line when I can tell the difference between
- // an instance method and a global. They may have the same mangled name.
- // if (recordedMangledNames.contains(mangledName)) return null;
- recordedMangledNames.add(mangledName);
- return typedef.name;
- }
- return null;
- }
-
- String _getReflectionGetterName(Name memberName) {
- return namer.privateName(memberName);
- }
-
- String _getReflectionSetterName(Name memberName, jsAst.Name mangledName) {
- String name = namer.privateName(memberName);
- if (mangledName is! SetterName) return '$name=';
- SetterName setterName = mangledName;
- jsAst.Name base = setterName.base;
- jsAst.Name getter = namer.deriveGetterName(base);
- mangledFieldNames.putIfAbsent(getter, () => name);
- assert(mangledFieldNames[getter] == name);
- recordedMangledNames.add(getter);
- // TODO(karlklose,ahe): we do not actually need to store information
- // about the name of this setter in the output, but it is needed for
- // marking the function as invokable by reflection.
- return '$name=';
- }
-
- String _getReflectionFunctionName(
- Name memberName, CallStructure callStructure) {
- String name = namer.privateName(memberName);
- return _getReflectionCallStructureName(name, callStructure);
- }
-
- String _getReflectionCallStructureName(
- String name, CallStructure callStructure,
- {bool isConstructor: false}) {
- int positionalParameterCount = callStructure.positionalArgumentCount;
- String namedArguments = namedParametersAsReflectionNames(callStructure);
- String suffix = '$name:$positionalParameterCount$namedArguments';
- return isConstructor ? 'new $suffix' : suffix;
- }
-
String namedParametersAsReflectionNames(CallStructure structure) {
if (structure.isUnnamed) return '';
String names = structure.getOrderedNamedArguments().join(':');
@@ -810,8 +653,6 @@
}
buildMain(jsAst.Statement invokeMain) {
- if (compiler.isMockCompilation) return js.comment("Mock compilation");
-
List<jsAst.Statement> parts = <jsAst.Statement>[];
if (NativeGenerator
@@ -1057,13 +898,11 @@
}
}
- String libraryName = (!compiler.options.enableMinification ||
- backend.mirrorsData.mustRetainLibraryNames)
+ String libraryName = !compiler.options.enableMinification
? _elementEnvironment.getLibraryName(library)
: "";
- jsAst.Fun metadata =
- task.metadataCollector.buildLibraryMetadataFunction(library);
+ jsAst.Fun metadata = null;
ClassBuilder descriptor = libraryDescriptors[fragment][library];
@@ -1120,47 +959,6 @@
cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
}
- void assembleTypedefs(Program program) {
- Fragment mainFragment = program.mainFragment;
- OutputUnit mainOutputUnit = mainFragment.outputUnit;
-
- // Emit all required typedef declarations into the main output unit.
- // TODO(karlklose): unify required classes and typedefs to declarations
- // and have builders for each kind.
- for (TypedefEntity typedef in typedefsNeededForReflection) {
- LibraryEntity library = typedef.library;
- // TODO(karlklose): add a TypedefBuilder and move this code there.
- FunctionType type = _elementEnvironment.getFunctionTypeOfTypedef(typedef);
- // TODO(zarah): reify type variables once reflection on type arguments of
- // typedefs is supported.
- jsAst.Expression typeIndex = task.metadataCollector
- .reifyType(type, mainOutputUnit, ignoreTypeVariables: true);
- ClassBuilder builder = new ClassBuilder.forStatics(typedef, namer);
- builder.addPropertyByName(
- embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, typeIndex);
- builder.addPropertyByName(
- embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, js.boolean(true));
-
- // We can be pretty sure that the objectClass is initialized, since
- // typedefs are only emitted with reflection, which requires lots of
- // classes.
- assert(commonElements.objectClass != null);
- builder.superName = namer.className(commonElements.objectClass);
- jsAst.Node declaration = builder.toObjectInitializer();
- jsAst.Name mangledName = namer.globalPropertyNameForType(typedef);
- String reflectionName = getReflectionTypedefName(typedef, mangledName);
- getLibraryDescriptor(library, mainFragment)
- ..addProperty(mangledName, declaration)
- ..addPropertyByName("+$reflectionName", js.string(''));
- // Also emit a trivial constructor for CSP mode.
- jsAst.Name constructorName = mangledName;
- jsAst.Expression constructorAst = js('function() {}');
- List<jsAst.Name> fieldNames = [];
- assemblePrecompiledConstructor(
- mainOutputUnit, constructorName, constructorAst, fieldNames);
- }
- }
-
jsAst.Statement buildGlobalObjectSetup(bool isProgramSplit) {
List<jsAst.Statement> parts = <jsAst.Statement>[];
@@ -1246,39 +1044,6 @@
return new jsAst.Block(parts);
}
- jsAst.Statement buildMangledNames() {
- List<jsAst.Statement> parts = <jsAst.Statement>[];
-
- if (!mangledFieldNames.isEmpty) {
- List<jsAst.Name> keys = mangledFieldNames.keys.toList()..sort();
- var properties = [];
- for (jsAst.Name key in keys) {
- var value = js.string(mangledFieldNames[key]);
- properties.add(new jsAst.Property(key, value));
- }
-
- jsAst.Expression mangledNamesAccess =
- generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
- var map = new jsAst.ObjectInitializer(properties);
- parts.add(js.statement('# = #', [mangledNamesAccess, map]));
- }
-
- if (!mangledGlobalFieldNames.isEmpty) {
- List<jsAst.Name> keys = mangledGlobalFieldNames.keys.toList()..sort();
- List<jsAst.Property> properties = <jsAst.Property>[];
- for (jsAst.Name key in keys) {
- jsAst.Literal value = js.string(mangledGlobalFieldNames[key]);
- properties.add(new jsAst.Property(js.quoteName(key), value));
- }
- jsAst.Expression mangledGlobalNamesAccess =
- generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
- jsAst.ObjectInitializer map = new jsAst.ObjectInitializer(properties);
- parts.add(js.statement('# = #', [mangledGlobalNamesAccess, map]));
- }
-
- return new jsAst.Block(parts);
- }
-
void checkEverythingEmitted(
Map<ClassEntity, ClassBuilder> pendingClassBuilders) {
if (pendingClassBuilders == null) return;
@@ -1314,7 +1079,6 @@
assembleLibrary(library, fragment);
}
}
- assembleTypedefs(program);
}
jsAst.Statement buildDeferredHeader() {
@@ -1410,8 +1174,6 @@
init();
- #mangledNames;
-
#cspPrecompiledFunctions;
#setupProgram;
@@ -1479,7 +1241,6 @@
"isolatePropertiesName": js(isolatePropertiesName),
"initName": initName,
"functionThatReturnsNull": buildFunctionThatReturnsNull(),
- "mangledNames": buildMangledNames(),
"setupProgram": buildSetupProgram(
program, compiler, backend, namer, this, _closedWorld),
"setupProgramName": setupProgramName,
@@ -1598,8 +1359,6 @@
outputStaticNonFinalFieldLists =
programBuilder.collector.outputStaticNonFinalFieldLists;
outputLibraryLists = programBuilder.collector.outputLibraryLists;
- typedefsNeededForReflection =
- programBuilder.collector.typedefsNeededForReflection;
assembleProgram(program);
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
index 9e194b88..48af9c9 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -51,33 +51,18 @@
List<jsAst.Name> names = addedJsNames.keys.toList()..sort();
for (jsAst.Name jsName in names) {
Selector selector = addedJsNames[jsName];
- String reflectionName =
- emitter.getReflectionSelectorName(selector, jsName);
-
- if (reflectionName != null) {
- emitter.mangledFieldNames[jsName] = reflectionName;
- }
-
List<jsAst.Expression> argNames = selector.callStructure
.getOrderedNamedArguments()
.map((String name) => js.string(name))
.toList();
int type = selector.invocationMirrorKind;
if (!haveVeryFewNoSuchMemberHandlers &&
- isTrivialNsmHandler(type, argNames, selector, jsName) &&
- reflectionName == null) {
+ isTrivialNsmHandler(type, argNames, selector, jsName)) {
trivialNsmHandlers.add(selector);
} else {
StubMethod method =
generator.generateStubForNoSuchMethod(jsName, selector);
addProperty(method.name, method.code);
- if (reflectionName != null) {
- bool accessible = closedWorld
- .locateMembers(selector, null)
- .any(backend.mirrorsData.isMemberAccessibleByReflection);
- addProperty(
- namer.asName('+$reflectionName'), js(accessible ? '2' : '0'));
- }
}
}
}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
index b8df5d2..f5a6d47 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -65,10 +65,8 @@
String defaultValuesField = namer.defaultValuesField;
String methodsWithOptionalArgumentsField =
namer.methodsWithOptionalArgumentsField;
- bool retainMetadata = backend.mirrorsData.mustRetainMetadata;
- String unmangledNameIndex = retainMetadata
- ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3'
- : ' 2 * optionalParameterCount + requiredParameterCount + 3';
+ String unmangledNameIndex =
+ ' 2 * optionalParameterCount + requiredParameterCount + 3';
String receiverParamName =
compiler.options.enableMinification ? "r" : "receiver";
String valueParamName = compiler.options.enableMinification ? "v" : "value";
@@ -104,7 +102,6 @@
'deferredAction': namer.deferredAction,
'allClasses': allClassesAccess,
'debugFastObjects': DEBUG_FAST_OBJECTS,
- 'isTreeShakingDisabled': backend.mirrorsData.isTreeShakingDisabled,
'precompiled': precompiledAccess,
'finishedClassesAccess': finishedClassesAccess,
'needsMixinSupport': emitter.needsMixinSupport,
@@ -116,7 +113,6 @@
'isObject': namer.operatorIs(closedWorld.commonElements.objectClass),
'specProperty': js.string(namer.nativeSpecProperty),
'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(),
- 'hasRetainedMetadata': backend.mirrorsData.hasRetainedMetadata,
'types': typesAccess,
'objectClassName': js.quoteName(
namer.runtimeTypeName(closedWorld.commonElements.objectClass)),
@@ -309,8 +305,6 @@
var desc = processedClasses.collected[cls];
var globalObject = desc[0];
desc = desc[1];
- if (#isTreeShakingDisabled)
- constructor["${namer.metadataField}"] = desc;
allClasses[cls] = constructor;
globalObject[cls] = constructor;
}
@@ -520,11 +514,6 @@
var classData = descriptor["${namer.classDescriptorProperty}"],
split, supr, fields = classData;
- if (#hasRetainedMetadata)
- if (typeof classData == "object" &&
- classData instanceof Array) {
- classData = fields = classData[0];
- }
// ${ClassBuilder.fieldEncodingDescription}.
var s = fields.split(";");
fields = s[1] ? s[1].split(",") : [];
@@ -664,14 +653,6 @@
${readInt("array", "position")} =
${readInt("array", "position")} + metadataOffset;
position++;
- if ($retainMetadata) {
- var metaArray = ${readInt("array", "position")};
- for (var j = 0; j < metaArray.length; j++) {
- ${readInt("metaArray", "j")} =
- ${readInt("metaArray", "j")} + metadataOffset;
- }
- position++;
- }
}
}
var unmangledNameIndex = $unmangledNameIndex;
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index ef1ffd3..b0e6d88 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -9,30 +9,13 @@
import '../common.dart';
import '../constants/values.dart';
import '../deferred_load.dart' show OutputUnit;
-import '../elements/elements.dart'
- show
- ClassElement,
- ConstructorElement,
- Element,
- FieldElement,
- FunctionSignature,
- LibraryElement,
- MemberElement,
- MethodElement,
- MetadataAnnotation,
- ParameterElement;
import '../elements/entities.dart' show FunctionEntity;
import '../elements/entities.dart';
-import '../elements/resolution_types.dart' show ResolutionTypedefType;
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
-import '../js_backend/constant_handler_javascript.dart';
-import '../js_backend/mirrors_data.dart';
import '../js_backend/runtime_types.dart' show RuntimeTypesEncoder;
-import '../js_backend/type_variable_handler.dart'
- show TypeVariableCodegenAnalysis;
import '../options.dart';
import '../universe/world_builder.dart' show CodegenWorldBuilder;
@@ -84,43 +67,6 @@
int compareTo(covariant _MetadataEntry other) => other._rc - this._rc;
}
-abstract class Placeholder implements jsAst.DeferredNumber {
- bind(_MetadataEntry entry);
-}
-
-class _ForwardingMetadataEntry extends _MetadataEntry implements Placeholder {
- _MetadataEntry _forwardTo;
- var debug;
-
- bool get isBound => _forwardTo != null;
-
- _ForwardingMetadataEntry([this.debug]);
-
- _MetadataEntry get forwardTo {
- assert(isBound, 'unbound $this $debug');
- return _forwardTo;
- }
-
- jsAst.Expression get entry {
- return forwardTo.entry;
- }
-
- int get value {
- return forwardTo.value;
- }
-
- int get _rc => forwardTo._rc;
-
- markSeen(jsAst.BaseVisitor visitor) => forwardTo.markSeen(visitor);
-
- int compareTo(other) => forwardTo.compareTo(other);
-
- bind(_MetadataEntry entry) {
- assert(!isBound);
- _forwardTo = entry;
- }
-}
-
class _MetadataList extends jsAst.DeferredExpression {
jsAst.Expression _value;
@@ -142,9 +88,6 @@
final CompilerOptions _options;
final DiagnosticReporter reporter;
final Emitter _emitter;
- final JavaScriptConstantCompiler _constants;
- final TypeVariableCodegenAnalysis _typeVariableCodegenAnalysis;
- final MirrorsData _mirrorsData;
final RuntimeTypesEncoder _rtiEncoder;
final CodegenWorldBuilder _codegenWorldBuilder;
@@ -175,80 +118,12 @@
Map<OutputUnit, Map<DartType, _BoundMetadataEntry>> _typesMap =
<OutputUnit, Map<DartType, _BoundMetadataEntry>>{};
- MetadataCollector(
- this._options,
- this.reporter,
- this._emitter,
- this._constants,
- this._typeVariableCodegenAnalysis,
- this._mirrorsData,
- this._rtiEncoder,
- this._codegenWorldBuilder);
-
- jsAst.Fun buildLibraryMetadataFunction(LibraryEntity element) {
- if (!_mirrorsData.mustRetainMetadata ||
- !_mirrorsData.isLibraryReferencedFromMirrorSystem(element)) {
- return null;
- }
- return _buildMetadataFunction(element as LibraryElement);
- }
-
- jsAst.Fun buildClassMetadataFunction(ClassEntity cls) {
- if (!_mirrorsData.mustRetainMetadata ||
- !_mirrorsData.isClassReferencedFromMirrorSystem(cls)) {
- return null;
- }
- // TODO(redemption): Handle class entities.
- ClassElement element = cls;
- return _buildMetadataFunction(element);
- }
-
- bool _mustEmitMetadataForMember(MemberEntity member) {
- if (!_mirrorsData.mustRetainMetadata) {
- return false;
- }
- // TODO(redemption): Handle member entities.
- MemberElement element = member;
- return _mirrorsData.isMemberReferencedFromMirrorSystem(element);
- }
-
- jsAst.Fun buildFieldMetadataFunction(FieldEntity field) {
- if (!_mustEmitMetadataForMember(field)) return null;
- // TODO(redemption): Handle field entities.
- FieldElement element = field;
- return _buildMetadataFunction(element);
- }
-
- /// The metadata function returns the metadata associated with
- /// [element] in generated code. The metadata needs to be wrapped
- /// in a function as it refers to constants that may not have been
- /// constructed yet. For example, a class is allowed to be
- /// annotated with itself. The metadata function is used by
- /// mirrors_patch to implement DeclarationMirror.metadata.
- jsAst.Fun _buildMetadataFunction(Element element) {
- return reporter.withCurrentElement(element, () {
- List<jsAst.Expression> metadata = <jsAst.Expression>[];
- for (MetadataAnnotation annotation in element.metadata) {
- ConstantValue constant =
- _constants.getConstantValueForMetadata(annotation);
- if (constant == null) {
- reporter.internalError(annotation, 'Annotation value is null.');
- } else {
- metadata.add(_emitter.constantReference(constant));
- }
- }
- if (metadata.isEmpty) return null;
- return js(
- 'function() { return # }', new jsAst.ArrayInitializer(metadata));
- });
- }
+ MetadataCollector(this._options, this.reporter, this._emitter,
+ this._rtiEncoder, this._codegenWorldBuilder);
List<jsAst.DeferredNumber> reifyDefaultArguments(
FunctionEntity function, OutputUnit outputUnit) {
// TODO(sra): These are stored on the InstanceMethod or StaticDartMethod.
- if (function is MethodElement)
- return reifyDefaultArgumentsAst(function, outputUnit);
-
List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[];
_codegenWorldBuilder.forEachParameter(function,
(_, String name, ConstantValue constant) {
@@ -259,100 +134,8 @@
return defaultValues;
}
- List<jsAst.DeferredNumber> reifyDefaultArgumentsAst(
- MethodElement function, OutputUnit outputUnit) {
- function = function.implementation;
- FunctionSignature signature = function.functionSignature;
- if (signature.optionalParameterCount == 0) return const [];
-
- // Optional parameters of redirecting factory constructors take their
- // defaults from the corresponding parameters of the redirection target.
- Map<ParameterElement, ParameterElement> targetParameterMap;
- if (function is ConstructorElement) {
- // TODO(sra): dart2js generates a redirecting factory constructor body
- // that has the signature of the redirecting constructor that calls the
- // redirection target. This is wrong - it should have the signature of the
- // target. This would make the reified default arguments trivial.
-
- ConstructorElement constructor = function;
- while (constructor.isRedirectingFactory &&
- !constructor.isCyclicRedirection) {
- // TODO(sra): Remove the loop once effectiveTarget forwards to patches.
- constructor = constructor.effectiveTarget.implementation;
- }
-
- if (constructor != function) {
- if (signature.hasOptionalParameters) {
- targetParameterMap =
- mapRedirectingFactoryConstructorOptionalParameters(
- signature, constructor.functionSignature);
- }
- }
- }
-
- List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[];
- for (ParameterElement element in signature.optionalParameters) {
- ParameterElement parameter =
- (targetParameterMap == null) ? element : targetParameterMap[element];
- ConstantValue constant = (parameter == null)
- ? null
- : _constants.getConstantValue(parameter.constant);
- jsAst.Expression expression = (constant == null)
- ? new jsAst.LiteralNull()
- : _emitter.constantReference(constant);
- defaultValues.add(_addGlobalMetadata(expression, outputUnit));
- }
- return defaultValues;
- }
-
- Map<ParameterElement, ParameterElement>
- mapRedirectingFactoryConstructorOptionalParameters(
- FunctionSignature source, FunctionSignature target) {
- var map = <ParameterElement, ParameterElement>{};
-
- if (source.optionalParametersAreNamed !=
- target.optionalParametersAreNamed) {
- // No legal optional arguments due to mismatch between named vs positional
- // optional arguments.
- return map;
- }
-
- if (source.optionalParametersAreNamed) {
- for (ParameterElement element in source.optionalParameters) {
- for (ParameterElement redirectedElement in target.optionalParameters) {
- if (element.name == redirectedElement.name) {
- map[element] = redirectedElement;
- break;
- }
- }
- }
- } else {
- int i = source.requiredParameterCount;
- for (ParameterElement element in source.orderedOptionalParameters) {
- if (i >= target.requiredParameterCount && i < target.parameterCount) {
- map[element] = target
- .orderedOptionalParameters[i - target.requiredParameterCount];
- }
- ++i;
- }
- }
- return map;
- }
-
- jsAst.Expression reifyMetadata(
- MetadataAnnotation annotation, OutputUnit outputUnit) {
- ConstantValue constant = _constants.getConstantValueForMetadata(annotation);
- if (constant == null) {
- reporter.internalError(annotation, 'Annotation value is null.');
- return null;
- }
- return _addGlobalMetadata(_emitter.constantReference(constant), outputUnit);
- }
-
- jsAst.Expression reifyType(DartType type, OutputUnit outputUnit,
- {ignoreTypeVariables: false}) {
- return addTypeInOutputUnit(type, outputUnit,
- ignoreTypeVariables: ignoreTypeVariables);
+ jsAst.Expression reifyType(DartType type, OutputUnit outputUnit) {
+ return addTypeInOutputUnit(type, outputUnit);
}
jsAst.Expression reifyName(String name, OutputUnit outputUnit) {
@@ -364,10 +147,6 @@
return _addGlobalMetadata(expression, outputUnit);
}
- Placeholder getMetadataPlaceholder([debug]) {
- return new _ForwardingMetadataEntry(debug);
- }
-
_MetadataEntry _addGlobalMetadata(jsAst.Node node, OutputUnit outputUnit) {
String nameToKey(jsAst.Name name) => "${name.key}";
String printed = jsAst.prettyPrint(node,
@@ -379,14 +158,16 @@
});
}
- jsAst.Expression _computeTypeRepresentation(DartType type,
- {ignoreTypeVariables: false}) {
+ jsAst.Expression _computeTypeRepresentation(DartType type) {
jsAst.Expression representation =
_rtiEncoder.getTypeRepresentation(_emitter, type, (variable) {
- if (ignoreTypeVariables) return new jsAst.LiteralNull();
- return _typeVariableCodegenAnalysis.reifyTypeVariable(variable.element);
- }, (ResolutionTypedefType typedef) {
- return _mirrorsData.isTypedefAccessibleByReflection(typedef.element);
+ failedAt(
+ NO_LOCATION_SPANNABLE,
+ "Type representation for type variable $variable in "
+ "$type is not supported.");
+ return jsAst.LiteralNull();
+ }, (TypedefType typedef) {
+ return false;
});
if (representation is jsAst.LiteralString) {
@@ -399,41 +180,15 @@
return representation;
}
- jsAst.Expression addTypeInOutputUnit(DartType type, OutputUnit outputUnit,
- {ignoreTypeVariables: false}) {
+ jsAst.Expression addTypeInOutputUnit(DartType type, OutputUnit outputUnit) {
_typesMap[outputUnit] ??= new Map<DartType, _BoundMetadataEntry>();
return _typesMap[outputUnit].putIfAbsent(type, () {
- return new _BoundMetadataEntry(_computeTypeRepresentation(type,
- ignoreTypeVariables: ignoreTypeVariables));
- });
- }
-
- List<jsAst.DeferredNumber> computeMetadata(
- MethodElement element, OutputUnit outputUnit) {
- return reporter.withCurrentElement(element, () {
- if (!_mustEmitMetadataForMember(element))
- return const <jsAst.DeferredNumber>[];
- List<jsAst.DeferredNumber> metadata = <jsAst.DeferredNumber>[];
- for (MetadataAnnotation annotation in element.metadata) {
- metadata.add(reifyMetadata(annotation, outputUnit));
- }
- return metadata;
+ return new _BoundMetadataEntry(_computeTypeRepresentation(type));
});
}
@override
void finalizeTokens() {
- bool checkTokensInTypes(OutputUnit outputUnit, entries) {
- UnBoundDebugger debugger = new UnBoundDebugger(outputUnit);
- for (_BoundMetadataEntry entry in entries) {
- if (!entry.isUsed) continue;
- if (debugger.findUnboundPlaceholders(entry.entry)) {
- return false;
- }
- }
- return true;
- }
-
void countTokensInTypes(Iterable<_BoundMetadataEntry> entries) {
jsAst.TokenCounter counter = new jsAst.TokenCounter();
entries
@@ -472,7 +227,6 @@
_typesTokens.forEach((OutputUnit outputUnit, _MetadataList token) {
Map typesMap = _typesMap[outputUnit];
if (typesMap != null) {
- assert(checkTokensInTypes(outputUnit, typesMap.values));
countTokensInTypes(typesMap.values);
token.setExpression(finalizeMap(typesMap));
} else {
@@ -481,22 +235,3 @@
});
}
}
-
-class UnBoundDebugger extends jsAst.BaseVisitor {
- OutputUnit outputUnit;
- bool _foundUnboundToken = false;
-
- UnBoundDebugger(this.outputUnit);
-
- @override
- visitDeferredNumber(jsAst.DeferredNumber token) {
- if (token is _ForwardingMetadataEntry && !token.isBound) {
- _foundUnboundToken = true;
- }
- }
-
- bool findUnboundPlaceholders(jsAst.Node node) {
- node.accept(this);
- return _foundUnboundToken;
- }
-}
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index a66b830..3938cfb 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -21,11 +21,6 @@
/// A map from load id to the list of fragments that need to be loaded.
final Map<String, List<Fragment>> loadMap;
- /// A map from names to strings.
- ///
- /// This map is needed to support `const Symbol` expressions;
- final Map<js.Name, String> symbolsMap;
-
// If this field is not `null` then its value must be emitted in the embedded
// global `TYPE_TO_INTERCEPTOR_MAP`. The map references constants and classes.
final js.Expression typeToInterceptorMap;
@@ -35,8 +30,8 @@
final MetadataCollector _metadataCollector;
final Iterable<js.TokenFinalizer> finalizers;
- Program(this.fragments, this.holders, this.loadMap, this.symbolsMap,
- this.typeToInterceptorMap, this._metadataCollector, this.finalizers,
+ Program(this.fragments, this.holders, this.loadMap, this.typeToInterceptorMap,
+ this._metadataCollector, this.finalizers,
{this.needsNativeSupport,
this.outputContainsConstantList,
this.hasSoftDeferredClasses}) {
@@ -430,9 +425,8 @@
final js.Name tearOffName;
final List<ParameterStubMethod> parameterStubs;
final bool canBeApplied;
- final bool canBeReflected;
- // Is non-null if [needsTearOff] or [canBeReflected].
+ // Is non-null if [needsTearOff].
//
// If the type is encoded in the metadata table this field contains an index
// into the table. Otherwise the type contains type variables in which case
@@ -440,7 +434,7 @@
final js.Expression functionType;
// Signature information for this method. This is only required and stored
- // here if the method [canBeApplied] or [canBeReflected]
+ // here if the method [canBeApplied].
final int requiredParameterCount;
final /* Map | List */ optionalParameterDefaultValues;
@@ -454,7 +448,6 @@
{this.needsTearOff,
this.tearOffName,
this.canBeApplied,
- this.canBeReflected,
this.requiredParameterCount,
this.optionalParameterDefaultValues,
this.functionType})
@@ -462,8 +455,7 @@
assert(needsTearOff != null);
assert(!needsTearOff || tearOffName != null);
assert(canBeApplied != null);
- assert(canBeReflected != null);
- assert((!canBeReflected && !canBeApplied) ||
+ assert(!canBeApplied ||
(requiredParameterCount != null &&
optionalParameterDefaultValues != null));
}
@@ -492,7 +484,6 @@
js.Name tearOffName,
this.aliasName,
bool canBeApplied,
- bool canBeReflected,
int requiredParameterCount,
/* List | Map */ optionalParameterDefaultValues,
this.isClosureCallMethod,
@@ -502,7 +493,6 @@
needsTearOff: needsTearOff,
tearOffName: tearOffName,
canBeApplied: canBeApplied,
- canBeReflected: canBeReflected,
requiredParameterCount: requiredParameterCount,
optionalParameterDefaultValues: optionalParameterDefaultValues,
functionType: functionType) {
@@ -573,7 +563,6 @@
{bool needsTearOff,
js.Name tearOffName,
bool canBeApplied,
- bool canBeReflected,
int requiredParameterCount,
/* List | Map */ optionalParameterDefaultValues,
js.Expression functionType})
@@ -581,7 +570,6 @@
needsTearOff: needsTearOff,
tearOffName: tearOffName,
canBeApplied: canBeApplied,
- canBeReflected: canBeReflected,
requiredParameterCount: requiredParameterCount,
optionalParameterDefaultValues: optionalParameterDefaultValues,
functionType: functionType);
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 84f2502..187729f 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -318,6 +318,33 @@
stubs.add(stub);
}
}
+
+ // A generic method might need to support `call<T>(x)` for a generic
+ // instantiation stub without `call<T>(x)` being in [callSelectors].
+ // [selector] will be `call(x)` (that already passes the appliesUnnamed
+ // check by defaulting type arguments), and the method will be generic.
+ //
+ // This is basically the same logic as above, but with type arguments.
+ if (selector.callStructure.typeArgumentCount == 0) {
+ ParameterStructure parameterStructure = member.parameterStructure;
+ if (parameterStructure.typeParameters > 0) {
+ Selector renamedSelectorWithTypeArguments = new Selector.call(
+ member.memberName,
+ selector.callStructure
+ .withTypeArgumentCount(parameterStructure.typeParameters));
+ renamedCallSelectors.add(renamedSelectorWithTypeArguments);
+
+ if (stubSelectors.add(renamedSelectorWithTypeArguments)) {
+ Selector closureSelector =
+ new Selector.callClosureFrom(renamedSelectorWithTypeArguments);
+ ParameterStubMethod stub = generateParameterStub(
+ member, renamedSelectorWithTypeArguments, closureSelector);
+ if (stub != null) {
+ stubs.add(stub);
+ }
+ }
+ }
+ }
}
// Now run through the actual member selectors (eg. `foo$2(x, y)` and not
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 7877cdb..615835e 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -23,7 +23,6 @@
final NativeData _nativeData;
final InterceptorData _interceptorData;
final OneShotInterceptorData _oneShotInterceptorData;
- final MirrorsData _mirrorsData;
final ClosedWorld _closedWorld;
final Set<ClassEntity> _rtiNeededClasses;
final Map<MemberEntity, js.Expression> _generatedCode;
@@ -50,8 +49,6 @@
final List<ClassEntity> nativeClassesAndSubclasses = <ClassEntity>[];
- List<TypedefEntity> typedefsNeededForReflection;
-
Collector(
this._options,
this._commonElements,
@@ -64,7 +61,6 @@
this._nativeData,
this._interceptorData,
this._oneShotInterceptorData,
- this._mirrorsData,
this._closedWorld,
this._rtiNeededClasses,
this._generatedCode,
@@ -87,10 +83,6 @@
* that needs to be emitted.
*/
Function computeClassFilter(Iterable<ClassEntity> backendTypeHelpers) {
- if (_mirrorsData.isTreeShakingDisabled) {
- return (ClassEntity cls) => true;
- }
-
Set<ClassEntity> unneededClasses = new Set<ClassEntity>();
// The [Bool] class is not marked as abstract, but has a factory
// constructor that always throws. We never need to emit it.
@@ -141,46 +133,6 @@
* Compute all the constants that must be emitted.
*/
void computeNeededConstants() {
- // Make sure we retain all metadata of all elements. This could add new
- // constants to the handler.
- if (_mirrorsData.mustRetainMetadata) {
- // TODO(floitsch): verify that we don't run through the same elements
- // multiple times.
- for (MemberEntity element in _generatedCode.keys) {
- if (_mirrorsData.isMemberAccessibleByReflection(element)) {
- _mirrorsData.retainMetadataOfMember(element);
- }
- }
- for (ClassEntity cls in neededClasses) {
- final onlyForRti = classesOnlyNeededForRti.contains(cls);
- if (!onlyForRti) {
- _mirrorsData.retainMetadataOfClass(cls);
- new FieldVisitor(
- _options,
- _elementEnvironment,
- _commonElements,
- _worldBuilder,
- _nativeData,
- _mirrorsData,
- _namer,
- _closedWorld)
- .visitFields((FieldEntity member,
- js.Name name,
- js.Name accessorName,
- bool needsGetter,
- bool needsSetter,
- bool needsCheckedSetter) {
- bool needsAccessor = needsGetter || needsSetter;
- if (needsAccessor &&
- _mirrorsData.isMemberAccessibleByReflection(member)) {
- _mirrorsData.retainMetadataOfMember(member);
- }
- }, cls: cls);
- }
- }
- typedefsNeededForReflection.forEach(_mirrorsData.retainMetadataOfTypedef);
- }
-
List<ConstantValue> constants =
_worldBuilder.getConstantsForEmission(_emitter.compareConstants);
for (ConstantValue constant in constants) {
@@ -206,11 +158,6 @@
Set<ClassEntity> backendTypeHelpers =
getBackendTypeHelpers(_commonElements).toSet();
- // Compute needed typedefs.
- typedefsNeededForReflection = _sorter.sortTypedefs(_closedWorld.allTypedefs
- .where(_mirrorsData.isTypedefAccessibleByReflection)
- .toList());
-
// Compute needed classes.
Set<ClassEntity> instantiatedClasses =
// TODO(johnniwinther): This should be accessed from a codegen closed
@@ -332,14 +279,8 @@
// TODO(johnniwinther): This should be accessed from a codegen closed
// world.
_worldBuilder.allReferencedStaticFields.where((FieldEntity field) {
- if (!field.isConst) {
- return field.isAssignable &&
- _worldBuilder.hasConstantFieldInitializer(field);
- } else {
- // We also need to emit static const fields if they are available for
- // reflection.
- return _mirrorsData.isMemberAccessibleByReflection(field);
- }
+ return field.isAssignable &&
+ _worldBuilder.hasConstantFieldInitializer(field);
});
_sorter.sortMembers(fields).forEach((MemberEntity e) => addToOutputUnit(e));
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
index 76576af..7415a08 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
@@ -31,7 +31,6 @@
final CommonElements _commonElements;
final CodegenWorldBuilder _codegenWorldBuilder;
final NativeData _nativeData;
- final MirrorsData _mirrorsData;
final Namer _namer;
final ClosedWorld _closedWorld;
@@ -41,7 +40,6 @@
this._commonElements,
this._codegenWorldBuilder,
this._nativeData,
- this._mirrorsData,
this._namer,
this._closedWorld);
@@ -63,10 +61,6 @@
*/
void visitFields(AcceptField f,
{bool visitStatics: false, LibraryEntity library, ClassEntity cls}) {
- assert(!(library is LibraryElement && !library.isDeclaration),
- failedAt(library));
- assert(!(cls is ClassElement && !cls.isDeclaration), failedAt(cls));
-
bool isNativeClass = false;
bool isLibrary = false;
bool isInstantiated = false;
@@ -86,8 +80,6 @@
}
void visitField(FieldEntity field, {ClassEntity holder}) {
- assert(!(field is FieldElement && !field.isDeclaration), failedAt(field));
-
bool isMixinNativeField =
isNativeClass && _elementEnvironment.isMixinApplication(holder);
@@ -153,7 +145,6 @@
bool fieldNeedsGetter(FieldEntity field) {
assert(field.isField);
if (fieldAccessNeverThrows(field)) return false;
- if (_mirrorsData.shouldRetainGetter(field)) return true;
return field.enclosingClass != null &&
_codegenWorldBuilder.hasInvokedGetter(field, _closedWorld);
}
@@ -162,7 +153,6 @@
assert(field.isField);
if (fieldAccessNeverThrows(field)) return false;
if (!field.isAssignable) return false;
- if (_mirrorsData.shouldRetainSetter(field)) return true;
return field.enclosingClass != null &&
_codegenWorldBuilder.hasInvokedSetter(field, _closedWorld);
}
@@ -173,7 +163,8 @@
// knowing that it is there. Therefore we don't need to use a getter
// (that will throw if the getter method is missing), but can always
// access the field directly.
- field is ClosureFieldElement;
+ // TODO(johnniwinther): Return `true` JClosureField.
+ false;
}
bool canAvoidGeneratedCheckedSetter(FieldEntity member) {
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 3a78a8f..88f2c2d 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -7,7 +7,7 @@
import 'dart:io';
import 'dart:convert' show jsonDecode;
-import '../../closure.dart' show ClosureConversionTask, ClosureFieldElement;
+import '../../closure.dart' show ClosureConversionTask;
import '../../common.dart';
import '../../common/names.dart' show Names, Selectors;
import '../../constants/values.dart'
@@ -15,8 +15,6 @@
import '../../common_elements.dart' show CommonElements, ElementEnvironment;
import '../../deferred_load.dart'
show DeferredLoadTask, OutputUnit, OutputUnitData;
-import '../../elements/elements.dart'
- show ClassElement, FieldElement, LibraryElement, MethodElement;
import '../../elements/entities.dart';
import '../../elements/types.dart';
import '../../io/source_information.dart';
@@ -29,11 +27,10 @@
import '../../js_backend/namer.dart' show Namer, StringBackedName;
import '../../js_backend/native_data.dart';
import '../../js_backend/interceptor_data.dart';
-import '../../js_backend/mirrors_data.dart';
import '../../js_backend/js_interop_analysis.dart';
import '../../js_backend/runtime_types.dart'
show RuntimeTypesChecks, RuntimeTypesNeed, RuntimeTypesEncoder;
-import '../../js_model/elements.dart' show JSignatureMethod;
+import '../../js_model/elements.dart' show JGeneratorBody, JSignatureMethod;
import '../../native/enqueue.dart' show NativeCodegenEnqueuer;
import '../../options.dart';
import '../../universe/selector.dart' show Selector;
@@ -75,7 +72,6 @@
final JavaScriptConstantCompiler _constantHandler;
final NativeData _nativeData;
final RuntimeTypesNeed _rtiNeed;
- final MirrorsData _mirrorsData;
final InterceptorData _interceptorData;
final SuperMemberData _superMemberData;
final RuntimeTypesChecks _rtiChecks;
@@ -102,7 +98,6 @@
final Registry _registry;
final FunctionEntity _mainFunction;
- final bool _isMockCompilation;
/// True if the program should store function types in the metadata.
bool _storeFunctionTypesInMetadata = false;
@@ -122,7 +117,6 @@
this._constantHandler,
this._nativeData,
this._rtiNeed,
- this._mirrorsData,
this._interceptorData,
this._superMemberData,
this._rtiChecks,
@@ -137,10 +131,8 @@
this._sourceInformationStrategy,
this._sorter,
Set<ClassEntity> rtiNeededClasses,
- this._mainFunction,
- {bool isMockCompilation})
- : this._isMockCompilation = isMockCompilation,
- this.collector = new Collector(
+ this._mainFunction)
+ : this.collector = new Collector(
_options,
_commonElements,
_elementEnvironment,
@@ -152,7 +144,6 @@
_nativeData,
_interceptorData,
_oneShotInterceptorData,
- _mirrorsData,
_closedWorld,
rtiNeededClasses,
_generatedCode,
@@ -171,13 +162,6 @@
/// update field-initializers to point to the ConstantModel.
final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{};
- /// Mapping from names to strings.
- ///
- /// This mapping is used to support `const Symbol` expressions.
- ///
- /// This map is filled when building classes.
- final Map<js.Name, String> _symbolsMap = <js.Name, String>{};
-
Set<Class> _unneededNativeClasses;
/// Classes that have been allocated during a profile run.
@@ -273,7 +257,7 @@
finalizers.add(namingFinalizer as js.TokenFinalizer);
}
- return new Program(fragments, holders, _buildLoadMap(), _symbolsMap,
+ return new Program(fragments, holders, _buildLoadMap(),
_buildTypeToInterceptorMap(), _task.metadataCollector, finalizers,
needsNativeSupport: needsNativeSupport,
outputContainsConstantList: collector.outputContainsConstantList,
@@ -389,7 +373,6 @@
}
js.Statement _buildInvokeMain() {
- if (_isMockCompilation) return js.js.comment("Mock compilation");
return MainCallStubGenerator.generateInvokeMain(
_task.emitter, _mainFunction);
}
@@ -714,9 +697,6 @@
// If the program contains `const Symbol` names we have to retain them.
String selectorName = selector.name;
if (selector.isSetter) selectorName = "$selectorName=";
- if (_mirrorsData.symbolsUsed.contains(selectorName)) {
- _symbolsMap[name] = selectorName;
- }
noSuchMethodStubs.add(
classStubGenerator.generateStubForNoSuchMethod(name, selector));
});
@@ -843,14 +823,12 @@
}
bool _methodNeedsStubs(FunctionEntity method) {
+ if (method is JGeneratorBody) return false;
+ if (method is ConstructorBodyEntity) return false;
return method.parameterStructure.optionalParameters != 0 ||
method.parameterStructure.typeParameters != 0;
}
- bool _methodCanBeReflected(FunctionEntity method) {
- return _mirrorsData.isMemberAccessibleByReflection(method);
- }
-
bool _methodCanBeApplied(FunctionEntity method) {
return _backendUsage.isFunctionApplyUsed &&
_closedWorld.getMightBePassedToApply(method);
@@ -883,7 +861,6 @@
}
DartMethod _buildMethod(FunctionEntity element) {
- assert(!(element is MethodElement && !element.isDeclaration));
js.Name name = _namer.methodPropertyName(element);
js.Expression code = _generatedCode[element];
@@ -896,7 +873,6 @@
bool isNotApplyTarget =
!element.isFunction || element.isGetter || element.isSetter;
- bool canBeReflected = _methodCanBeReflected(element);
bool canBeApplied = _methodCanBeApplied(element);
js.Name aliasName = _superMemberData.isAliasedSuperMember(element)
@@ -911,8 +887,7 @@
isClosureCallMethod = true;
} else {
// Careful with operators.
- canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld) ||
- (canBeReflected && !Selector.isOperatorName(element.name));
+ canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld);
assert(canTearOff ||
!_worldBuilder.methodsNeedingSuperGetter.contains(element));
tearOffName = _namer.getterForElement(element);
@@ -936,14 +911,14 @@
DartType memberType = _elementEnvironment.getFunctionType(element);
js.Expression functionType;
- if (canTearOff || canBeReflected) {
+ if (canTearOff) {
OutputUnit outputUnit = _outputUnitData.outputUnitForMember(element);
functionType = _generateFunctionType(memberType, outputUnit);
}
int requiredParameterCount;
var /* List | Map */ optionalParameterDefaultValues;
- if (canBeApplied || canBeReflected) {
+ if (canBeApplied) {
// TODO(redemption): Handle function entities.
FunctionEntity method = element;
ParameterStructure parameterStructure = method.parameterStructure;
@@ -959,7 +934,6 @@
isIntercepted: isIntercepted,
aliasName: aliasName,
canBeApplied: canBeApplied,
- canBeReflected: canBeReflected,
requiredParameterCount: requiredParameterCount,
optionalParameterDefaultValues: optionalParameterDefaultValues,
functionType: functionType);
@@ -1063,8 +1037,6 @@
void visitField(FieldEntity field, js.Name name, js.Name accessorName,
bool needsGetter, bool needsSetter, bool needsCheckedSetter) {
- assert(!(field is FieldElement && !field.isDeclaration), failedAt(field));
-
int getterFlags = 0;
if (needsGetter) {
if (visitStatics ||
@@ -1097,15 +1069,8 @@
needsCheckedSetter));
}
- FieldVisitor visitor = new FieldVisitor(
- _options,
- _elementEnvironment,
- _commonElements,
- _worldBuilder,
- _nativeData,
- _mirrorsData,
- _namer,
- _closedWorld);
+ FieldVisitor visitor = new FieldVisitor(_options, _elementEnvironment,
+ _commonElements, _worldBuilder, _nativeData, _namer, _closedWorld);
visitor.visitFields(visitField,
visitStatics: visitStatics, library: library, cls: cls);
@@ -1145,11 +1110,9 @@
bool isApplyTarget =
!element.isConstructor && !element.isGetter && !element.isSetter;
bool canBeApplied = _methodCanBeApplied(element);
- bool canBeReflected = _methodCanBeReflected(element);
bool needsTearOff = isApplyTarget &&
- (canBeReflected ||
- _worldBuilder.staticFunctionsNeedingGetter.contains(element));
+ _worldBuilder.staticFunctionsNeedingGetter.contains(element);
js.Name tearOffName =
needsTearOff ? _namer.staticClosureName(element) : null;
@@ -1162,14 +1125,14 @@
}
js.Expression functionType;
DartType type = _elementEnvironment.getFunctionType(element);
- if (needsTearOff || canBeReflected) {
+ if (needsTearOff) {
OutputUnit outputUnit = _outputUnitData.outputUnitForMember(element);
functionType = _generateFunctionType(type, outputUnit);
}
int requiredParameterCount;
var /* List | Map */ optionalParameterDefaultValues;
- if (canBeApplied || canBeReflected) {
+ if (canBeApplied) {
// TODO(redemption): Support entities;
FunctionEntity method = element;
ParameterStructure parameterStructure = method.parameterStructure;
@@ -1184,7 +1147,6 @@
needsTearOff: needsTearOff,
tearOffName: tearOffName,
canBeApplied: canBeApplied,
- canBeReflected: canBeReflected,
requiredParameterCount: requiredParameterCount,
optionalParameterDefaultValues: optionalParameterDefaultValues,
functionType: functionType);
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index b483325..3615c8c 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -5,15 +5,9 @@
library dart2js.js_emitter.runtime_type_generator;
import '../closure.dart'
- show
- ClosureRepresentationInfo,
- ClosureFieldElement,
- ClosureConversionTask,
- ScopeInfo;
-import '../common.dart';
+ show ClosureRepresentationInfo, ClosureConversionTask, ScopeInfo;
import '../common_elements.dart' show CommonElements;
import '../deferred_load.dart' show OutputUnit, OutputUnitData;
-import '../elements/elements.dart' show ClassElement, MethodElement;
import '../elements/entities.dart';
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
@@ -142,14 +136,10 @@
{bool storeFunctionTypeInMetadata: true}) {
TypeTestProperties result = new TypeTestProperties();
- assert(!(classElement is ClassElement && !classElement.isDeclaration),
- failedAt(classElement));
-
// TODO(johnniwinther): Include function signatures in [ClassChecks].
void generateFunctionTypeSignature(ClassFunctionType classFunctionType) {
FunctionEntity method = classFunctionType.callFunction;
FunctionType type = classFunctionType.callType;
- assert(!(method is MethodElement && !method.isImplementation));
// TODO(johnniwinther): Avoid unneeded function type indices or
// signatures. We either need them for mirrors or because [type] is
@@ -177,8 +167,7 @@
if (scopeInfo is ClosureRepresentationInfo) {
FieldEntity thisLocal = scopeInfo.thisFieldEntity;
if (thisLocal != null) {
- assert(thisLocal is ClosureFieldElement ||
- thisLocal is JClosureField);
+ assert(thisLocal is JClosureField);
jsAst.Name thisName =
_namer.instanceFieldPropertyName(thisLocal);
thisAccess = js('this.#', thisName);
diff --git a/pkg/compiler/lib/src/js_emitter/sorter.dart b/pkg/compiler/lib/src/js_emitter/sorter.dart
index 70fbd51..5048bb4 100644
--- a/pkg/compiler/lib/src/js_emitter/sorter.dart
+++ b/pkg/compiler/lib/src/js_emitter/sorter.dart
@@ -4,7 +4,6 @@
library dart2js.js_emitter.sorter;
-import '../elements/elements.dart';
import '../elements/entities.dart';
/// Sorting strategy for libraries, classes and members.
@@ -26,64 +25,3 @@
int compareTypedefsByLocation(TypedefEntity a, TypedefEntity b);
int compareMembersByLocation(MemberEntity a, MemberEntity b);
}
-
-class ElementSorter implements Sorter {
- const ElementSorter();
-
- @override
- List<LibraryEntity> sortLibraries(Iterable<LibraryEntity> libraries) {
- return Elements.sortedByPosition(new List.from(libraries, growable: false));
- }
-
- @override
- List<ClassEntity> sortClasses(Iterable<ClassEntity> classes) {
- List<ClassElement> regularClasses = <ClassElement>[];
- List<MixinApplicationElement> unnamedMixins = <MixinApplicationElement>[];
- for (ClassElement cls in classes) {
- if (cls.isUnnamedMixinApplication) {
- unnamedMixins.add(cls);
- } else {
- regularClasses.add(cls);
- }
- }
- List<ClassEntity> sorted = <ClassEntity>[];
- sorted.addAll(Elements.sortedByPosition<ClassElement>(regularClasses));
- unnamedMixins.sort((a, b) {
- int result = a.name.compareTo(b.name);
- if (result != 0) return result;
- return Elements.compareByPosition(a.mixin, b.mixin);
- });
- sorted.addAll(unnamedMixins);
- return sorted;
- }
-
- @override
- Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs) {
- return Elements.sortedByPosition(new List.from(typedefs, growable: false));
- }
-
- @override
- Iterable<T> sortMembers<T extends MemberEntity>(Iterable<T> members) {
- return Elements.sortedByPosition(new List.from(members, growable: false));
- }
-
- @override
- int compareLibrariesByLocation(
- covariant LibraryElement a, covariant LibraryElement b) =>
- Elements.compareByPosition(a, b);
-
- @override
- int compareClassesByLocation(
- covariant ClassElement a, covariant ClassElement b) =>
- Elements.compareByPosition(a, b);
-
- @override
- int compareTypedefsByLocation(
- covariant TypedefElement a, covariant TypedefElement b) =>
- Elements.compareByPosition(a, b);
-
- @override
- int compareMembersByLocation(
- covariant MemberElement a, covariant MemberElement b) =>
- Elements.compareByPosition(a, b);
-}
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 9bb77ff..6996a89 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
@@ -1336,7 +1336,7 @@
CommonElements commonElements = _closedWorld.commonElements;
// We want to keep the original names for the most common core classes when
// calling toString on them.
- List<ClassElement> nativeClassesNeedingUnmangledName = [
+ List<ClassEntity> nativeClassesNeedingUnmangledName = [
commonElements.intClass,
commonElements.doubleClass,
commonElements.numClass,
@@ -1404,13 +1404,10 @@
// The [MANGLED_NAMES] table must contain the mapping for const symbols.
// Without const symbols, the table is only relevant for reflection and
// therefore unused in this emitter.
- List<js.Property> mangledNamesProperties = <js.Property>[];
- program.symbolsMap.forEach((js.Name mangledName, String unmangledName) {
- mangledNamesProperties
- .add(new js.Property(mangledName, js.string(unmangledName)));
- });
- globals.add(new js.Property(js.string(MANGLED_NAMES),
- new js.ObjectInitializer(mangledNamesProperties)));
+ // TODO(johnniwinther): Remove the need for adding an empty list of
+ // mangled names.
+ globals.add(new js.Property(
+ js.string(MANGLED_NAMES), new js.ObjectInitializer(<js.Property>[])));
globals.add(emitGetTypeFromName());
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 f2ba354..9c3beac 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
@@ -31,7 +31,6 @@
import '../../compiler.dart' show Compiler;
import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
import '../../common_elements.dart' show CommonElements;
-import '../../elements/elements.dart' show ClassElement;
import '../../elements/entities.dart';
import '../../hash/sha1.dart' show Hasher;
import '../../io/code_output.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
index 1f1895b..f353ebb 100644
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
@@ -7,16 +7,13 @@
import '../common.dart';
import '../common_elements.dart';
import '../elements/entities.dart';
-import '../elements/types.dart';
import '../js_backend/runtime_types.dart'
show
RuntimeTypesChecks,
RuntimeTypesChecksBuilder,
RuntimeTypesSubstitutions;
-import '../js_backend/mirrors_data.dart';
import '../options.dart';
import '../universe/world_builder.dart';
-import '../world.dart' show ClosedWorld;
class TypeTestRegistry {
final ElementEnvironment _elementEnvironment;
@@ -27,12 +24,11 @@
final CompilerOptions _options;
final CodegenWorldBuilder _codegenWorldBuilder;
- final ClosedWorld _closedWorld;
RuntimeTypesChecks _rtiChecks;
- TypeTestRegistry(this._options, this._codegenWorldBuilder, this._closedWorld,
- this._elementEnvironment);
+ TypeTestRegistry(
+ this._options, this._codegenWorldBuilder, this._elementEnvironment);
RuntimeTypesChecks get rtiChecks {
assert(
@@ -51,7 +47,7 @@
}
void computeRtiNeededClasses(RuntimeTypesSubstitutions rtiSubstitutions,
- MirrorsData mirrorsData, Iterable<MemberEntity> liveMembers) {
+ Iterable<MemberEntity> liveMembers) {
_rtiNeededClasses = new Set<ClassEntity>();
void addClassWithSuperclasses(ClassEntity cls) {
@@ -69,47 +65,9 @@
}
}
- // 1. Add classes that are referenced by type arguments or substitutions in
- // argument checks.
+ // Add classes that are referenced by type arguments or substitutions in
+ // argument checks.
addClassesWithSuperclasses(rtiChecks.requiredClasses);
-
- bool canTearOff(MemberEntity function) {
- if (!function.isFunction ||
- function.isConstructor ||
- function.isGetter ||
- function.isSetter) {
- return false;
- } else if (function.isInstanceMember) {
- if (!function.enclosingClass.isClosure) {
- return _codegenWorldBuilder.hasInvokedGetter(function, _closedWorld);
- }
- }
- return false;
- }
-
- bool canBeReflectedAsFunction(MemberEntity element) {
- return !element.isField;
- }
-
- bool canBeReified(MemberEntity element) {
- return (canTearOff(element) ||
- mirrorsData.isMemberAccessibleByReflection(element));
- }
-
- // 2. Find all types referenced from the types of elements that can be
- // reflected on 'as functions'.
- liveMembers.where((MemberEntity element) {
- return canBeReflectedAsFunction(element) && canBeReified(element);
- }).forEach((_function) {
- FunctionEntity function = _function;
- FunctionType type = _elementEnvironment.getFunctionType(function);
- for (ClassEntity cls in _rtiChecks.getReferencedClasses(type)) {
- while (cls != null) {
- _rtiNeededClasses.add(cls);
- cls = _elementEnvironment.getSuperClass(cls);
- }
- }
- });
}
void computeRequiredTypeChecks(RuntimeTypesChecksBuilder rtiChecksBuilder) {
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index f7ab997a..462ba79 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -80,10 +80,8 @@
'dart:_foreign_helper',
'dart:_interceptors',
'dart:_internal',
- 'dart:_isolate_helper',
'dart:_js_embedded_names',
'dart:_js_helper',
- 'dart:_js_mirrors',
'dart:_js_names',
'dart:_native_typed_data',
'dart:async',
@@ -104,10 +102,8 @@
'dart:_foreign_helper',
'dart:_interceptors',
'dart:_internal',
- 'dart:_isolate_helper',
'dart:_js_embedded_names',
'dart:_js_helper',
- 'dart:_js_mirrors',
'dart:_js_names',
'dart:_native_typed_data',
'dart:async',
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index fe468dd..13adcc4 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -20,7 +20,7 @@
import '../js_model/elements.dart' show JGeneratorBody;
import '../native/native.dart' as native;
import '../ssa/type_builder.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
import '../universe/call_structure.dart';
import '../universe/selector.dart';
import '../world.dart';
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 8a70896..a6e104d 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -20,7 +20,6 @@
import '../constants/evaluation.dart';
import '../constants/expressions.dart';
import '../constants/values.dart';
-import '../elements/elements.dart';
import '../elements/entities.dart';
import '../elements/entity_utils.dart' as utils;
import '../elements/names.dart';
@@ -1884,18 +1883,6 @@
@override
ConstantSystem get constantSystem => const JavaScriptConstantSystem();
- @override
- ConstantValue getConstantValueForVariable(VariableElement element) {
- throw new UnimplementedError(
- "KernelConstantEnvironment.getConstantValueForVariable");
- }
-
- @override
- ConstantValue getConstantValue(ConstantExpression expression) {
- return _getConstantValue(CURRENT_ELEMENT_SPANNABLE, expression,
- constantRequired: true);
- }
-
ConstantValue _getConstantValue(
Spannable spannable, ConstantExpression expression,
{bool constantRequired}) {
@@ -1906,11 +1893,6 @@
constantSystem);
});
}
-
- @override
- bool hasConstantValue(ConstantExpression expression) {
- throw new UnimplementedError("KernelConstantEnvironment.hasConstantValue");
- }
}
/// Evaluation environment used for computing [ConstantValue]s for
@@ -2898,7 +2880,7 @@
} else if (node is ir.FunctionDeclaration) {
String name = node.variable.name;
if (name != null && name != "") {
- parts.add(Elements.operatorNameToIdentifier(name));
+ parts.add(utils.operatorNameToIdentifier(name));
} else {
parts.add(anonymous);
anonymous = '';
@@ -2911,7 +2893,7 @@
if (node.kind == ir.ProcedureKind.Factory) {
parts.add(utils.reconstructConstructorName(getMember(node)));
} else {
- parts.add(Elements.operatorNameToIdentifier(node.name.name));
+ parts.add(utils.operatorNameToIdentifier(node.name.name));
}
} else if (node is ir.Constructor) {
parts.add(utils.reconstructConstructorName(getMember(node)));
diff --git a/pkg/compiler/lib/src/kernel/element_map_mixins.dart b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
index 3588b19..a7f7901 100644
--- a/pkg/compiler/lib/src/kernel/element_map_mixins.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
@@ -158,7 +158,6 @@
type ??= findIn(Uris.dart_core);
type ??= findIn(Uris.dart__js_helper);
type ??= findIn(Uris.dart__interceptors);
- type ??= findIn(Uris.dart__isolate_helper);
type ??= findIn(Uris.dart__native_typed_data);
type ??= findIn(Uris.dart_collection);
type ??= findIn(Uris.dart_math);
diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
index 3c3f6bf..ae1b004 100644
--- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
@@ -25,6 +25,7 @@
import '../ssa/nodes.dart';
import '../ssa/ssa.dart';
import '../ssa/types.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../universe/selector.dart';
import '../universe/world_impact.dart';
@@ -173,7 +174,7 @@
!mask.satisfies(closedWorld.commonElements.jsStringClass, closedWorld);
}
- bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) {
+ bool isFixedLength(covariant TypeMask mask, ClosedWorld closedWorld) {
if (mask.isContainer && (mask as ContainerTypeMask).length != null) {
// A container on which we have inferred the length.
return true;
@@ -204,7 +205,7 @@
parameter, _globalInferenceResults);
}
- TypeMask selectorTypeOf(Selector selector, TypeMask mask) {
+ TypeMask selectorTypeOf(Selector selector, covariant TypeMask mask) {
return TypeMaskFactory.inferredTypeForSelector(
selector, mask, _globalInferenceResults);
}
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index 1872ee8..d6d273e 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -15,17 +15,13 @@
import '../common_elements.dart';
import '../compiler.dart';
import '../deferred_load.dart' show DeferredLoadTask;
-import '../elements/elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../enqueue.dart';
import '../environment.dart' as env;
import '../frontend_strategy.dart';
-import '../js_backend/backend.dart';
import '../js_backend/backend_usage.dart';
import '../js_backend/interceptor_data.dart';
-import '../js_backend/mirrors_analysis.dart';
-import '../js_backend/mirrors_data.dart';
import '../js_backend/native_data.dart';
import '../js_backend/no_such_method_registry.dart';
import '../js_backend/runtime_types.dart';
@@ -34,12 +30,9 @@
import '../native/enqueue.dart' show NativeResolutionEnqueuer;
import '../native/resolver.dart';
import '../options.dart';
-import '../patch_parser.dart';
-import '../resolved_uri_translator.dart';
import '../universe/class_hierarchy_builder.dart';
import '../universe/world_builder.dart';
import '../universe/world_impact.dart';
-import '../world.dart';
import 'deferred_load.dart';
import 'element_map.dart';
import 'element_map_impl.dart';
@@ -71,16 +64,8 @@
}
@override
- LibraryLoaderTask createLibraryLoader(
- ResolvedUriTranslator uriTranslator,
- ScriptLoader scriptLoader,
- api.CompilerInput compilerInput,
- ElementScanner scriptScanner,
- PatchResolverFunction patchResolverFunc,
- PatchParserTask patchParser,
- env.Environment environment,
- DiagnosticReporter reporter,
- Measurer measurer) {
+ LibraryLoaderTask createLibraryLoader(api.CompilerInput compilerInput,
+ DiagnosticReporter reporter, Measurer measurer) {
return new KernelLibraryLoaderTask(
_options.librariesSpecificationUri,
_options.platformBinaries,
@@ -113,8 +98,8 @@
@override
NativeClassFinder createNativeClassFinder(NativeBasicData nativeBasicData) {
- return new BaseNativeClassFinder(_elementMap.elementEnvironment,
- elementMap.commonElements, nativeBasicData);
+ return new BaseNativeClassFinder(
+ _elementMap.elementEnvironment, nativeBasicData);
}
NoSuchMethodResolver createNoSuchMethodResolver() {
@@ -128,15 +113,6 @@
return elementEnvironment.mainFunction;
}
- MirrorsDataBuilder createMirrorsDataBuilder() {
- return new MirrorsDataBuilderImpl(elementEnvironment, commonElements);
- }
-
- MirrorsResolutionAnalysis createMirrorsResolutionAnalysis(
- JavaScriptBackend backend) {
- return new MirrorsResolutionAnalysisImpl();
- }
-
RuntimeTypesNeedBuilder createRuntimeTypesNeedBuilder() {
return _runtimeTypesNeedBuilder ??= _options.disableRtiOptimization
? const TrivialRuntimeTypesNeedBuilder()
@@ -219,7 +195,7 @@
}
}
-class KernelWorkItem implements ResolutionWorkItem {
+class KernelWorkItem implements WorkItem {
final CompilerTask _compilerTask;
final KernelToElementMapForImpactImpl _elementMap;
final ImpactTransformer _impactTransformer;
@@ -259,59 +235,3 @@
});
}
}
-
-/// Mock implementation of [MirrorsDataImpl].
-class MirrorsDataBuilderImpl extends MirrorsDataImpl {
- MirrorsDataBuilderImpl(
- ElementEnvironment elementEnvironment, CommonElements commonElements)
- : super(null, elementEnvironment, commonElements);
-
- @override
- void registerUsedMember(MemberEntity member) {}
-
- @override
- void computeMembersNeededForReflection(
- ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) {
- // TODO(redemption): Support dart:mirrors.
- createImmutableSets();
- }
-
- @override
- void maybeMarkClosureAsNeededForReflection(ClassEntity closureClass,
- FunctionEntity callMethod, Local localFunction) {}
-
- @override
- void registerConstSymbol(String name) {}
-
- @override
- void registerMirrorUsage(
- Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) {}
-}
-
-/// Mock implementation of [MirrorsResolutionAnalysis].
-class MirrorsResolutionAnalysisImpl implements MirrorsResolutionAnalysis {
- @override
- void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {}
-
- @override
- MirrorsCodegenAnalysis close() {
- // TODO(redemption): Implement this.
- return new MirrorsCodegenAnalysisImpl();
- }
-
- @override
- void onResolutionComplete() {}
-}
-
-class MirrorsCodegenAnalysisImpl implements MirrorsCodegenAnalysis {
- @override
- int get preMirrorsMethodCount {
- // TODO(redemption): Implement this.
- return null;
- }
-
- @override
- void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
- // TODO(redemption): Implement this.
- }
-}
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index b96adbd..2124d1f 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -16,42 +16,13 @@
import 'kernel/front_end_adapter.dart';
import 'kernel/dart2js_target.dart' show Dart2jsTarget;
-import 'common/names.dart' show Uris;
import 'common/tasks.dart' show CompilerTask, Measurer;
import 'common.dart';
-import 'elements/elements.dart'
- show
- CompilationUnitElement,
- Element,
- ImportElement,
- ExportElement,
- LibraryElement;
import 'elements/entities.dart' show LibraryEntity;
-import 'elements/modelx.dart'
- show
- CompilationUnitElementX,
- DeferredLoaderGetterElementX,
- ErroneousElementX,
- ExportElementX,
- ImportElementX,
- LibraryElementX,
- LibraryDependencyElementX,
- PrefixElementX,
- SyntheticImportElement;
import 'enqueue.dart' show DeferredAction;
-import 'environment.dart';
-import 'io/source_file.dart' show Binary;
import 'kernel/element_map_impl.dart' show KernelToElementMapForImpactImpl;
-import 'patch_parser.dart' show PatchParserTask;
import 'resolved_uri_translator.dart';
-import 'script.dart';
-import 'tree/tree.dart';
-import 'util/util.dart' show Link, LinkBuilder;
-
-typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction(
- Iterable<LibraryElement> libraries);
-
-typedef Uri PatchResolverFunction(String dartLibraryPath);
+import 'util/util.dart' show Link;
/**
* [CompilerTask] for loading libraries and setting up the import/export scopes.
@@ -167,19 +138,6 @@
Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
{bool skipFileWithPartOfTag: false});
- /// Reset the library loader task to prepare for compilation. If provided,
- /// libraries matching [reuseLibrary] are reused.
- ///
- /// This method is used for incremental compilation.
- void reset({bool reuseLibrary(LibraryElement library)});
-
- /// Asynchronous version of [reset].
- Future resetAsync(Future<bool> reuseLibrary(LibraryElement library));
-
- /// Similar to [resetAsync] but [reuseLibrary] maps all libraries to a list
- /// of libraries that can be reused.
- Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries);
-
// TODO(johnniwinther): Move these to a separate interface.
/// Register a deferred action to be performed during resolution.
void registerDeferredAction(DeferredAction action);
@@ -222,563 +180,6 @@
LibraryEntity lookupLibrary(Uri canonicalUri);
}
-/// Handle for creating synthesized/patch libraries during library loading.
-abstract class LibraryLoader {
- /// This method must be called when a new synthesized/patch library has been
- /// created to ensure that [library] will part of library dependency graph
- /// used for computing import/export scopes.
- void registerNewLibrary(LibraryElement library);
-
- /// This method must be called when a new synthesized/patch library has been
- /// scanned in order to process the library tags in [library] and thus handle
- /// imports/exports/parts in the synthesized/patch library.
- Future processLibraryTags(LibraryElement library);
-}
-
-/**
- * [CombinatorFilter] is a succinct representation of a list of combinators from
- * a library dependency tag.
- */
-class CombinatorFilter {
- const CombinatorFilter();
-
- /**
- * Returns [:true:] if [element] is excluded by this filter.
- */
- bool exclude(Element element) => false;
-
- /**
- * Creates a filter based on the combinators of [tag].
- */
- factory CombinatorFilter.fromTag(LibraryDependency tag) {
- if (tag == null || tag.combinators == null) {
- return const CombinatorFilter();
- }
-
- // If the list of combinators contain at least one [:show:] we can create
- // a positive list of elements to include, otherwise we create a negative
- // list of elements to exclude.
- bool show = false;
- Set<String> nameSet;
- for (Combinator combinator in tag.combinators) {
- if (combinator.isShow) {
- show = true;
- var set = new Set<String>();
- for (Identifier identifier in combinator.identifiers) {
- set.add(identifier.source);
- }
- if (nameSet == null) {
- nameSet = set;
- } else {
- nameSet = nameSet.intersection(set);
- }
- }
- }
- if (nameSet == null) {
- nameSet = new Set<String>();
- }
- for (Combinator combinator in tag.combinators) {
- if (combinator.isHide) {
- for (Identifier identifier in combinator.identifiers) {
- if (show) {
- // We have a positive list => Remove hidden elements.
- nameSet.remove(identifier.source);
- } else {
- // We have no positive list => Accumulate hidden elements.
- nameSet.add(identifier.source);
- }
- }
- }
- }
- return show ? new ShowFilter(nameSet) : new HideFilter(nameSet);
- }
-}
-
-/**
- * A list of combinators represented as a list of element names to include.
- */
-class ShowFilter extends CombinatorFilter {
- final Set<String> includedNames;
-
- ShowFilter(this.includedNames);
-
- bool exclude(Element element) => !includedNames.contains(element.name);
-}
-
-/**
- * A list of combinators represented as a list of element names to exclude.
- */
-class HideFilter extends CombinatorFilter {
- final Set<String> excludedNames;
-
- HideFilter(this.excludedNames);
-
- bool exclude(Element element) => excludedNames.contains(element.name);
-}
-
-/// Implementation class for [LibraryLoaderTask]. This library loader loads
-/// '.dart' files into the [Element] model with AST nodes which are resolved
-/// by the resolver.
-class ResolutionLibraryLoaderTask extends CompilerTask
- implements LibraryLoaderTask {
- /// Translates internal uris (like dart:core) to a disk location.
- final ResolvedUriTranslator uriTranslator;
-
- /// Loads the contents of a script file (a .dart file). Used when loading
- /// libraries from source.
- final ScriptLoader scriptLoader;
-
- /// Provides a diet element model from a script file containing information
- /// about imports and exports. Used when loading libraries from source.
- final ElementScanner scanner;
-
- /// Definitions provided via the `-D` command line flags. Used to resolve
- /// conditional imports.
- final Environment environment;
-
- // TODO(efortuna): Don't pass PatchParserTask here.
- final PatchParserTask _patchParserTask;
-
- /// Function that accepts the string name of a library and returns the
- /// path to the corresponding patch file. This is a function that is passed in
- /// because our test mock_compiler subclasses compiler.
- // TODO(efortuna): Refactor mock_compiler to not do this.
- final PatchResolverFunction _patchResolverFunc;
-
- List<DeferredAction> _deferredActions = <DeferredAction>[];
-
- final DiagnosticReporter reporter;
-
- ResolutionLibraryLoaderTask(
- this.uriTranslator,
- this.scriptLoader,
- this.scanner,
- this._patchResolverFunc,
- this._patchParserTask,
- this.environment,
- this.reporter,
- Measurer measurer)
- : super(measurer);
-
- String get name => 'LibraryLoader';
-
- final Map<Uri, LibraryElement> libraryCanonicalUriMap =
- new Map<Uri, LibraryElement>();
- final Map<Uri, LibraryElement> libraryResourceUriMap =
- new Map<Uri, LibraryElement>();
- final Map<String, LibraryElement> libraryNames =
- new Map<String, LibraryElement>();
-
- Iterable<LibraryEntity> get libraries => libraryCanonicalUriMap.values;
-
- LibraryEntity lookupLibrary(Uri canonicalUri) {
- return libraryCanonicalUriMap[canonicalUri];
- }
-
- void reset({bool reuseLibrary(LibraryElement library)}) {
- measure(() {
- Iterable<LibraryElement> reusedLibraries = null;
- if (reuseLibrary != null) {
- reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () {
- // Call [toList] to force eager calls to [reuseLibrary].
- return libraryCanonicalUriMap.values.where(reuseLibrary).toList();
- });
- }
-
- resetImplementation(reusedLibraries);
- });
- }
-
- void resetImplementation(Iterable<LibraryElement> reusedLibraries) {
- measure(() {
- libraryCanonicalUriMap.clear();
- libraryResourceUriMap.clear();
- libraryNames.clear();
-
- if (reusedLibraries != null) {
- reusedLibraries.forEach(mapLibrary);
- }
- });
- }
-
- Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) {
- return measure(() {
- Future<LibraryElement> wrapper(LibraryElement library) {
- try {
- return reuseLibrary(library)
- .then((bool reuse) => reuse ? library : null);
- } catch (exception, trace) {
- reporter.onCrashInUserCode(
- 'Uncaught exception in reuseLibrary', exception, trace);
- rethrow;
- }
- }
-
- List<Future<LibraryElement>> reusedLibrariesFuture = measureSubtask(
- _reuseLibrarySubtaskName,
- () => libraryCanonicalUriMap.values.map(wrapper).toList());
-
- return Future
- .wait(reusedLibrariesFuture)
- .then((Iterable<LibraryElement> reusedLibraries) {
- resetImplementation(reusedLibraries.where((e) => e != null));
- });
- });
- }
-
- Future<Null> resetLibraries(
- Future<Iterable<LibraryElement>> reuseLibraries(
- Iterable<LibraryElement> libraries)) {
- return measureSubtask(_reuseLibrarySubtaskName, () {
- return new Future<Iterable<LibraryElement>>(() {
- // Wrap in Future to shield against errors in user code.
- return reuseLibraries(libraryCanonicalUriMap.values);
- }).catchError((exception, StackTrace trace) {
- reporter.onCrashInUserCode(
- 'Uncaught exception in reuseLibraries', exception, trace);
- throw exception; // Async rethrow.
- }).then((Iterable<LibraryElement> reusedLibraries) {
- measure(() {
- resetImplementation(reusedLibraries);
- });
- });
- });
- }
-
- /// Insert [library] in the internal maps. Used for compiler reuse.
- void mapLibrary(LibraryElement library) {
- libraryCanonicalUriMap[library.canonicalUri] = library;
-
- Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
- libraryResourceUriMap[resourceUri] = library;
-
- if (library.hasLibraryName) {
- String name = library.libraryName;
- libraryNames[name] = library;
- }
- }
-
- Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
- {bool skipFileWithPartOfTag: false}) {
- return measure(() async {
- LibraryDependencyHandler handler = new LibraryDependencyHandler(this);
- LibraryElement library = await createLibrary(
- handler, null, resolvedUri, NO_LOCATION_SPANNABLE,
- skipFileWithPartOfTag: skipFileWithPartOfTag);
- if (library == null) return null;
- return reporter.withCurrentElement(library, () {
- return measure(() {
- handler.computeExports();
- return new _LoadedLibraries(library, handler.newLibraries);
- });
- });
- });
- }
-
- /**
- * Processes the library tags in [library].
- *
- * The imported/exported libraries are loaded and processed recursively but
- * the import/export scopes are not set up.
- */
- Future processLibraryTags(
- LibraryDependencyHandler handler, LibraryElementX library) {
- TagState tagState = new TagState();
-
- bool importsDartCore = false;
- LinkBuilder<LibraryDependencyElementX> libraryDependencies =
- new LinkBuilder<LibraryDependencyElementX>();
- Uri base = library.entryCompilationUnit.script.readableUri;
-
- return Future.forEach(library.tags, (LibraryTag tag) {
- return reporter.withCurrentElement(library, () {
- Uri computeUri(LibraryDependency node) {
- 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 = environment.valueOf(key);
- if (value == actual) {
- uriNode = conditionalUri.uri;
- break;
- }
- }
- }
- String tagUriString = uriNode.dartString.slowToString();
- try {
- return Uri.parse(tagUriString);
- } on FormatException {
- reporter.reportErrorMessage(
- node.uri, MessageKind.INVALID_URI, {'uri': tagUriString});
- return null;
- }
- }
-
- if (tag.isImport) {
- Uri uri = computeUri(tag);
- if (uri == null) {
- // Skip this erroneous import.
- return new Future.value();
- }
- // TODO(johnniwinther): Create imports during parsing.
- ImportElementX import =
- new ImportElementX(library.entryCompilationUnit, tag, uri);
- tagState.checkTag(TagState.IMPORT_OR_EXPORT, import.node, reporter);
- if (import.uri == Uris.dart_core) {
- importsDartCore = true;
- }
- library.addImportDeclaration(import);
- libraryDependencies.addLast(import);
- } else if (tag.isExport) {
- Uri uri = computeUri(tag);
- if (uri == null) {
- // Skip this erroneous export.
- return new Future.value();
- }
- // TODO(johnniwinther): Create exports during parsing.
- ExportElementX export =
- new ExportElementX(library.entryCompilationUnit, tag, uri);
- tagState.checkTag(TagState.IMPORT_OR_EXPORT, export.node, reporter);
- library.addExportDeclaration(export);
- libraryDependencies.addLast(export);
- } else if (tag.isLibraryName) {
- tagState.checkTag(TagState.LIBRARY, tag, reporter);
- if (library.libraryTag == null) {
- // Use the first if there are multiple (which is reported as an
- // error in [TagState.checkTag]).
- library.libraryTag = tag;
- }
- } else if (tag.isPart) {
- Part part = tag;
- StringNode uri = part.uri;
- Uri resolvedUri = base.resolve(uri.dartString.slowToString());
- tagState.checkTag(TagState.PART, part, reporter);
- return scanPart(part, resolvedUri, library);
- } else {
- reporter.internalError(tag, "Unhandled library tag.");
- }
- });
- }).then((_) {
- return reporter.withCurrentElement(library, () {
- checkDuplicatedLibraryName(library);
-
- // Import dart:core if not already imported.
- if (!importsDartCore && library.canonicalUri != Uris.dart_core) {
- return createLibrary(handler, null, Uris.dart_core, library)
- .then((LibraryElement coreLibrary) {
- handler.registerDependency(
- library,
- new SyntheticImportElement(
- library.entryCompilationUnit, Uris.dart_core, coreLibrary),
- coreLibrary);
- });
- }
- });
- }).then((_) {
- return Future.forEach(libraryDependencies.toList(),
- (LibraryDependencyElementX libraryDependency) {
- return reporter.withCurrentElement(library, () {
- return registerLibraryFromImportExport(
- handler, library, libraryDependency);
- });
- });
- });
- }
-
- void checkDuplicatedLibraryName(LibraryElement library) {
- if (library.isInternalLibrary) return;
- Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
- LibraryElement existing =
- libraryResourceUriMap.putIfAbsent(resourceUri, () => library);
- if (!identical(existing, library)) {
- if (library.hasLibraryName) {
- reporter.withCurrentElement(library, () {
- reporter.reportWarningMessage(
- library, MessageKind.DUPLICATED_LIBRARY_RESOURCE, {
- 'libraryName': library.libraryName,
- 'resourceUri': resourceUri,
- 'canonicalUri1': library.canonicalUri,
- 'canonicalUri2': existing.canonicalUri
- });
- });
- } else {
- reporter.reportHintMessage(library, MessageKind.DUPLICATED_RESOURCE, {
- 'resourceUri': resourceUri,
- 'canonicalUri1': library.canonicalUri,
- 'canonicalUri2': existing.canonicalUri
- });
- }
- } else if (library.hasLibraryName) {
- String name = library.libraryName;
- existing = libraryNames.putIfAbsent(name, () => library);
- if (!identical(existing, library)) {
- reporter.withCurrentElement(library, () {
- reporter.reportWarningMessage(library,
- MessageKind.DUPLICATED_LIBRARY_NAME, {'libraryName': name});
- });
- reporter.withCurrentElement(existing, () {
- reporter.reportWarningMessage(existing,
- MessageKind.DUPLICATED_LIBRARY_NAME, {'libraryName': name});
- });
- }
- }
- }
-
- /**
- * Handle a part tag in the scope of [library]. The [resolvedUri] given is
- * used as is, any URI resolution should be done beforehand.
- */
- Future scanPart(Part part, Uri resolvedUri, LibraryElement library) {
- if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri);
- Uri readableUri = uriTranslator.translate(library, resolvedUri, part);
- if (readableUri == null) return new Future.value();
- return reporter.withCurrentElement(library, () {
- return scriptLoader.readScript(readableUri, part).then((Script script) {
- if (script == null) return;
- createUnitSync(script, library);
- });
- });
- }
-
- /**
- * Handle an import/export tag by loading the referenced library and
- * registering its dependency in [handler] for the computation of the import/
- * export scope. If the tag does not contain a valid URI, then its dependency
- * is not registered in [handler].
- */
- Future<Null> registerLibraryFromImportExport(LibraryDependencyHandler handler,
- LibraryElement library, LibraryDependencyElementX libraryDependency) {
- Uri base = library.canonicalUri;
- Uri resolvedUri = base.resolveUri(libraryDependency.uri);
- return createLibrary(handler, library, resolvedUri, libraryDependency)
- .then((LibraryElement loadedLibrary) {
- if (loadedLibrary == null) return;
- reporter.withCurrentElement(library, () {
- libraryDependency.libraryDependency = loadedLibrary;
- handler.registerDependency(library, libraryDependency, loadedLibrary);
- });
- });
- }
-
- Future<Script> _readScript(
- Spannable spannable, Uri readableUri, Uri resolvedUri) {
- if (readableUri == null) {
- return new Future.value(new Script.synthetic(resolvedUri));
- } else {
- return scriptLoader.readScript(readableUri, spannable);
- }
- }
-
- /**
- * Create (or reuse) a library element for the library specified by the
- * [resolvedUri].
- *
- * If a new library is created, the [handler] is notified.
- */
- Future<LibraryElement> createLibrary(LibraryDependencyHandler handler,
- LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable,
- {bool skipFileWithPartOfTag: false}) async {
- Uri readableUri =
- uriTranslator.translate(importingLibrary, resolvedUri, spannable);
- LibraryElement library = libraryCanonicalUriMap[resolvedUri];
- if (library != null) {
- return new Future.value(library);
- }
- return reporter.withCurrentElement(importingLibrary, () {
- return _readScript(spannable, readableUri, resolvedUri)
- .then((Script script) async {
- if (script == null) return null;
- LibraryElement element =
- createLibrarySync(handler, script, resolvedUri);
- CompilationUnitElementX compilationUnit = element.entryCompilationUnit;
- if (compilationUnit.partTag != null) {
- if (skipFileWithPartOfTag) {
- // TODO(johnniwinther): Avoid calling
- // [compiler.processLoadedLibraries] with this library.
- libraryCanonicalUriMap.remove(resolvedUri);
- return null;
- }
- if (importingLibrary == null) {
- DiagnosticMessage error = reporter.withCurrentElement(
- compilationUnit,
- () => reporter.createMessage(
- compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF));
- reporter.reportError(error);
- } else {
- DiagnosticMessage error = reporter.withCurrentElement(
- compilationUnit,
- () => reporter.createMessage(
- compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
- DiagnosticMessage info = reporter.withCurrentElement(
- importingLibrary,
- () => reporter.createMessage(
- spannable, MessageKind.IMPORT_PART_OF_HERE));
- reporter.reportError(error, [info]);
- }
- }
- await processLibraryTags(handler, element);
- reporter.withCurrentElement(element, () {
- handler.registerLibraryExports(element);
- });
-
- await patchLibraryIfNecessary(element, handler);
- return element;
- });
- });
- }
-
- Future patchLibraryIfNecessary(
- LibraryElement element, LibraryDependencyHandler handler) async {
- if (element.isPlatformLibrary &&
- // Don't patch library currently disallowed.
- !element.isSynthesized &&
- !element.isPatched) {
- // Apply patch, if any.
- Uri patchUri = _patchResolverFunc(element.canonicalUri.path);
- if (patchUri != null) {
- await _patchParserTask.patchLibrary(handler, patchUri, element);
- }
- }
- }
-
- LibraryElement createLibrarySync(
- LibraryDependencyHandler handler, Script script, Uri resolvedUri) {
- LibraryElement element = new LibraryElementX(script, resolvedUri);
- return reporter.withCurrentElement(element, () {
- if (handler != null) {
- handler.registerNewLibrary(element);
- libraryCanonicalUriMap[resolvedUri] = element;
- }
- scanner.scanLibrary(element);
- return element;
- });
- }
-
- CompilationUnitElement createUnitSync(Script script, LibraryElement library) {
- CompilationUnitElementX unit = new CompilationUnitElementX(script, library);
- reporter.withCurrentElement(unit, () {
- scanner.scanUnit(unit);
- if (unit.partTag == null && !script.isSynthesized) {
- reporter.reportErrorMessage(unit, MessageKind.MISSING_PART_OF_TAG);
- }
- });
- return unit;
- }
-
- void registerDeferredAction(DeferredAction action) {
- _deferredActions.add(action);
- }
-
- Iterable<DeferredAction> pullDeferredActions() {
- Iterable<DeferredAction> actions = _deferredActions.toList();
- _deferredActions.clear();
- return actions;
- }
-}
-
/// A loader that builds a kernel IR representation of the component.
///
/// It supports loading both .dart source files or pre-compiled .dill files.
@@ -897,24 +298,12 @@
KernelToElementMapForImpactImpl get elementMap => _elementMap;
- void reset({bool reuseLibrary(LibraryElement library)}) {
- throw new UnimplementedError('KernelLibraryLoaderTask.reset');
- }
-
- Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) {
- throw new UnimplementedError('KernelLibraryLoaderTask.resetAsync');
- }
-
Iterable<LibraryEntity> get libraries => _allLoadedLibraries;
LibraryEntity lookupLibrary(Uri canonicalUri) {
return _elementMap?.lookupLibrary(canonicalUri);
}
- Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries) {
- throw new UnimplementedError('KernelLibraryLoaderTask.reuseLibraries');
- }
-
void registerDeferredAction(DeferredAction action) {
throw new UnimplementedError(
'KernelLibraryLoaderTask.registerDeferredAction');
@@ -923,581 +312,6 @@
Iterable<DeferredAction> pullDeferredActions() => const <DeferredAction>[];
}
-/// A state machine for checking script tags come in the correct order.
-class TagState {
- /// Initial state.
- static const int NO_TAG_SEEN = 0;
-
- /// Passed to [checkTag] when a library declaration (the syntax "library
- /// name;") has been seen. Not an actual state.
- static const int LIBRARY = 1;
-
- /// The state after the first library declaration.
- static const int AFTER_LIBRARY_DECLARATION = 2;
-
- /// The state after a import or export declaration has been seen, but before
- /// a part tag has been seen.
- static const int IMPORT_OR_EXPORT = 3;
-
- /// The state after a part tag has been seen.
- static const int PART = 4;
-
- /// Encodes transition function for state machine.
- static const List<int> NEXT = const <int>[
- NO_TAG_SEEN,
- AFTER_LIBRARY_DECLARATION, // Only one library tag is allowed.
- IMPORT_OR_EXPORT,
- IMPORT_OR_EXPORT,
- PART,
- ];
-
- int tagState = TagState.NO_TAG_SEEN;
-
- bool hasLibraryDeclaration = false;
-
- /// If [value] is less than [tagState] complain. Regardless, update
- /// [tagState] using transition function for state machine.
- void checkTag(int value, LibraryTag tag, DiagnosticReporter reporter) {
- if (tagState > value) {
- MessageKind kind;
- switch (value) {
- case LIBRARY:
- if (hasLibraryDeclaration) {
- kind = MessageKind.ONLY_ONE_LIBRARY_TAG;
- } else {
- kind = MessageKind.LIBRARY_TAG_MUST_BE_FIRST;
- }
- break;
-
- case IMPORT_OR_EXPORT:
- if (tag.isImport) {
- kind = MessageKind.IMPORT_BEFORE_PARTS;
- } else if (tag.isExport) {
- kind = MessageKind.EXPORT_BEFORE_PARTS;
- } else {
- reporter.internalError(tag, "Expected import or export.");
- }
- break;
-
- default:
- reporter.internalError(tag, "Unexpected order of library tags.");
- }
- reporter.reportErrorMessage(tag, kind);
- }
- tagState = NEXT[value];
- if (value == LIBRARY) {
- hasLibraryDeclaration = true;
- }
- }
-}
-
-/**
- * An [import] tag and the [importedLibrary] imported through [import].
- */
-class ImportLink {
- final ImportElementX import;
- final LibraryElement importedLibrary;
-
- ImportLink(this.import, this.importedLibrary);
-
- /**
- * Imports the library into the [importingLibrary].
- */
- void importLibrary(
- DiagnosticReporter reporter, LibraryElementX importingLibrary) {
- assert(importedLibrary.exportsHandled,
- failedAt(importedLibrary, 'Exports not handled on $importedLibrary'));
- Import tag = import.node;
- CombinatorFilter combinatorFilter = new CombinatorFilter.fromTag(tag);
- if (tag != null && tag.prefix != null) {
- String prefix = tag.prefix.source;
- Element existingElement = importingLibrary.find(prefix);
- PrefixElementX prefixElement;
- if (existingElement == null || !existingElement.isPrefix) {
- prefixElement = new PrefixElementX(
- prefix,
- importingLibrary.entryCompilationUnit,
- tag.getBeginToken(),
- tag.isDeferred ? import : null);
- } else {
- prefixElement = existingElement;
- }
- importingLibrary.addToScope(prefixElement, reporter);
- importedLibrary.forEachExport((Element element) {
- if (combinatorFilter.exclude(element)) return;
- prefixElement.addImport(element, import, reporter);
- });
- import.prefix = prefixElement;
- if (prefixElement.isDeferred) {
- prefixElement.addImport(
- new DeferredLoaderGetterElementX(prefixElement), import, reporter);
- }
- } else {
- importedLibrary.forEachExport((Element element) {
- reporter.withCurrentElement(importingLibrary, () {
- if (combinatorFilter.exclude(element)) return;
- importingLibrary.addImport(element, import, reporter);
- });
- });
- }
- }
-}
-
-/**
- * The combinator filter computed from an export tag and the library dependency
- * node for the library that declared the export tag. This represents an edge in
- * the library dependency graph.
- */
-class ExportLink {
- final ExportElementX export;
- final CombinatorFilter combinatorFilter;
- final LibraryDependencyNode exportNode;
-
- ExportLink(ExportElementX export, LibraryDependencyNode this.exportNode)
- : this.export = export,
- this.combinatorFilter = new CombinatorFilter.fromTag(export.node);
-
- /**
- * Exports [element] to the dependent library unless [element] is filtered by
- * the export combinators. Returns [:true:] if the set pending exports of the
- * dependent library was modified.
- */
- bool exportElement(Element element) {
- if (combinatorFilter.exclude(element)) return false;
- return exportNode.addElementToPendingExports(element, export);
- }
-}
-
-/**
- * A node in the library dependency graph.
- *
- * This class is used to collect the library dependencies expressed through
- * import and export tags, and as the work-list entry in computations of library
- * exports performed in [LibraryDependencyHandler.computeExports].
- */
-class LibraryDependencyNode {
- final LibraryElementX library;
-
- // Stored identity based hashCode for performance.
- final int hashCode = _nextHash = (_nextHash + 100019).toUnsigned(30);
- static int _nextHash = 0;
-
- /**
- * A linked list of the import tags that import [library] mapped to the
- * corresponding libraries. This is used to propagate exports into imports
- * after the export scopes have been computed.
- */
- Link<ImportLink> imports = const Link<ImportLink>();
-
- /// A linked list of all libraries directly exported by [library].
- Link<LibraryElement> exports = const Link<LibraryElement>();
-
- /**
- * A linked list of the export tags the dependent upon this node library.
- * This is used to propagate exports during the computation of export scopes.
- */
- Link<ExportLink> dependencies = const Link<ExportLink>();
-
- /**
- * The export scope for [library] which is gradually computed by the work-list
- * computation in [LibraryDependencyHandler.computeExports].
- */
- Map<String, Element> exportScope = <String, Element>{};
-
- /// Map from exported elements to the export directives that exported them.
- Map<Element, Link<ExportElement>> exporters =
- <Element, Link<ExportElement>>{};
-
- /**
- * The set of exported elements that need to be propageted to dependent
- * libraries as part of the work-list computation performed in
- * [LibraryDependencyHandler.computeExports]. Each export element is mapped
- * to a list of exports directives that export it.
- */
- Map<Element, Link<ExportElement>> pendingExportMap =
- <Element, Link<ExportElement>>{};
-
- LibraryDependencyNode(this.library);
-
- /**
- * Registers that the library of this node imports [importLibrary] through the
- * [import] tag.
- */
- void registerImportDependency(
- ImportElementX import, LibraryElement importedLibrary) {
- imports = imports.prepend(new ImportLink(import, importedLibrary));
- }
-
- /**
- * Registers that the library of this node is exported by
- * [exportingLibraryNode] through the [export] tag.
- */
- void registerExportDependency(
- ExportElementX export, LibraryDependencyNode exportingLibraryNode) {
- // Register the exported library in the exporting library node.
- exportingLibraryNode.exports =
- exportingLibraryNode.exports.prepend(library);
- // Register the export in the exported library node.
- dependencies =
- dependencies.prepend(new ExportLink(export, exportingLibraryNode));
- }
-
- /**
- * Registers all non-private locally declared members of the library of this
- * node to be exported. This forms the basis for the work-list computation of
- * the export scopes performed in [LibraryDependencyHandler.computeExports].
- */
- void registerInitialExports() {
- for (Element element in library.getNonPrivateElementsInScope()) {
- pendingExportMap[element] = const Link<ExportElement>();
- }
- }
-
- /// Register the already computed export scope of [exportedLibraryElement] to
- /// export from the library of this node through the [export] declaration
- /// with the given combination [filter].
- ///
- /// Additionally, check that all names in the show/hide combinators are in the
- /// export scope of [exportedLibraryElement].
- void registerHandledExports(
- DiagnosticReporter reporter,
- LibraryElement exportedLibraryElement,
- ExportElementX export,
- CombinatorFilter filter) {
- assert(exportedLibraryElement.exportsHandled, failedAt(library));
- exportedLibraryElement.forEachExport((Element exportedElement) {
- if (!filter.exclude(exportedElement)) {
- Link<ExportElement> exports = pendingExportMap.putIfAbsent(
- exportedElement, () => const Link<ExportElement>());
- pendingExportMap[exportedElement] = exports.prepend(export);
- }
- });
- if (!reporter.options.suppressHints) {
- reporter.withCurrentElement(library, () {
- checkLibraryDependency(reporter, export.node, exportedLibraryElement);
- });
- }
- }
-
- /**
- * Registers the compute export scope with the node library.
- */
- void registerExports() {
- library.setExports(exportScope.values.toList());
- }
-
- /**
- * Registers the imports of the node library.
- */
- void registerImports(DiagnosticReporter reporter) {
- for (ImportLink link in imports) {
- link.importLibrary(reporter, library);
- }
- }
-
- /**
- * Copies and clears pending export set for this node.
- */
- Map<Element, Link<ExportElement>> pullPendingExports() {
- Map<Element, Link<ExportElement>> pendingExports =
- new Map<Element, Link<ExportElement>>.from(pendingExportMap);
- pendingExportMap.clear();
- return pendingExports;
- }
-
- /**
- * Adds [element] to the export scope for this node. If the [element] name
- * is a duplicate, an error element is inserted into the export scope.
- */
- Element addElementToExportScope(DiagnosticReporter reporter, Element element,
- Link<ExportElement> exports) {
- String name = element.name;
- DiagnosticMessage error;
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-
- void createDuplicateExportMessage(
- Element duplicate, Link<ExportElement> duplicateExports) {
- assert(
- !duplicateExports.isEmpty,
- failedAt(
- library,
- "No export for $duplicate from ${duplicate.library} "
- "in $library."));
- reporter.withCurrentElement(library, () {
- for (ExportElement export in duplicateExports) {
- if (error == null) {
- error = reporter.createMessage(
- export, MessageKind.DUPLICATE_EXPORT, {'name': name});
- } else {
- infos.add(reporter.createMessage(
- export, MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}));
- }
- }
- });
- }
-
- void createDuplicateExportDeclMessage(
- Element duplicate, Link<ExportElement> duplicateExports) {
- assert(
- !duplicateExports.isEmpty,
- failedAt(
- library,
- "No export for $duplicate from ${duplicate.library} "
- "in $library."));
- infos.add(reporter.createMessage(
- duplicate,
- MessageKind.DUPLICATE_EXPORT_DECL,
- {'name': name, 'uriString': duplicateExports.head.uri}));
- }
-
- Element existingElement = exportScope[name];
- if (existingElement != null && existingElement != element) {
- if (existingElement.isMalformed) {
- createDuplicateExportMessage(element, exports);
- createDuplicateExportDeclMessage(element, exports);
- element = existingElement;
- } else if (existingElement.library == library) {
- // Do nothing. [existingElement] hides [element].
- } else if (element.library == library) {
- // [element] hides [existingElement].
- exportScope[name] = element;
- exporters[element] = exports;
- } else {
- // Declared elements hide exported elements.
- Link<ExportElement> existingExports = exporters[existingElement];
- createDuplicateExportMessage(existingElement, existingExports);
- createDuplicateExportMessage(element, exports);
- createDuplicateExportDeclMessage(existingElement, existingExports);
- createDuplicateExportDeclMessage(element, exports);
- element = exportScope[name] = new ErroneousElementX(
- MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
- }
- } else {
- exportScope[name] = element;
- exporters[element] = exports;
- }
- if (error != null) {
- reporter.reportError(error, infos);
- }
- return element;
- }
-
- /**
- * Propagates the exported [element] to all library nodes that depend upon
- * this node. If the propagation updated any pending exports, [:true:] is
- * returned.
- */
- bool propagateElement(Element element) {
- bool change = false;
- for (ExportLink link in dependencies) {
- if (link.exportElement(element)) {
- change = true;
- }
- }
- return change;
- }
-
- /**
- * Adds [element] to the pending exports of this node and returns [:true:] if
- * the pending export set was modified. The combinators of [export] are used
- * to filter the element.
- */
- bool addElementToPendingExports(Element element, ExportElement export) {
- bool changed = false;
- if (!identical(exportScope[element.name], element)) {
- Link<ExportElement> exports = pendingExportMap.putIfAbsent(element, () {
- changed = true;
- return const Link<ExportElement>();
- });
- pendingExportMap[element] = exports.prepend(export);
- }
- return changed;
- }
-
- /// Check that all names in the show/hide combinators of imports and exports
- /// are in the export scope of the imported/exported libraries.
- void checkCombinators(DiagnosticReporter reporter) {
- reporter.withCurrentElement(library, () {
- for (ImportLink importLink in imports) {
- checkLibraryDependency(
- reporter, importLink.import.node, importLink.importedLibrary);
- }
- });
- for (ExportLink exportLink in dependencies) {
- reporter.withCurrentElement(exportLink.exportNode.library, () {
- checkLibraryDependency(reporter, exportLink.export.node, library);
- });
- }
- }
-
- /// Check that all names in the show/hide combinators of [tag] are in the
- /// export scope of [library].
- void checkLibraryDependency(DiagnosticReporter reporter,
- LibraryDependency tag, LibraryElement library) {
- if (tag == null || tag.combinators == null) return;
- for (Combinator combinator in tag.combinators) {
- for (Identifier identifier in combinator.identifiers) {
- String name = identifier.source;
- Element element = library.findExported(name);
- if (element == null) {
- if (combinator.isHide) {
- if (library.isPackageLibrary &&
- reporter.options.hidePackageWarnings) {
- // Only report hide hint on packages if we show warnings on these:
- // The hide may be non-empty in some versions of the package, in
- // which case you shouldn't remove the combinator.
- continue;
- }
- reporter.reportHintMessage(identifier, MessageKind.EMPTY_HIDE,
- {'uri': library.canonicalUri, 'name': name});
- } else if (!library.isDartCore || name != 'dynamic') {
- // TODO(sigmund): remove this condition, we don't report a hint for
- // `import "dart:core" show dynamic;` until our tools match in
- // semantics (see #29125).
- reporter.reportHintMessage(identifier, MessageKind.EMPTY_SHOW,
- {'uri': library.canonicalUri, 'name': name});
- }
- }
- }
- }
- }
-}
-
-/**
- * Helper class used for computing the possibly cyclic import/export scopes of
- * a set of libraries.
- *
- * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded
- * libraries and to compute their import/export scopes through a fixed-point
- * algorithm.
- */
-class LibraryDependencyHandler implements LibraryLoader {
- final ResolutionLibraryLoaderTask task;
- final List<LibraryElement> _newLibraries = <LibraryElement>[];
-
- /**
- * Newly loaded libraries and their corresponding node in the library
- * dependency graph. Libraries that have already been fully loaded are not
- * part of the dependency graph of this handler since their export scopes have
- * already been computed.
- */
- Map<LibraryElement, LibraryDependencyNode> nodeMap =
- new Map<LibraryElement, LibraryDependencyNode>();
-
- LibraryDependencyHandler(this.task);
-
- DiagnosticReporter get reporter => task.reporter;
-
- /// The libraries created with this handler.
- Iterable<LibraryElement> get newLibraries => _newLibraries;
-
- /**
- * Performs a fixed-point computation on the export scopes of all registered
- * libraries and creates the import/export of the libraries based on the
- * fixed-point.
- */
- void computeExports() {
- bool changed = true;
- while (changed) {
- changed = false;
- Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>> tasks =
- new Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>>();
-
- // Locally defined elements take precedence over exported
- // elements. So we must propagate local elements first. We
- // ensure this by pulling the pending exports before
- // propagating. This enforces that we handle exports
- // breadth-first, with locally defined elements being level 0.
- nodeMap.forEach((_, LibraryDependencyNode node) {
- Map<Element, Link<ExportElement>> pendingExports =
- node.pullPendingExports();
- tasks[node] = pendingExports;
- });
- tasks.forEach((LibraryDependencyNode node,
- Map<Element, Link<ExportElement>> pendingExports) {
- pendingExports.forEach((Element element, Link<ExportElement> exports) {
- element = node.addElementToExportScope(reporter, element, exports);
- if (node.propagateElement(element)) {
- changed = true;
- }
- });
- });
- }
-
- // Setup export scopes. These have to be set before computing the import
- // scopes to avoid accessing uncomputed export scopes during handling of
- // imports.
- nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
- node.registerExports();
- });
-
- // Setup import scopes.
- nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
- node.registerImports(reporter);
- });
-
- if (!reporter.options.suppressHints) {
- nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
- node.checkCombinators(reporter);
- });
- }
- }
-
- /// Registers that [library] depends on [loadedLibrary] through
- /// [libraryDependency].
- void registerDependency(
- LibraryElementX library,
- LibraryDependencyElementX libraryDependency,
- LibraryElement loadedLibrary) {
- if (libraryDependency.isExport) {
- // [loadedLibrary] is exported by [library].
- LibraryDependencyNode exportingNode = nodeMap[library];
- if (loadedLibrary.exportsHandled) {
- // Export scope already computed on [loadedLibrary].
- CombinatorFilter combinatorFilter =
- new CombinatorFilter.fromTag(libraryDependency.node);
- exportingNode.registerHandledExports(
- reporter, loadedLibrary, libraryDependency, combinatorFilter);
- return;
- }
- LibraryDependencyNode exportedNode = nodeMap[loadedLibrary];
- assert(exportedNode != null,
- failedAt(loadedLibrary, "$loadedLibrary has not been registered"));
- assert(exportingNode != null,
- failedAt(library, "$library has not been registered"));
- exportedNode.registerExportDependency(libraryDependency, exportingNode);
- } else if (libraryDependency == null || libraryDependency.isImport) {
- // [loadedLibrary] is imported by [library].
- LibraryDependencyNode importingNode = nodeMap[library];
- assert(importingNode != null,
- failedAt(library, "$library has not been registered"));
- importingNode.registerImportDependency(libraryDependency, loadedLibrary);
- }
- }
-
- /**
- * Registers [library] for the processing of its import/export scope.
- */
- void registerNewLibrary(LibraryElement library) {
- _newLibraries.add(library);
- if (!library.exportsHandled) {
- nodeMap[library] = new LibraryDependencyNode(library);
- }
- }
-
- /**
- * Registers all top-level entities of [library] as starting point for the
- * fixed-point computation of the import/export scopes.
- */
- void registerLibraryExports(LibraryElement library) {
- nodeMap[library].registerInitialExports();
- }
-
- Future processLibraryTags(LibraryElement library) {
- return task.processLibraryTags(this, library);
- }
-}
-
/// Information on the set libraries loaded as a result of a call to
/// [LibraryLoader.loadLibrary].
abstract class LoadedLibraries {
@@ -1526,104 +340,6 @@
{bool callback(Link<Uri> importChainReversed)});
}
-class _LoadedLibraries implements LoadedLibraries {
- final LibraryElement rootLibrary;
- final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{};
- final List<LibraryElement> _newLibraries;
-
- _LoadedLibraries(this.rootLibrary, this._newLibraries) {
- _newLibraries.forEach((LibraryElement loadedLibrary) {
- loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary;
- });
- assert(rootLibrary != null);
- }
-
- bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri);
-
- LibraryElement getLibrary(Uri uri) => loadedLibraries[uri];
-
- void forEachLibrary(f(LibraryElement library)) => _newLibraries.forEach(f);
-
- void forEachImportChain(Uri targetUri,
- {bool callback(Link<Uri> importChainReversed)}) {
- bool aborted = false;
-
- /// Map from libraries to the set of (unreversed) paths to [uri].
- Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap =
- <LibraryElement, Iterable<Link<Uri>>>{};
-
- /// Computes the set of (unreversed) paths to [targetUri].
- ///
- /// Finds all paths (suffixes) from the current library to [uri] and stores
- /// it in [suffixChainMap].
- ///
- /// For every found suffix it prepends the given [prefix] and the canonical
- /// uri of [library] and invokes the [callback] with the concatenated chain.
- void computeSuffixes(LibraryElement library, Link<Uri> prefix) {
- if (aborted) return;
-
- Uri canonicalUri = library.canonicalUri;
- prefix = prefix.prepend(canonicalUri);
- if (suffixChainMap.containsKey(library)) return;
- suffixChainMap[library] = const <Link<Uri>>[];
- List<Link<Uri>> suffixes = [];
- if (targetUri != canonicalUri) {
- /// Process the import (or export) of [importedLibrary].
- void processLibrary(LibraryElement importedLibrary) {
- bool suffixesArePrecomputed =
- suffixChainMap.containsKey(importedLibrary);
-
- if (!suffixesArePrecomputed) {
- computeSuffixes(importedLibrary, prefix);
- if (aborted) return;
- }
-
- for (Link<Uri> suffix in suffixChainMap[importedLibrary]) {
- suffixes.add(suffix.prepend(canonicalUri));
-
- if (suffixesArePrecomputed) {
- // Only report chains through [import] if the suffixes had already
- // been computed, otherwise [computeSuffixes] have reported the
- // paths through [prefix].
- Link<Uri> chain = prefix;
- while (!suffix.isEmpty) {
- chain = chain.prepend(suffix.head);
- suffix = suffix.tail;
- }
- if (!callback(chain)) {
- aborted = true;
- return;
- }
- }
- }
- }
-
- for (ImportElement import in library.imports) {
- processLibrary(import.importedLibrary);
- if (aborted) return;
- }
- for (ExportElement export in library.exports) {
- processLibrary(export.exportedLibrary);
- if (aborted) return;
- }
- } else {
- // Here `targetUri == canonicalUri`.
- if (!callback(prefix)) {
- aborted = true;
- return;
- }
- suffixes.add(const Link<Uri>().prepend(canonicalUri));
- }
- suffixChainMap[library] = suffixes;
- return;
- }
-
- computeSuffixes(rootLibrary, const Link<Uri>());
- }
-
- String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
-}
-
/// Adapter class to mimic the behavior of LoadedLibraries for Kernel element
/// behavior. Ultimately we'll just access worldBuilder instead.
class _LoadedLibrariesAdapter implements LoadedLibraries {
@@ -1652,23 +368,3 @@
String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
}
-
-/// API used by the library loader to request scripts from the compiler system.
-abstract class ScriptLoader {
- /// Load script from a readable [uri], report any errors using the location of
- /// the given [spannable].
- Future<Script> readScript(Uri uri, [Spannable spannable]);
-
- /// Load a binary from a readable [uri], report any errors using the location
- /// of the given [spannable].
- Future<Binary> readBinary(Uri uri, [Spannable spannable]);
-}
-
-/// API used by the library loader to synchronously scan a library or
-/// compilation unit and ensure that their library tags are computed.
-abstract class ElementScanner {
- void scanLibrary(LibraryElement library);
- void scanUnit(CompilationUnitElement unit);
-}
-
-const _reuseLibrarySubtaskName = "Reuse library";
diff --git a/pkg/compiler/lib/src/mirrors_used.dart b/pkg/compiler/lib/src/mirrors_used.dart
deleted file mode 100644
index c295a27..0000000
--- a/pkg/compiler/lib/src/mirrors_used.dart
+++ /dev/null
@@ -1,578 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.mirrors_used;
-
-import 'common/tasks.dart' show CompilerTask;
-import 'common.dart';
-import 'compile_time_constants.dart' show ConstantCompiler;
-import 'compiler.dart' show Compiler;
-import 'constants/expressions.dart';
-import 'constants/values.dart'
- show
- ConstantValue,
- ConstructedConstantValue,
- ListConstantValue,
- StringConstantValue,
- TypeConstantValue;
-import 'elements/resolution_types.dart'
- show ResolutionDartType, ResolutionInterfaceType;
-import 'elements/elements.dart'
- show
- ClassElement,
- Element,
- FieldElement,
- ImportElement,
- LibraryElement,
- MetadataAnnotation,
- ScopeContainerElement;
-import 'elements/entities.dart';
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'tree/tree.dart' show NamedArgument, NewExpression, Node;
-
-/**
- * Compiler task that analyzes MirrorsUsed annotations.
- *
- * When importing 'dart:mirrors', it is possible to annotate the import with
- * MirrorsUsed annotation. This is a way to declare what elements will be
- * reflected on at runtime. Such elements, even they would normally be
- * discarded by the implicit tree-shaking algorithm must be preserved in the
- * final output.
- *
- * Since some libraries cannot tell exactly what they will be reflecting on, it
- * is possible for one library to specify a MirrorsUsed annotation that applies
- * to another library. For example:
- *
- * Mirror utility library that cannot tell what it is reflecting on:
- * library mirror_utils;
- * import 'dart:mirrors';
- * ...
- *
- * The main app which knows how it use the mirror utility library:
- * library main_app;
- * @MirrorsUsed(override='mirror_utils')
- * import 'dart:mirrors';
- * import 'mirror_utils.dart';
- * ...
- *
- * In this case, we say that @MirrorsUsed in main_app overrides @MirrorsUsed in
- * mirror_utils.
- *
- * It is possible to override all libraries using override='*'. If multiple
- * catch-all overrides like this, they are merged together.
- *
- * It is possible for library "a" to declare that it overrides library "b", and
- * vice versa. In this case, both annotations will be discarded and the
- * compiler will emit a hint (that is, a warning that is not specified by the
- * language specification).
- *
- * After applying all the overrides, we can iterate over libraries that import
- * 'dart:mirrors'. If a library does not have an associated MirrorsUsed
- * annotation, then we have to discard all MirrorsUsed annotations and assume
- * everything can be reflected on.
- *
- * On the other hand, if all libraries importing dart:mirrors have a
- * MirrorsUsed annotation, these annotations are merged.
- *
- * MERGING MIRRORSUSED
- *
- * TBD.
- */
-class MirrorUsageAnalyzerTask extends CompilerTask {
- Set<LibraryElement> librariesWithUsage;
- MirrorUsageAnalyzer analyzer;
- final Compiler compiler;
-
- MirrorUsageAnalyzerTask(Compiler compiler)
- : compiler = compiler,
- super(compiler.measurer) {
- analyzer = new MirrorUsageAnalyzer(compiler, this);
- }
-
- /// Collect @MirrorsUsed annotations in all libraries. Called by the
- /// compiler after all libraries are loaded, but before resolution.
- void analyzeUsage(LibraryEntity mainApp) {
- if (mainApp == null ||
- compiler.resolution.commonElements.mirrorsLibrary == null) {
- return;
- }
- measure(analyzer.run);
- List<String> symbols = analyzer.mergedMirrorUsage.symbols;
- List<Element> targets = analyzer.mergedMirrorUsage.targets;
- List<Element> metaTargets = analyzer.mergedMirrorUsage.metaTargets;
- compiler.backend.mirrorsDataBuilder.registerMirrorUsage(
- symbols == null ? null : new Set<String>.from(symbols),
- targets == null ? null : new Set<Element>.from(targets),
- metaTargets == null ? null : new Set<Element>.from(metaTargets));
- librariesWithUsage = analyzer.librariesWithUsage;
- }
-
- /// Is there a @MirrorsUsed annotation in the library of [element]? Used by
- /// the resolver to suppress hints about using new Symbol or
- /// MirrorSystem.getName.
- bool hasMirrorUsage(Element element) {
- LibraryElement library = element.library;
- // Internal libraries always have implicit mirror usage.
- return library.isInternalLibrary ||
- (librariesWithUsage != null && librariesWithUsage.contains(library));
- }
-
- /// Call-back from the resolver to analyze MirrorsUsed annotations. The result
- /// is stored in [analyzer] and later used to compute
- /// [:analyzer.mergedMirrorUsage:].
- void validate(NewExpression node, TreeElements mapping) {
- for (Node argument in node.send.arguments) {
- NamedArgument named = argument.asNamedArgument();
- if (named == null) continue;
- ConstantCompiler constantCompiler = compiler.resolver.constantCompiler;
- ConstantValue value = constantCompiler.getConstantValue(
- constantCompiler.compileNode(named.expression, mapping));
-
- MirrorUsageBuilder builder = new MirrorUsageBuilder(analyzer,
- mapping.analyzedElement.library, named.expression, value, mapping);
-
- if (named.name.source == 'symbols') {
- analyzer.cachedStrings[value] =
- builder.convertConstantToUsageList(value, onlyStrings: true);
- } else if (named.name.source == 'targets') {
- analyzer.cachedElements[value] =
- builder.resolveUsageList(builder.convertConstantToUsageList(value));
- } else if (named.name.source == 'metaTargets') {
- analyzer.cachedElements[value] =
- builder.resolveUsageList(builder.convertConstantToUsageList(value));
- } else if (named.name.source == 'override') {
- analyzer.cachedElements[value] =
- builder.resolveUsageList(builder.convertConstantToUsageList(value));
- }
- }
- }
-}
-
-class MirrorUsageAnalyzer {
- final Compiler compiler;
- final MirrorUsageAnalyzerTask task;
- List<LibraryElement> wildcard;
- final Set<LibraryElement> librariesWithUsage;
- final Map<ConstantValue, List<String>> cachedStrings;
- final Map<ConstantValue, List<Element>> cachedElements;
- MirrorUsage mergedMirrorUsage;
-
- MirrorUsageAnalyzer(this.compiler, this.task)
- : librariesWithUsage = new Set<LibraryElement>(),
- cachedStrings = new Map<ConstantValue, List<String>>(),
- cachedElements = new Map<ConstantValue, List<Element>>();
-
- DiagnosticReporter get reporter => compiler.reporter;
-
- /// Collect and merge all @MirrorsUsed annotations. As a side-effect, also
- /// compute which libraries have the annotation (which is used by
- /// [MirrorUsageAnalyzerTask.hasMirrorUsage]).
- void run() {
- wildcard = compiler.libraryLoader.libraries.toList();
- Map<LibraryElement, List<MirrorUsage>> usageMap =
- collectMirrorsUsedAnnotation();
- propagateOverrides(usageMap);
- Set<LibraryElement> librariesWithoutUsage = new Set<LibraryElement>();
- usageMap.forEach((LibraryElement library, List<MirrorUsage> usage) {
- if (usage.isEmpty) librariesWithoutUsage.add(library);
- });
- if (librariesWithoutUsage.isEmpty) {
- mergedMirrorUsage = mergeUsages(usageMap);
- } else {
- mergedMirrorUsage = new MirrorUsage(null, null, null, null);
- }
- }
-
- /// Collect all @MirrorsUsed from all libraries and represent them as
- /// [MirrorUsage].
- Map<LibraryElement, List<MirrorUsage>> collectMirrorsUsedAnnotation() {
- Map<LibraryElement, List<MirrorUsage>> result =
- new Map<LibraryElement, List<MirrorUsage>>();
- for (LibraryElement library in compiler.libraryLoader.libraries) {
- if (library.isInternalLibrary) continue;
- for (ImportElement import in library.imports) {
- reporter.withCurrentElement(library, () {
- List<MirrorUsage> usages = mirrorsUsedOnLibraryTag(library, import);
- if (usages != null) {
- List<MirrorUsage> existing = result[library];
- if (existing != null) {
- existing.addAll(usages);
- } else {
- result[library] = usages;
- }
- }
- });
- }
- }
- return result;
- }
-
- /// Apply [MirrorUsage] with 'override' to libraries they override.
- void propagateOverrides(Map<LibraryElement, List<MirrorUsage>> usageMap) {
- Map<LibraryElement, List<MirrorUsage>> propagatedOverrides =
- new Map<LibraryElement, List<MirrorUsage>>();
- usageMap.forEach((LibraryElement library, List<MirrorUsage> usages) {
- for (MirrorUsage usage in usages) {
- List<Element> override = usage.override;
- if (override == null) continue;
- if (override == wildcard) {
- for (LibraryElement overridden in wildcard) {
- if (overridden != library) {
- List<MirrorUsage> overriddenUsages = propagatedOverrides
- .putIfAbsent(overridden, () => <MirrorUsage>[]);
- overriddenUsages.add(usage);
- }
- }
- } else {
- for (Element overridden in override) {
- List<MirrorUsage> overriddenUsages = propagatedOverrides
- .putIfAbsent(overridden, () => <MirrorUsage>[]);
- overriddenUsages.add(usage);
- }
- }
- }
- });
- propagatedOverrides.forEach(
- (LibraryElement overridden, List<MirrorUsage> overriddenUsages) {
- List<MirrorUsage> usages =
- usageMap.putIfAbsent(overridden, () => <MirrorUsage>[]);
- usages.addAll(overriddenUsages);
- });
- }
-
- /// Find @MirrorsUsed annotations on the given import [tag] in [library]. The
- /// annotations are represented as [MirrorUsage].
- List<MirrorUsage> mirrorsUsedOnLibraryTag(
- LibraryElement library, ImportElement import) {
- LibraryElement importedLibrary = import.importedLibrary;
- if (importedLibrary != compiler.resolution.commonElements.mirrorsLibrary) {
- return null;
- }
- List<MirrorUsage> result = <MirrorUsage>[];
- for (MetadataAnnotation metadata in import.metadata) {
- metadata.ensureResolved(compiler.resolution);
- ConstantValue value =
- compiler.constants.getConstantValue(metadata.constant);
- ResolutionDartType type =
- value.getType(compiler.resolution.commonElements);
- Element element = type.element;
- if (element == compiler.resolution.commonElements.mirrorsUsedClass) {
- result.add(buildUsage(value));
- }
- }
- return result;
- }
-
- /// Merge all [MirrorUsage] instances across all libraries.
- MirrorUsage mergeUsages(Map<LibraryElement, List<MirrorUsage>> usageMap) {
- Set<MirrorUsage> usagesToMerge = new Set<MirrorUsage>();
- usageMap.forEach((LibraryElement library, List<MirrorUsage> usages) {
- librariesWithUsage.add(library);
- usagesToMerge.addAll(usages);
- });
- if (usagesToMerge.isEmpty) {
- return new MirrorUsage(null, wildcard, null, null);
- } else {
- MirrorUsage result = new MirrorUsage(null, null, null, null);
- for (MirrorUsage usage in usagesToMerge) {
- result = merge(result, usage);
- }
- return result;
- }
- }
-
- /// Merge [a] with [b]. The resulting [MirrorUsage] simply has the symbols,
- /// targets, and metaTargets of [a] and [b] concatenated. 'override' is
- /// ignored.
- MirrorUsage merge(MirrorUsage a, MirrorUsage b) {
- // TOOO(ahe): Should be an instance method on MirrorUsage.
- if (a.symbols == null && a.targets == null && a.metaTargets == null) {
- return b;
- } else if (b.symbols == null &&
- b.targets == null &&
- b.metaTargets == null) {
- return a;
- }
- // TODO(ahe): Test the following cases.
- List<String> symbols = a.symbols;
- if (symbols == null) {
- symbols = b.symbols;
- } else if (b.symbols != null) {
- symbols.addAll(b.symbols);
- }
- List<Element> targets = a.targets;
- if (targets == null) {
- targets = b.targets;
- } else if (targets != wildcard && b.targets != null) {
- targets.addAll(b.targets);
- }
- List<Element> metaTargets = a.metaTargets;
- if (metaTargets == null) {
- metaTargets = b.metaTargets;
- } else if (metaTargets != wildcard && b.metaTargets != null) {
- metaTargets.addAll(b.metaTargets);
- }
- return new MirrorUsage(symbols, targets, metaTargets, null);
- }
-
- /// Convert a [constant] to an instance of [MirrorUsage] using information
- /// that was resolved during [MirrorUsageAnalyzerTask.validate].
- MirrorUsage buildUsage(ConstructedConstantValue constant) {
- Map<FieldElement, ConstantValue> fields = constant.fields;
- ClassElement cls = compiler.resolution.commonElements.mirrorsUsedClass;
- FieldElement symbolsField = cls.lookupLocalMember('symbols');
- FieldElement targetsField = cls.lookupLocalMember('targets');
- FieldElement metaTargetsField = cls.lookupLocalMember('metaTargets');
- FieldElement overrideField = cls.lookupLocalMember('override');
-
- return new MirrorUsage(
- cachedStrings[fields[symbolsField]],
- cachedElements[fields[targetsField]],
- cachedElements[fields[metaTargetsField]],
- cachedElements[fields[overrideField]]);
- }
-}
-
-/// Used to represent a resolved MirrorsUsed constant.
-class MirrorUsage {
- final List<String> symbols;
- final List<Element> targets;
- final List<Element> metaTargets;
- final List<Element> override;
-
- MirrorUsage(this.symbols, this.targets, this.metaTargets, this.override);
-
- String toString() {
- return 'MirrorUsage('
- 'symbols = $symbols, '
- 'targets = $targets, '
- 'metaTargets = $metaTargets, '
- 'override = $override'
- ')';
- }
-}
-
-class MirrorUsageBuilder {
- final MirrorUsageAnalyzer analyzer;
- final LibraryElement enclosingLibrary;
- final Spannable spannable;
- final ConstantValue constant;
- final TreeElements elements;
-
- MirrorUsageBuilder(this.analyzer, this.enclosingLibrary, this.spannable,
- this.constant, this.elements);
-
- Compiler get compiler => analyzer.compiler;
-
- DiagnosticReporter get reporter => analyzer.reporter;
-
- /// Convert a constant to a list of [String] and [Type] values. If the
- /// constant is a single [String], it is assumed to be a comma-separated list
- /// of qualified names. If the constant is a [Type] t, the result is [:[t]:].
- /// Otherwise, the constant is assumed to represent a list of strings (each a
- /// qualified name) and types, and such a list is constructed. If
- /// [onlyStrings] is true, the returned list is a [:List<String>:] and any
- /// [Type] values are treated as an error (meaning that the value is ignored
- /// and a hint is emitted).
- List convertConstantToUsageList(ConstantValue constant,
- {bool onlyStrings: false}) {
- if (constant.isNull) {
- return null;
- } else if (constant.isList) {
- ListConstantValue list = constant;
- List result = onlyStrings ? <String>[] : [];
- for (ConstantValue entry in list.entries) {
- if (entry.isString) {
- StringConstantValue string = entry;
- result.add(string.stringValue);
- } else if (!onlyStrings && entry.isType) {
- TypeConstantValue type = entry;
- result.add(type.representedType);
- } else {
- Spannable node = positionOf(entry);
- MessageKind kind = onlyStrings
- ? MessageKind.MIRRORS_EXPECTED_STRING
- : MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE;
- reporter.reportHintMessage(
- node, kind, {'name': node, 'type': apiTypeOf(entry)});
- }
- }
- return result;
- } else if (!onlyStrings && constant.isType) {
- TypeConstantValue type = constant;
- return [type.representedType];
- } else if (constant.isString) {
- StringConstantValue string = constant;
- var iterable = string.stringValue.split(',').map((e) => e.trim());
- return onlyStrings ? new List<String>.from(iterable) : iterable.toList();
- } else {
- Spannable node = positionOf(constant);
- MessageKind kind = onlyStrings
- ? MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST
- : MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST;
- reporter.reportHintMessage(
- node, kind, {'name': node, 'type': apiTypeOf(constant)});
- return null;
- }
- }
-
- /// Find the first non-implementation interface of constant.
- ResolutionDartType apiTypeOf(ConstantValue constant) {
- ResolutionDartType type =
- constant.getType(compiler.resolution.commonElements);
- LibraryElement library = type.element.library;
- if (type.isInterfaceType && library.isInternalLibrary) {
- ResolutionInterfaceType interface = type;
- ClassElement cls = type.element;
- cls.ensureResolved(compiler.resolution);
- for (ResolutionInterfaceType supertype in cls.allSupertypes) {
- if (supertype.isInterfaceType &&
- !supertype.element.library.isInternalLibrary) {
- return interface.asInstanceOf(supertype.element);
- }
- }
- }
- return type;
- }
-
- /// Convert a list of strings and types to a list of elements. Types are
- /// converted to their corresponding element, and strings are resolved as
- /// follows:
- ///
- /// First find the longest library name that is a prefix of the string, if
- /// there are none, resolve using [resolveExpression]. Otherwise, resolve the
- /// rest of the string using [resolveLocalExpression].
- List<Element> resolveUsageList(List list) {
- if (list == null) return null;
- if (list.length == 1 && list[0] == '*') {
- return analyzer.wildcard;
- }
- List<Element> result = <Element>[];
- for (var entry in list) {
- if (entry is ResolutionDartType) {
- ResolutionDartType type = entry;
- result.add(type.element);
- } else {
- String string = entry;
- LibraryElement libraryCandidate;
- String libraryNameCandidate;
- for (LibraryElement l in compiler.libraryLoader.libraries) {
- if (l.hasLibraryName) {
- String libraryName = l.libraryName;
- if (string == libraryName) {
- // Found an exact match.
- libraryCandidate = l;
- libraryNameCandidate = libraryName;
- break;
- } else if (string.startsWith('$libraryName.')) {
- if (libraryNameCandidate == null ||
- libraryNameCandidate.length < libraryName.length) {
- // Found a better candidate
- libraryCandidate = l;
- libraryNameCandidate = libraryName;
- }
- }
- }
- }
- Element e;
- if (libraryNameCandidate == string) {
- e = libraryCandidate;
- } else if (libraryNameCandidate != null) {
- e = resolveLocalExpression(libraryCandidate,
- string.substring(libraryNameCandidate.length + 1).split('.'));
- } else {
- e = resolveExpression(string);
- }
- if (e != null) result.add(e);
- }
- }
- return result;
- }
-
- /// Resolve [expression] in [enclosingLibrary]'s import scope.
- Element resolveExpression(String expression) {
- List<String> identifiers = expression.split('.');
- Element element = enclosingLibrary.find(identifiers[0]);
- if (element == null) {
- reporter.reportHintMessage(
- spannable,
- MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY,
- {'name': expression});
- return null;
- } else {
- if (identifiers.length == 1) return element;
- return resolveLocalExpression(element, identifiers.sublist(1));
- }
- }
-
- /// Resolve [identifiers] in [element]'s local members.
- Element resolveLocalExpression(Element element, List<String> identifiers) {
- Element current = element;
- for (String identifier in identifiers) {
- Element e = findLocalMemberIn(current, identifier);
- if (e == null) {
- if (current.isLibrary) {
- LibraryElement library = current;
- reporter.reportHintMessage(
- spannable,
- MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY,
- {'name': identifiers[0], 'library': library.name});
- } else {
- reporter.reportHintMessage(
- spannable,
- MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT,
- {'name': identifier, 'element': current.name});
- }
- return current;
- }
- current = e;
- }
- return current;
- }
-
- /// Helper method to lookup members in a [ScopeContainerElement]. If
- /// [element] is not a ScopeContainerElement, return null.
- Element findLocalMemberIn(Element element, String name) {
- if (element is ScopeContainerElement) {
- ScopeContainerElement scope = element;
- if (element.isClass) {
- ClassElement cls = element;
- cls.ensureResolved(compiler.resolution);
- }
- return scope.localLookup(name);
- }
- return null;
- }
-
- /// Attempt to find a [Spannable] corresponding to constant.
- Spannable positionOf(ConstantValue constant) {
- Node node;
- elements.forEachConstantNode((Node n, ConstantExpression c) {
- if (node == null && compiler.constants.getConstantValue(c) == constant) {
- node = n;
- }
- });
- if (node == null) {
- // TODO(ahe): Returning [spannable] here leads to confusing error
- // messages. For example, consider:
- // @MirrorsUsed(targets: fisk)
- // import 'dart:mirrors';
- //
- // const fisk = const [main];
- //
- // main() {}
- //
- // The message is:
- // example.dart:1:23: Hint: Can't use 'fisk' here because ...
- // Did you forget to add quotes?
- // @MirrorsUsed(targets: fisk)
- // ^^^^
- //
- // Instead of saying 'fisk' should pretty print the problematic constant
- // value.
- return spannable;
- }
- return node;
- }
-}
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index a862a9d..dc624c1 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -3,21 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
import '../common.dart';
-import '../common/backend_api.dart' show ForeignResolver;
-import '../common/resolution.dart' show ParsingContext, Resolution;
-import '../compiler.dart' show Compiler;
import '../constants/values.dart';
import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../elements/elements.dart';
import '../elements/entities.dart';
-import '../elements/resolution_types.dart';
import '../elements/types.dart';
import '../js/js.dart' as js;
import '../js_backend/native_data.dart' show NativeBasicData;
-import '../resolution/resolution_strategy.dart';
-import '../tree/tree.dart';
import '../universe/side_effects.dart' show SideEffects;
-import '../util/util.dart';
import 'js.dart';
typedef dynamic /*DartType|SpecialType*/ TypeLookup(String typeString,
@@ -495,61 +487,6 @@
return sideEffects;
}
- /// Returns a [TypeLookup] that uses [resolver] to perform lookup and [node]
- /// as position for errors.
- static TypeLookup _typeLookup(
- Node node, DiagnosticReporter reporter, ForeignResolver resolver) {
- ResolutionDartType lookup(String name, {bool required}) {
- ResolutionDartType type = resolver.resolveTypeFromString(node, name);
- if (type == null && required) {
- reporter.reportErrorMessage(
- node, MessageKind.GENERIC, {'text': "Type '$name' not found."});
- }
- return type;
- }
-
- return lookup;
- }
-
- /// Compute the [NativeBehavior] for a [Send] node calling the 'JS' function.
- static NativeBehavior ofJsCallSend(
- Send jsCall,
- DiagnosticReporter reporter,
- ParsingContext parsing,
- CommonElements commonElements,
- ForeignResolver resolver) {
- var argNodes = jsCall.arguments;
- if (argNodes.isEmpty || argNodes.tail.isEmpty) {
- reporter.reportErrorMessage(jsCall, MessageKind.WRONG_ARGUMENT_FOR_JS);
- return new NativeBehavior();
- }
-
- dynamic specArgument = argNodes.head;
- if (specArgument is! StringNode || specArgument.isInterpolation) {
- reporter.reportErrorMessage(
- specArgument, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST);
- return new NativeBehavior();
- }
-
- dynamic codeArgument = argNodes.tail.head;
- if (codeArgument is! StringNode || codeArgument.isInterpolation) {
- reporter.reportErrorMessage(
- codeArgument, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
- return new NativeBehavior();
- }
-
- String specString = specArgument.dartString.slowToString();
- String codeString = codeArgument.dartString.slowToString();
-
- return ofJsCall(
- specString,
- codeString,
- _typeLookup(specArgument, reporter, resolver),
- specArgument,
- reporter,
- commonElements);
- }
-
/// Compute the [NativeBehavior] for a call to the 'JS' function with the
/// given [specString] and [codeString] (first and second arguments).
static NativeBehavior ofJsCall(
@@ -636,50 +573,6 @@
nullType: commonElements.nullType);
}
- static NativeBehavior ofJsBuiltinCallSend(
- Send jsBuiltinCall,
- DiagnosticReporter reporter,
- CommonElements commonElements,
- ForeignResolver resolver) {
- NativeBehavior behavior = new NativeBehavior();
- behavior.sideEffects.setTo(new SideEffects());
-
- // The first argument of a JS-embedded global call is a string encoding
- // the type of the code.
- //
- // 'Type1|Type2'. A union type.
- // '=Object'. A JavaScript Object, no subtype.
-
- Link<Node> argNodes = jsBuiltinCall.arguments;
- if (argNodes.isEmpty) {
- reporter.internalError(
- jsBuiltinCall, "JS builtin expression has no type.");
- }
-
- // We don't check the given name. That needs to be done at a later point.
- // This is, because we want to allow non-literals (like references to
- // enums) as names.
- if (argNodes.tail.isEmpty) {
- reporter.internalError(jsBuiltinCall, "JS builtin is missing name.");
- }
-
- LiteralString specLiteral = argNodes.head.asLiteralString();
- if (specLiteral == null) {
- // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It
- // is not very satisfactory because it does not work for void, dynamic.
- reporter.internalError(argNodes.head, "Unexpected first argument.");
- }
-
- String specString = specLiteral.dartString.slowToString();
-
- return ofJsBuiltinCall(
- specString,
- _typeLookup(jsBuiltinCall, reporter, resolver),
- jsBuiltinCall,
- reporter,
- commonElements);
- }
-
static NativeBehavior ofJsBuiltinCall(
String specString,
TypeLookup lookupType,
@@ -693,60 +586,6 @@
return behavior;
}
- static NativeBehavior ofJsEmbeddedGlobalCallSend(
- Send jsEmbeddedGlobalCall,
- DiagnosticReporter reporter,
- CommonElements commonElements,
- ForeignResolver resolver) {
- NativeBehavior behavior = new NativeBehavior();
- // TODO(sra): Allow the use site to override these defaults.
- // Embedded globals are usually pre-computed data structures or JavaScript
- // functions that never change.
- behavior.sideEffects.setTo(new SideEffects.empty());
- behavior.throwBehavior = NativeThrowBehavior.NEVER;
-
- // The first argument of a JS-embedded global call is a string encoding
- // the type of the code.
- //
- // 'Type1|Type2'. A union type.
- // '=Object'. A JavaScript Object, no subtype.
-
- Link<Node> argNodes = jsEmbeddedGlobalCall.arguments;
- if (argNodes.isEmpty) {
- reporter.internalError(
- jsEmbeddedGlobalCall, "JS embedded global expression has no type.");
- }
-
- // We don't check the given name. That needs to be done at a later point.
- // This is, because we want to allow non-literals (like references to
- // enums) as names.
- if (argNodes.tail.isEmpty) {
- reporter.internalError(
- jsEmbeddedGlobalCall, "JS embedded global is missing name.");
- }
-
- if (!argNodes.tail.tail.isEmpty) {
- reporter.internalError(argNodes.tail.tail.head,
- 'JS embedded global has more than 2 arguments');
- }
-
- LiteralString specLiteral = argNodes.head.asLiteralString();
- if (specLiteral == null) {
- // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It
- // is not very satisfactory because it does not work for void, dynamic.
- reporter.internalError(argNodes.head, "Unexpected first argument.");
- }
-
- String specString = specLiteral.dartString.slowToString();
-
- return ofJsEmbeddedGlobalCall(
- specString,
- _typeLookup(jsEmbeddedGlobalCall, reporter, resolver),
- jsEmbeddedGlobalCall,
- reporter,
- commonElements);
- }
-
static NativeBehavior ofJsEmbeddedGlobalCall(
String specString,
TypeLookup lookupType,
@@ -765,72 +604,11 @@
return behavior;
}
- static NativeBehavior ofMethodElement(
- MethodElement element, Compiler compiler,
- {bool isJsInterop}) {
- ResolutionFunctionType type = element.computeType(compiler.resolution);
- List<ConstantValue> metadata = <ConstantValue>[];
- for (MetadataAnnotation annotation in element.implementation.metadata) {
- annotation.ensureResolved(compiler.resolution);
- metadata.add(compiler.constants.getConstantValue(annotation.constant));
- }
-
- BehaviorBuilder builder = new ResolverBehaviorBuilder(
- compiler, compiler.frontendStrategy.nativeBasicData);
- return builder.buildMethodBehavior(
- type, metadata, lookupFromElement(compiler.resolution, element),
- isJsInterop: isJsInterop);
- }
-
- static NativeBehavior ofFieldElementLoad(
- MemberElement element, Compiler compiler,
- {bool isJsInterop}) {
- Resolution resolution = compiler.resolution;
- ResolutionDartType type = element.computeType(resolution);
- List<ConstantValue> metadata = <ConstantValue>[];
- for (MetadataAnnotation annotation in element.implementation.metadata) {
- annotation.ensureResolved(compiler.resolution);
- metadata.add(compiler.constants.getConstantValue(annotation.constant));
- }
-
- BehaviorBuilder builder = new ResolverBehaviorBuilder(
- compiler, compiler.frontendStrategy.nativeBasicData);
- return builder.buildFieldLoadBehavior(
- type, metadata, lookupFromElement(resolution, element),
- isJsInterop: isJsInterop);
- }
-
- static NativeBehavior ofFieldElementStore(
- MemberElement field, Compiler compiler) {
- BehaviorBuilder builder = new ResolverBehaviorBuilder(
- compiler, compiler.frontendStrategy.nativeBasicData);
- ResolutionDartType type = field.computeType(compiler.resolution);
- return builder.buildFieldStoreBehavior(type);
- }
-
- static TypeLookup lookupFromElement(Resolution resolution, Element element) {
- ResolutionDartType lookup(String name, {bool required}) {
- Element e = element.buildScope().lookup(name);
- if (e == null || e is! ClassElement) {
- if (required) {
- resolution.reporter.reportErrorMessage(element, MessageKind.GENERIC,
- {'text': "Type '$name' not found."});
- }
- return null;
- }
- ClassElement cls = e;
- cls.ensureResolved(resolution);
- return cls.thisType;
- }
-
- return lookup;
- }
-
static dynamic /*DartType|SpecialType*/ _parseType(
String typeString, TypeLookup lookupType) {
if (typeString == '=Object') return SpecialType.JsObject;
if (typeString == 'dynamic') {
- return const ResolutionDynamicType();
+ return const DynamicType();
}
int index = typeString.indexOf('<');
var type = lookupType(typeString, required: index == -1);
@@ -843,7 +621,7 @@
return type;
}
}
- return const ResolutionDynamicType();
+ return const DynamicType();
}
}
@@ -1025,26 +803,3 @@
return _behavior;
}
}
-
-class ResolverBehaviorBuilder extends BehaviorBuilder {
- final Compiler compiler;
- final NativeBasicData nativeBasicData;
-
- ResolverBehaviorBuilder(this.compiler, this.nativeBasicData);
-
- @override
- CommonElements get commonElements => compiler.resolution.commonElements;
-
- @override
- bool get trustJSInteropTypeAnnotations =>
- compiler.options.trustJSInteropTypeAnnotations;
-
- @override
- DiagnosticReporter get reporter => compiler.reporter;
-
- @override
- ElementEnvironment get elementEnvironment {
- ResolutionFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
- return frontendStrategy.elementEnvironment;
- }
-}
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index c79894f..0de573e 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -5,11 +5,10 @@
import '../common_elements.dart' show CommonElements, ElementEnvironment;
import '../elements/entities.dart';
import '../elements/types.dart';
-import '../js_backend/backend_usage.dart' show BackendUsageBuilder;
import '../js_backend/native_data.dart' show NativeData;
import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
import '../options.dart';
-import '../universe/use.dart' show StaticUse, TypeUse;
+import '../universe/use.dart' show TypeUse;
import '../universe/world_impact.dart'
show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl;
import 'behavior.dart';
@@ -150,18 +149,7 @@
return _unusedClasses.where(predicate);
}
- void _registerBackendUse(FunctionEntity element) {}
-
Iterable<ClassEntity> _onFirstNativeClass(WorldImpactBuilder impactBuilder) {
- void staticUse(FunctionEntity element) {
- impactBuilder.registerStaticUse(new StaticUse.implicitInvoke(element));
- _registerBackendUse(element);
- }
-
- staticUse(_commonElements.defineProperty);
- staticUse(_commonElements.toStringForNativeObject);
- staticUse(_commonElements.hashCodeForNativeObject);
- staticUse(_commonElements.closureConverter);
return _findNativeExceptions();
}
@@ -184,7 +172,6 @@
class NativeResolutionEnqueuer extends NativeEnqueuerBase {
final NativeClassFinder _nativeClassFinder;
- final BackendUsageBuilder _backendUsageBuilder;
/// The set of all native classes. Each native class is in [nativeClasses]
/// and exactly one of [unusedClasses] and [registeredClasses].
@@ -195,7 +182,6 @@
ElementEnvironment elementEnvironment,
CommonElements commonElements,
DartTypes dartTypes,
- this._backendUsageBuilder,
this._nativeClassFinder)
: super(options, elementEnvironment, commonElements, dartTypes);
@@ -205,11 +191,6 @@
Iterable<ClassEntity> get liveNativeClasses => _registeredClasses;
- void _registerBackendUse(FunctionEntity element) {
- _backendUsageBuilder.registerBackendFunctionUse(element);
- _backendUsageBuilder.registerGlobalFunctionDependency(element);
- }
-
WorldImpact processNativeClasses(Iterable<LibraryEntity> libraries) {
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
Iterable<ClassEntity> nativeClasses =
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index 5b50350..ae0ce99 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -7,8 +7,6 @@
export 'behavior.dart';
export 'enqueue.dart';
export 'js.dart';
-export 'scanner.dart';
-export 'ssa.dart';
const Iterable<String> _allowedDartSchemePaths = const <String>[
'async',
diff --git a/pkg/compiler/lib/src/native/resolver.dart b/pkg/compiler/lib/src/native/resolver.dart
index 9f7ff83..5da0d2e 100644
--- a/pkg/compiler/lib/src/native/resolver.dart
+++ b/pkg/compiler/lib/src/native/resolver.dart
@@ -2,74 +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.
-import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import 'package:front_end/src/scanner/token.dart' show BeginToken;
-
import '../common.dart';
import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../common/backend_api.dart';
-import '../common/resolution.dart';
-import '../compiler.dart' show Compiler;
import '../constants/values.dart';
-import '../elements/elements.dart'
- show
- ClassElement,
- Element,
- FieldElement,
- MemberElement,
- MetadataAnnotation,
- MethodElement;
import '../elements/entities.dart';
-import '../elements/modelx.dart' show FunctionElementX, MetadataAnnotationX;
-import '../elements/resolution_types.dart' show ResolutionDartType;
-import '../js_backend/js_backend.dart';
import '../js_backend/native_data.dart';
-import '../patch_parser.dart';
-import '../tree/tree.dart';
import 'behavior.dart';
/// Interface for computing native members.
abstract class NativeMemberResolver {
- /// Computes whether [element] is native or JsInterop and, if so, registers
- /// its [NativeBehavior]s to [registry].
- void resolveNativeMember(MemberEntity element, [NativeRegistry registry]);
-}
-
-/// Interface for computing native members and [NativeBehavior]s in member code
-/// based on the AST.
-abstract class NativeDataResolver implements NativeMemberResolver {
- /// Returns `true` if [element] is a JsInterop member.
- bool isJsInteropMember(MemberElement element);
-
- /// Computes the [NativeBehavior] for a `JS` call, which can be an
- /// instantiation point for types.
- ///
- /// For example, the following code instantiates and returns native classes
- /// that are `_DOMWindowImpl` or a subtype.
- ///
- /// JS('_DOMWindowImpl', 'window')
- ///
- NativeBehavior resolveJsCall(Send node, ForeignResolver resolver);
-
- /// Computes the [NativeBehavior] for a `JS_EMBEDDED_GLOBAL` call, which can
- /// be an instantiation point for types.
- ///
- /// For example, the following code instantiates and returns a String class
- ///
- /// JS_EMBEDDED_GLOBAL('String', 'foo')
- ///
- NativeBehavior resolveJsEmbeddedGlobalCall(
- Send node, ForeignResolver resolver);
-
- /// Computes the [NativeBehavior] for a `JS_BUILTIN` call, which can be an
- /// instantiation point for types.
- ///
- /// For example, the following code instantiates and returns a String class
- ///
- /// JS_BUILTIN('String', 'int2string', 0)
- ///
- NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver);
+ /// Computes whether [element] is native or JsInterop.
+ void resolveNativeMember(MemberEntity element);
}
abstract class NativeMemberResolverBase implements NativeMemberResolver {
@@ -90,7 +33,7 @@
NativeBehavior computeNativeFieldStoreBehavior(covariant FieldEntity field);
@override
- void resolveNativeMember(MemberEntity element, [NativeRegistry registry]) {
+ void resolveNativeMember(MemberEntity element) {
bool isJsInterop = isJsInteropMember(element);
if (element.isFunction ||
element.isConstructor ||
@@ -102,7 +45,6 @@
NativeBehavior behavior =
computeNativeMethodBehavior(method, isJsInterop: isJsInterop);
nativeDataBuilder.setNativeMethodBehavior(method, behavior);
- registry?.registerNativeData(behavior);
}
} else if (element.isField) {
FieldEntity field = element;
@@ -115,13 +57,6 @@
nativeDataBuilder.setNativeFieldLoadBehavior(field, fieldLoadBehavior);
nativeDataBuilder.setNativeFieldStoreBehavior(
field, fieldStoreBehavior);
-
- // TODO(sra): Process fields for storing separately.
- // We have to handle both loading and storing to the field because we
- // only get one look at each member and there might be a load or store
- // we have not seen yet.
- registry?.registerNativeData(fieldLoadBehavior);
- registry?.registerNativeData(fieldStoreBehavior);
}
}
}
@@ -208,180 +143,6 @@
}
}
-class NativeDataResolverImpl extends NativeMemberResolverBase
- implements NativeDataResolver {
- final Compiler _compiler;
-
- NativeDataResolverImpl(this._compiler);
-
- JavaScriptBackend get _backend => _compiler.backend;
- DiagnosticReporter get _reporter => _compiler.reporter;
- ElementEnvironment get elementEnvironment =>
- _compiler.resolution.elementEnvironment;
- CommonElements get commonElements => _compiler.resolution.commonElements;
- NativeBasicData get nativeBasicData =>
- _compiler.frontendStrategy.nativeBasicData;
- NativeDataBuilder get nativeDataBuilder => _backend.nativeDataBuilder;
-
- @override
- bool isJsInteropMember(MemberElement element) {
- // TODO(johnniwinther): Avoid computing this twice for external function;
- // once from JavaScriptBackendTarget.resolveExternalFunction and once
- // through JavaScriptBackendTarget.resolveNativeMember.
- bool isJsInterop =
- checkJsInteropMemberAnnotations(_compiler, element, nativeDataBuilder);
- // TODO(johnniwinther): Avoid this duplication of logic from
- // NativeData.isJsInterop.
- if (!isJsInterop && element is MethodElement && element.isExternal) {
- if (element.enclosingClass != null) {
- isJsInterop = nativeBasicData.isJsInteropClass(element.enclosingClass);
- } else {
- isJsInterop = nativeBasicData.isJsInteropLibrary(element.library);
- }
- }
- return isJsInterop;
- }
-
- @override
- NativeBehavior computeNativeMethodBehavior(MethodElement function,
- {bool isJsInterop}) {
- return NativeBehavior.ofMethodElement(function, _compiler,
- isJsInterop: isJsInterop);
- }
-
- @override
- NativeBehavior computeNativeFieldLoadBehavior(FieldElement field,
- {bool isJsInterop}) {
- return NativeBehavior.ofFieldElementLoad(field, _compiler,
- isJsInterop: isJsInterop);
- }
-
- @override
- NativeBehavior computeNativeFieldStoreBehavior(FieldElement field) {
- return NativeBehavior.ofFieldElementStore(field, _compiler);
- }
-
- @override
- bool isNativeMethod(FunctionElementX element) {
- if (!_backend.canLibraryUseNative(element.library)) return false;
- // Native method?
- return _reporter.withCurrentElement(element, () {
- Node node = element.parseNode(_compiler.resolution.parsingContext);
- if (node is! FunctionExpression) return false;
- FunctionExpression functionExpression = node;
- node = functionExpression.body;
- Token token = node.getBeginToken();
- if (identical(token.stringValue, 'native')) {
- element.isMarkedNative = true;
- return true;
- }
- return false;
- });
- }
-
- @override
- NativeBehavior resolveJsCall(Send node, ForeignResolver resolver) {
- return NativeBehavior.ofJsCallSend(
- node, _reporter, _compiler.parsingContext, commonElements, resolver);
- }
-
- @override
- NativeBehavior resolveJsEmbeddedGlobalCall(
- Send node, ForeignResolver resolver) {
- return NativeBehavior.ofJsEmbeddedGlobalCallSend(
- node, _reporter, commonElements, resolver);
- }
-
- @override
- NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver) {
- return NativeBehavior.ofJsBuiltinCallSend(
- node, _reporter, commonElements, resolver);
- }
-}
-
-/// Annotation handler for pre-resolution detection of `@Native(...)`
-/// annotations.
-class NativeAnnotationHandler extends EagerAnnotationHandler<String> {
- final NativeBasicDataBuilder _nativeBasicDataBuilder;
-
- NativeAnnotationHandler(this._nativeBasicDataBuilder);
-
- String getNativeAnnotation(MetadataAnnotationX annotation) {
- if (annotation.beginToken != null &&
- annotation.beginToken.next.lexeme == 'Native') {
- // Skipping '@', 'Native', and '('.
- Token argument = annotation.beginToken.next.next.next;
- if (argument is StringToken) {
- return argument.lexeme;
- }
- }
- return null;
- }
-
- String apply(
- Compiler compiler, Element element, MetadataAnnotation annotation) {
- if (element.isClass) {
- ClassElement cls = element;
- String native = getNativeAnnotation(annotation);
- if (native != null) {
- String tagText = native.substring(1, native.length - 1);
- _nativeBasicDataBuilder.setNativeClassTagInfo(cls, tagText);
- return native;
- }
- }
- return null;
- }
-
- void validate(Compiler compiler, Element element,
- MetadataAnnotation annotation, ConstantValue constant) {
- ResolutionDartType annotationType =
- constant.getType(compiler.resolution.commonElements);
- if (annotationType.element !=
- compiler.resolution.commonElements.nativeAnnotationClass) {
- DiagnosticReporter reporter = compiler.reporter;
- reporter.internalError(annotation, 'Invalid @Native(...) annotation.');
- }
- }
-}
-
-bool checkJsInteropMemberAnnotations(Compiler compiler, MemberElement element,
- NativeDataBuilder nativeDataBuilder) {
- bool isJsInterop = EagerAnnotationHandler.checkAnnotation(
- compiler, element, const JsInteropAnnotationHandler());
- if (isJsInterop) {
- nativeDataBuilder.markAsJsInteropMember(element);
- }
- return isJsInterop;
-}
-
-/// Annotation handler for pre-resolution detection of `@JS(...)`
-/// annotations.
-class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> {
- const JsInteropAnnotationHandler();
-
- bool hasJsNameAnnotation(MetadataAnnotationX annotation) =>
- annotation.beginToken != null &&
- annotation.beginToken.next.lexeme == 'JS';
-
- bool apply(
- Compiler compiler, Element element, MetadataAnnotation annotation) {
- return hasJsNameAnnotation(annotation);
- }
-
- @override
- void validate(Compiler compiler, Element element,
- MetadataAnnotation annotation, ConstantValue constant) {
- ResolutionDartType type =
- constant.getType(compiler.resolution.commonElements);
- if (type.element != compiler.resolution.commonElements.jsAnnotationClass) {
- compiler.reporter
- .internalError(annotation, 'Invalid @JS(...) annotation.');
- }
- }
-
- bool get defaultResult => false;
-}
-
/// Determines all native classes in a set of libraries.
abstract class NativeClassFinder {
/// Returns the set of all native classes declared in [libraries].
@@ -390,22 +151,16 @@
class BaseNativeClassFinder implements NativeClassFinder {
final ElementEnvironment _elementEnvironment;
- final CommonElements _commonElements;
final NativeBasicData _nativeBasicData;
Map<String, ClassEntity> _tagOwner = new Map<String, ClassEntity>();
- BaseNativeClassFinder(
- this._elementEnvironment, this._commonElements, this._nativeBasicData);
+ BaseNativeClassFinder(this._elementEnvironment, this._nativeBasicData);
Iterable<ClassEntity> computeNativeClasses(
Iterable<LibraryEntity> libraries) {
Set<ClassEntity> nativeClasses = new Set<ClassEntity>();
libraries.forEach((l) => _processNativeClassesInLibrary(l, nativeClasses));
- if (_commonElements.isolateHelperLibrary != null) {
- _processNativeClassesInLibrary(
- _commonElements.isolateHelperLibrary, nativeClasses);
- }
_processSubclassesOfNativeClasses(libraries, nativeClasses);
return nativeClasses;
}
@@ -502,98 +257,6 @@
}
}
-/// Native class finder that extends [BaseNativeClassFinder] to handle
-/// unresolved classes encountered during the native classes computation.
-class ResolutionNativeClassFinder extends BaseNativeClassFinder {
- final DiagnosticReporter _reporter;
- final Resolution _resolution;
-
- ResolutionNativeClassFinder(
- this._resolution,
- this._reporter,
- ElementEnvironment elementEnvironment,
- CommonElements commonElements,
- NativeBasicData nativeBasicData)
- : super(elementEnvironment, commonElements, nativeBasicData);
-
- void _processNativeClass(
- ClassElement classElement, Set<ClassEntity> nativeClasses) {
- // Resolve class to ensure the class has valid inheritance info.
- classElement.ensureResolved(_resolution);
- super._processNativeClass(classElement, nativeClasses);
- }
-
- /**
- * Returns the source string of the class named in the extends clause, or
- * `null` if there is no extends clause.
- */
- String _findExtendsNameOfClass(ClassElement classElement) {
- if (classElement.isResolved) {
- ClassElement superClass = classElement.superclass;
- while (superClass != null) {
- if (!superClass.isUnnamedMixinApplication) {
- return superClass.name;
- }
- superClass = superClass.superclass;
- }
- return null;
- }
-
- // "class B extends A ... {}" --> "A"
- // "class B extends foo.A ... {}" --> "A"
- // "class B<T> extends foo.A<T,T> with M1, M2 ... {}" --> "A"
-
- // We want to avoid calling classElement.parseNode on every class. Doing so
- // will slightly increase parse time and size and cause compiler errors and
- // warnings to me emitted in more unused code.
-
- // An alternative to this code is to extend the API of ClassElement to
- // expose the name of the extended element.
-
- // Pattern match the above cases in the token stream.
- // [abstract] class X extends [id.]* id
-
- Token skipTypeParameters(Token token) {
- BeginToken beginGroupToken = token;
- Token endToken = beginGroupToken.endGroup;
- return endToken.next;
- //for (;;) {
- // token = token.next;
- // if (token.stringValue == '>') return token.next;
- // if (token.stringValue == '<') return skipTypeParameters(token);
- //}
- }
-
- String scanForExtendsName(Token token) {
- if (token.stringValue == 'abstract') token = token.next;
- if (token.stringValue != 'class') return null;
- token = token.next;
- if (!token.isIdentifier) return null;
- token = token.next;
- // class F<X extends B<X>> extends ...
- if (token.stringValue == '<') {
- token = skipTypeParameters(token);
- }
- if (token.stringValue != 'extends') return null;
- token = token.next;
- Token id = token;
- while (token.kind != Tokens.EOF_TOKEN) {
- token = token.next;
- if (token.stringValue != '.') break;
- token = token.next;
- if (!token.isIdentifier) return null;
- id = token;
- }
- // Should be at '{', 'with', 'implements', '<' or 'native'.
- return id.lexeme;
- }
-
- return _reporter.withCurrentElement(classElement, () {
- return scanForExtendsName(classElement.position);
- });
- }
-}
-
/// Returns `true` if [value] is named annotation based on [annotationClass].
bool isAnnotation(
Spannable spannable, ConstantValue value, ClassEntity annotationClass) {
diff --git a/pkg/compiler/lib/src/native/scanner.dart b/pkg/compiler/lib/src/native/scanner.dart
deleted file mode 100644
index ee0edcb..0000000
--- a/pkg/compiler/lib/src/native/scanner.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import '../common.dart';
-import '../parser/element_listener.dart' show ElementListener;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
- show STRING_TOKEN;
-import 'package:front_end/src/scanner/token.dart' show BeginToken;
-
-void checkAllowedLibrary(ElementListener listener, Token token) {
- if (listener.scannerOptions.canUseNative) return;
- listener.reportErrorFromToken(token, MessageKind.NATIVE_NOT_SUPPORTED);
-}
-
-Token handleNativeBlockToSkip(ElementListener listener, Token token) {
- checkAllowedLibrary(listener, token);
- token = token.next;
- if (identical(token.kind, Tokens.STRING_TOKEN)) {
- token = token.next;
- }
- if (identical(token.stringValue, '{')) {
- BeginToken beginGroupToken = token;
- token = beginGroupToken.endGroup;
- }
- return token;
-}
-
-Token handleNativeFunctionBody(ElementListener listener, Token token) {
- checkAllowedLibrary(listener, token);
- Token begin = token;
- listener.beginReturnStatement(token);
- token = token.next;
- bool hasExpression = false;
- if (identical(token.kind, Tokens.STRING_TOKEN)) {
- hasExpression = true;
- listener.beginLiteralString(token);
- token = token.next;
- listener.endLiteralString(0, token);
- }
- listener.endReturnStatement(hasExpression, begin, token);
- // TODO(ngeoffray): expect a ';'.
- // Currently there are method with both native marker and Dart body.
- return token.next;
-}
diff --git a/pkg/compiler/lib/src/native/ssa.dart b/pkg/compiler/lib/src/native/ssa.dart
deleted file mode 100644
index 240df64..0000000
--- a/pkg/compiler/lib/src/native/ssa.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import '../common.dart';
-import '../constants/values.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../js/js.dart' as js;
-import '../js_emitter/js_emitter.dart' show NativeEmitter;
-import '../ssa/builder.dart' show SsaAstGraphBuilder;
-import '../ssa/nodes.dart' show HInstruction, HForeignCode, HReturn;
-import '../tree/tree.dart';
-import '../universe/side_effects.dart' show SideEffects;
-
-final RegExp nativeRedirectionRegExp = new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$');
-
-void handleSsaNative(SsaAstGraphBuilder builder, Expression nativeBody) {
- MethodElement element = builder.target;
- NativeEmitter nativeEmitter = builder.nativeEmitter;
-
- HInstruction convertDartClosure(
- ParameterElement parameter, ResolutionFunctionType type) {
- HInstruction local = builder.localsHandler.readLocal(parameter);
- ConstantValue arityConstant =
- builder.constantSystem.createInt(type.parameterTypes.length);
- HInstruction arity =
- builder.graph.addConstant(arityConstant, builder.closedWorld);
- // TODO(ngeoffray): For static methods, we could pass a method with a
- // defined arity.
- MethodElement helper = builder.commonElements.closureConverter;
- builder.pushInvokeStatic(nativeBody, helper, [local, arity]);
- HInstruction closure = builder.pop();
- return closure;
- }
-
- // Check which pattern this native method follows:
- // 1) foo() native;
- // hasBody = false
- // 2) foo() native "bar";
- // No longer supported, this is now done with @JSName('foo') and case 1.
- // 3) foo() native "return 42";
- // hasBody = true
- bool hasBody = false;
- assert(builder.nativeData.isNativeMember(element));
- String nativeMethodName = builder.nativeData.getFixedBackendName(element);
- if (nativeBody != null) {
- LiteralString jsCode = nativeBody.asLiteralString();
- String str = jsCode.dartString.slowToString();
- if (nativeRedirectionRegExp.hasMatch(str)) {
- failedAt(nativeBody, "Deprecated syntax, use @JSName('name') instead.");
- }
- hasBody = true;
- }
-
- if (!hasBody) {
- nativeEmitter.nativeMethods.add(element);
- }
-
- FunctionSignature parameters = element.functionSignature;
- if (!hasBody) {
- List<String> arguments = <String>[];
- List<HInstruction> inputs = <HInstruction>[];
- String receiver = '';
- if (element.isInstanceMember) {
- receiver = '#.';
- inputs.add(builder.localsHandler.readThis());
- }
- parameters.forEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- ResolutionDartType type = parameter.type.unaliased;
- HInstruction input = builder.localsHandler.readLocal(parameter);
- if (type is ResolutionFunctionType) {
- // The parameter type is a function type either directly or through
- // typedef(s).
- input = convertDartClosure(parameter, type);
- }
- inputs.add(input);
- arguments.add('#');
- });
-
- String foreignParameters = arguments.join(',');
- String nativeMethodCall;
- if (element.kind == ElementKind.FUNCTION) {
- nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)';
- } else if (element.kind == ElementKind.GETTER) {
- nativeMethodCall = '$receiver$nativeMethodName';
- } else if (element.kind == ElementKind.SETTER) {
- nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters';
- } else {
- failedAt(element, 'Unexpected kind: "${element.kind}".');
- }
-
- builder.push(new HForeignCode(
- // TODO(sra): This could be cached. The number of templates should
- // be proportional to the number of native methods, which is bounded
- // by the dart: libraries.
- js.js.uncachedExpressionTemplate(nativeMethodCall),
- builder.commonMasks.dynamicType,
- inputs,
- effects: new SideEffects()));
- // TODO(johnniwinther): Provide source information.
- builder
- .close(new HReturn(builder.abstractValueDomain, builder.pop(), null))
- .addSuccessor(builder.graph.exit);
- } else {
- if (parameters.parameterCount != 0) {
- failedAt(
- nativeBody,
- 'native "..." syntax is restricted to '
- 'functions with zero parameters.');
- }
- LiteralString jsCode = nativeBody.asLiteralString();
- builder.push(new HForeignCode.statement(
- js.js.statementTemplateYielding(
- new js.LiteralStatement(jsCode.dartString.slowToString())),
- <HInstruction>[],
- new SideEffects(),
- null,
- builder.commonMasks.dynamicType));
- }
-}
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index 52b4d61..67c594a 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -6,9 +6,7 @@
import 'common.dart';
import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
-import 'elements/elements.dart' show ClassElement;
import 'elements/entities.dart';
-import 'elements/resolution_types.dart';
import 'elements/types.dart';
import 'util/util.dart' show Link, LinkBuilder;
import 'package:front_end/src/fasta/util/link_implementation.dart'
@@ -305,21 +303,3 @@
return sb.toString();
}
}
-
-class ResolutionOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
- ResolutionOrderedTypeSetBuilder(ClassElement cls, InterfaceType objectType,
- {DiagnosticReporter reporter})
- : super(cls, objectType, reporter: reporter);
-
- InterfaceType getThisType(ClassElement cls) => cls.thisType;
-
- ResolutionInterfaceType substByContext(
- ResolutionInterfaceType type, ResolutionInterfaceType context) {
- return type.substByContext(context);
- }
-
- int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
-
- OrderedTypeSet getOrderedTypeSet(ClassElement cls) =>
- cls.allSupertypesAndSelf;
-}
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
deleted file mode 100644
index 0e93cb0..0000000
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.diet.task;
-
-import '../common.dart';
-import '../common/tasks.dart' show CompilerTask, Measurer;
-import '../elements/elements.dart' show CompilationUnitElement;
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../id_generator.dart';
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'element_listener.dart' show ElementListener, ScannerOptions;
-import 'package:front_end/src/fasta/parser.dart'
- show Listener, MemberKind, ParserError, TopLevelParser;
-
-class PartialParser extends TopLevelParser {
- PartialParser(Listener listener) : super(listener);
-
- Token parseFormalParameters(Token token, MemberKind kind) {
- return skipFormalParameters(token, kind);
- }
-}
-
-class DietParserTask extends CompilerTask {
- final IdGenerator _idGenerator;
- final JavaScriptBackend _backend;
- final DiagnosticReporter _reporter;
-
- DietParserTask(
- this._idGenerator, this._backend, this._reporter, Measurer measurer)
- : super(measurer);
-
- final String name = 'Diet Parser';
-
- dietParse(CompilationUnitElement compilationUnit, Token tokens) {
- measure(() {
- ScannerOptions scannerOptions = new ScannerOptions(
- canUseNative: _backend.canLibraryUseNative(compilationUnit.library));
- ElementListener listener = new ElementListener(
- scannerOptions, _reporter, compilationUnit, _idGenerator);
- PartialParser parser = new PartialParser(listener);
- try {
- parser.parseUnit(tokens);
- } on ParserError catch (_) {
- // TODO(johnniwinther): assert that the error was reported once there is
- // a [hasErrorBeenReported] field in [DiagnosticReporter]
- // The error should have already been reported by the parser.
- }
- });
- }
-}
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
deleted file mode 100644
index 081a066..0000000
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ /dev/null
@@ -1,1031 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.element_listener;
-
-import 'package:front_end/src/fasta/fasta_codes.dart' show Message;
-
-import 'package:front_end/src/fasta/fasta_codes.dart' as codes;
-
-import '../common.dart';
-import '../diagnostics/messages.dart' show MessageTemplate;
-import '../elements/elements.dart'
- show Element, LibraryElement, MetadataAnnotation;
-import '../elements/modelx.dart'
- show
- CompilationUnitElementX,
- DeclarationSite,
- ElementX,
- EnumClassElementX,
- FieldElementX,
- LibraryElementX,
- MetadataAnnotationX,
- NamedMixinApplicationElementX,
- VariableList;
-import '../id_generator.dart';
-import '../native/native.dart' as native;
-import '../string_validator.dart' show StringValidator;
-import 'package:front_end/src/fasta/scanner.dart'
- show ErrorToken, StringToken, Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link, LinkBuilder;
-import 'package:front_end/src/fasta/parser.dart'
- show Listener, ParserError, optional;
-import 'package:front_end/src/fasta/parser/identifier_context.dart'
- show IdentifierContext;
-import 'package:front_end/src/scanner/token.dart' show KeywordToken, TokenType;
-import 'partial_elements.dart'
- show
- PartialClassElement,
- PartialElement,
- PartialFieldList,
- PartialFunctionElement,
- PartialMetadataAnnotation,
- PartialTypedefElement;
-
-const bool VERBOSE = false;
-
-/// Options used for scanning.
-///
-/// Use this to conditionally support special tokens.
-///
-/// TODO(johnniwinther): This class should be renamed, it is not about options
-/// in the same sense as `CompilerOptions` or `DiagnosticOptions`.
-class ScannerOptions {
- /// If `true` the pseudo keyword `native` is supported.
- final bool canUseNative;
-
- const ScannerOptions({this.canUseNative: false});
-}
-
-/**
- * A parser event listener designed to work with [PartialParser]. It
- * builds elements representing the top-level declarations found in
- * the parsed compilation unit and records them in
- * [compilationUnitElement].
- */
-class ElementListener extends Listener {
- final IdGenerator idGenerator;
- final DiagnosticReporter reporter;
- final ScannerOptions scannerOptions;
- final CompilationUnitElementX compilationUnitElement;
- final StringValidator stringValidator;
- Link<StringQuoting> interpolationScope;
-
- Link<Node> nodes = const Link<Node>();
-
- LinkBuilder<MetadataAnnotation> metadata =
- new LinkBuilder<MetadataAnnotation>();
-
- /// Indicates whether the parser is currently accepting a type variable.
- bool inTypeVariable = false;
-
- /// Records a stack of booleans for each member parsed (a stack is used to
- /// support nested members which isn't currently possible, but it also serves
- /// as a simple way to tell we're currently parsing a member). In this case,
- /// member refers to members of a library or a class (but currently, classes
- /// themselves are not considered members). If the top of the stack
- /// (memberErrors.head) is true, the current member has already reported at
- /// least one parse error.
- Link<bool> memberErrors = const Link<bool>();
-
- bool suppressParseErrors = false;
-
- /// Set to true each time we parse a native function body. It is reset in
- /// [handleInvalidFunctionBody] which is called immediately after.
- bool lastErrorWasNativeFunctionBody = false;
-
- LiteralString nativeName;
-
- ElementListener(this.scannerOptions, DiagnosticReporter reporter,
- this.compilationUnitElement, this.idGenerator)
- : this.reporter = reporter,
- stringValidator = new StringValidator(reporter),
- interpolationScope = const Link<StringQuoting>();
-
- @override
- Uri get uri => compilationUnitElement?.script?.resourceUri;
-
- bool get currentMemberHasParseError {
- return !memberErrors.isEmpty && memberErrors.head;
- }
-
- void pushQuoting(StringQuoting quoting) {
- interpolationScope = interpolationScope.prepend(quoting);
- }
-
- StringQuoting popQuoting() {
- StringQuoting result = interpolationScope.head;
- interpolationScope = interpolationScope.tail;
- return result;
- }
-
- StringNode popLiteralString() {
- StringNode node = popNode();
- // TODO(lrn): Handle interpolations in script tags.
- if (node.isInterpolation) {
- reporter.internalError(
- node, "String interpolation not supported in library tags.");
- return null;
- }
- return node;
- }
-
- bool allowLibraryTags() {
- // Library tags are only allowed in the library file itself, not
- // in sourced files.
- LibraryElement library = compilationUnitElement.implementationLibrary;
- return !compilationUnitElement.hasMembers &&
- library.entryCompilationUnit == compilationUnitElement;
- }
-
- @override
- void endLibraryName(Token libraryKeyword, Token semicolon) {
- Expression name = popNode();
- addLibraryTag(new LibraryName(
- libraryKeyword, name, popMetadata(compilationUnitElement)));
- }
-
- @override
- void handleImportPrefix(Token deferredKeyword, Token asKeyword) {
- if (asKeyword == null) {
- // If asKeyword is null, then no prefix has been pushed on the stack.
- // Push a placeholder indicating that there is no prefix.
- pushNode(null);
- }
- pushNode(deferredKeyword != null ? Flag.TRUE : Flag.FALSE);
- }
-
- @override
- void endImport(Token importKeyword, Token semicolon) {
- NodeList combinators = popNode();
- Flag flag = popNode();
- bool isDeferred = flag == Flag.TRUE;
- Identifier prefix = popNode();
- NodeList conditionalUris = popNode();
- StringNode uri = popLiteralString();
- addLibraryTag(new Import(importKeyword, uri, conditionalUris, prefix,
- combinators, popMetadata(compilationUnitElement),
- isDeferred: isDeferred));
- }
-
- @override
- void handleRecoverImport(Token semicolon) {
- popNode(); // combinators
- popNode(); // isDeferred
- popNode(); // prefix
- popNode(); // conditionalUris
- // TODO(danrubel): recover
- }
-
- @override
- void handleDottedName(int count, Token token) {
- NodeList identifiers = makeNodeList(count, null, null, '.');
- pushNode(new DottedName(token, identifiers));
- }
-
- @override
- void endConditionalUris(int count) {
- if (count == 0) {
- pushNode(null);
- } else {
- pushNode(makeNodeList(count, null, null, " "));
- }
- }
-
- @override
- void endConditionalUri(Token ifToken, Token leftParen, Token equalSign) {
- StringNode uri = popNode();
- LiteralString conditionValue = (equalSign != null) ? popNode() : null;
- DottedName identifier = popNode();
- pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
- }
-
- @override
- void endEnum(Token enumKeyword, Token leftBrace, int count) {
- NodeList names = makeNodeList(count, leftBrace, leftBrace?.endGroup, ",");
- Identifier name = popNode();
-
- int id = idGenerator.getNextFreeId();
- Element enclosing = compilationUnitElement;
- pushElement(new EnumClassElementX(
- name.source, enclosing, id, new Enum(enumKeyword, name, names)));
- rejectBuiltInIdentifier(name);
- }
-
- @override
- void endExport(Token exportKeyword, Token semicolon) {
- NodeList combinators = popNode();
- NodeList conditionalUris = popNode();
- StringNode uri = popNode();
- addLibraryTag(new Export(exportKeyword, uri, conditionalUris, combinators,
- popMetadata(compilationUnitElement)));
- }
-
- @override
- void endCombinators(int count) {
- if (0 == count) {
- pushNode(null);
- } else {
- pushNode(makeNodeList(count, null, null, " "));
- }
- }
-
- @override
- void endHide(Token hideKeyword) => pushCombinator(hideKeyword);
-
- @override
- void endShow(Token showKeyword) => pushCombinator(showKeyword);
-
- void pushCombinator(Token keywordToken) {
- NodeList identifiers = popNode();
- pushNode(new Combinator(identifiers, keywordToken));
- }
-
- @override
- void handleIdentifierList(int count) {
- pushNode(makeNodeList(count, null, null, ","));
- }
-
- @override
- void endTypeList(int count) {
- pushNode(makeNodeList(count, null, null, ","));
- }
-
- @override
- void endPart(Token partKeyword, Token semicolon) {
- StringNode uri = popLiteralString();
- addLibraryTag(
- new Part(partKeyword, uri, popMetadata(compilationUnitElement)));
- }
-
- @override
- void endPartOf(
- Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
- Expression name = popNode();
- addPartOfTag(
- new PartOf(partKeyword, name, popMetadata(compilationUnitElement)));
- }
-
- void addPartOfTag(PartOf tag) {
- compilationUnitElement.setPartOf(tag, reporter);
- }
-
- @override
- void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
- if (periodBeforeName != null) {
- popNode(); // Discard name.
- }
- popNode(); // Discard type parameters
- popNode(); // Discard identifier
- // TODO(paulberry,ahe): type variable metadata should not be ignored. See
- // dartbug.com/5841.
- if (!inTypeVariable) {
- pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
- }
- }
-
- @override
- void endTopLevelDeclaration(Token token) {
- if (!metadata.isEmpty) {
- MetadataAnnotationX first = metadata.first;
- recoverableError(reporter.spanFromToken(first.beginToken),
- 'Metadata not supported here.');
- metadata.clear();
- }
- }
-
- @override
- void handleNativeFunctionBody(Token nativeToken, Token semicolon) {}
-
- @override
- void handleClassImplements(Token implementsKeyword, int interfacesCount) {
- makeNodeList(interfacesCount, implementsKeyword, null, ","); // interfaces
- }
-
- @override
- void handleRecoverClassHeader() {
- popNode(); // superType
- }
-
- @override
- void endClassDeclaration(Token beginToken, Token endToken) {
- popNode(); // superType
- popNode(); // typeParameters
- Identifier name = popNode();
- int id = idGenerator.getNextFreeId();
- PartialClassElement element = new PartialClassElement(
- name.source, beginToken, endToken, compilationUnitElement, id);
- pushElement(element);
- rejectBuiltInIdentifier(name);
- }
-
- void rejectBuiltInIdentifier(Identifier name) {
- if (name.token is KeywordToken) {
- TokenType type = name.token.type;
- if (!type.isPseudo) {
- recoverableError(name, "Illegal name '${type.lexeme}'.");
- }
- }
- }
-
- @override
- void endFunctionTypeAlias(
- Token typedefKeyword, Token equals, Token endToken) {
- Identifier name;
- if (equals == null) {
- popNode(); // TODO(karlklose): do not throw away typeVariables.
- name = popNode();
- popNode(); // returnType
- } else {
- popNode(); // Function type.
- popNode(); // TODO(karlklose): do not throw away typeVariables.
- name = popNode();
- }
- pushElement(new PartialTypedefElement(
- name.source, compilationUnitElement, typedefKeyword, endToken));
- rejectBuiltInIdentifier(name);
- }
-
- @override
- void beginNamedMixinApplication(
- Token begin, Token abstractToken, Token name) {
- if (abstractToken == null) {
- pushNode(Modifiers.EMPTY);
- } else {
- Link<Node> poppedNodes = const Link<Node>();
- poppedNodes = poppedNodes.prepend(new Identifier(abstractToken));
- NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- }
- }
-
- @override
- void endNamedMixinApplication(Token beginToken, Token classKeyword,
- Token equals, Token implementsKeyword, Token endToken) {
- NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
- MixinApplication mixinApplication = popNode();
- Modifiers modifiers = popNode();
- NodeList typeParameters = popNode();
- Identifier name = popNode();
- NamedMixinApplication namedMixinApplication = new NamedMixinApplication(
- name,
- typeParameters,
- modifiers,
- mixinApplication,
- interfaces,
- beginToken,
- endToken);
-
- int id = idGenerator.getNextFreeId();
- Element enclosing = compilationUnitElement;
- pushElement(new NamedMixinApplicationElementX(
- name.source, enclosing, id, namedMixinApplication));
- rejectBuiltInIdentifier(name);
- }
-
- @override
- void endMixinApplication(Token withKeyword) {
- NodeList mixins = popNode();
- NominalTypeAnnotation superclass = popNode();
- pushNode(new MixinApplication(superclass, mixins));
- }
-
- @override
- void handleVoidKeyword(Token token) {
- pushNode(new NominalTypeAnnotation(new Identifier(token), null));
- }
-
- @override
- void beginTopLevelMethod(Token lastConsumed, Token externalToken) {
- if (externalToken == null) {
- pushNode(Modifiers.EMPTY);
- } else {
- Link<Node> poppedNodes = const Link<Node>();
- poppedNodes = poppedNodes.prepend(new Identifier(externalToken));
- NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- }
- }
-
- @override
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
- bool hasParseError = currentMemberHasParseError;
- memberErrors = memberErrors.tail;
- popNode(); // typeVariables
- Identifier name = popNode();
- popNode(); // type
- Modifiers modifiers = popNode();
- PartialFunctionElement element = new PartialFunctionElement(name.source,
- beginToken, getOrSet, endToken, modifiers, compilationUnitElement);
- element.hasParseError = hasParseError;
- pushElement(element);
- }
-
- @override
- void endTopLevelFields(Token staticToken, Token covariantToken,
- Token varFinalOrConst, int count, Token beginToken, Token endToken) {
- bool hasParseError = currentMemberHasParseError;
- memberErrors = memberErrors.tail;
- void buildFieldElement(Identifier name, VariableList fields) {
- pushElement(new FieldElementX(name, compilationUnitElement, fields));
- }
-
- NodeList variables = makeNodeList(count, null, null, ",");
- popNode(); // type
- Modifiers modifiers =
- newFieldModifiers(staticToken, covariantToken, varFinalOrConst);
- buildFieldElements(modifiers, variables, compilationUnitElement,
- buildFieldElement, beginToken, endToken, hasParseError);
- }
-
- Modifiers newFieldModifiers(
- Token staticToken, Token covariantToken, Token varFinalOrConst) {
- Link<Node> modifierNodes = const Link<Node>();
- if (varFinalOrConst != null) {
- modifierNodes = modifierNodes.prepend(new Identifier(varFinalOrConst));
- }
- if (covariantToken != null) {
- modifierNodes = modifierNodes.prepend(new Identifier(covariantToken));
- }
- if (staticToken != null) {
- modifierNodes = modifierNodes.prepend(new Identifier(staticToken));
- }
- if (!modifierNodes.isNotEmpty) {
- return Modifiers.EMPTY;
- }
- return new Modifiers(new NodeList(null, modifierNodes, null, ' '));
- }
-
- @override
- void handleInvalidTopLevelDeclaration(Token endToken) {
- memberErrors = memberErrors.tail;
- }
-
- void buildFieldElements(
- Modifiers modifiers,
- NodeList variables,
- Element enclosingElement,
- void buildFieldElement(Identifier name, VariableList fields),
- Token beginToken,
- Token endToken,
- bool hasParseError) {
- VariableList fields =
- new PartialFieldList(beginToken, endToken, modifiers, hasParseError);
- for (Link<Node> variableNodes = variables.nodes;
- !variableNodes.isEmpty;
- variableNodes = variableNodes.tail) {
- Expression initializedIdentifier = variableNodes.head;
- Identifier identifier = initializedIdentifier.asIdentifier();
- if (identifier == null) {
- identifier = initializedIdentifier.asSendSet().selector.asIdentifier();
- }
- buildFieldElement(identifier, fields);
- }
- }
-
- @override
- void handleIdentifier(Token token, IdentifierContext context) {
- if (context == IdentifierContext.enumValueDeclaration) {
- metadata.clear();
- }
- pushNode(new Identifier(token));
- }
-
- @override
- void handleQualified(Token period) {
- Identifier last = popNode();
- Expression first = popNode();
- pushNode(new Send(first, last));
- }
-
- @override
- void handleNoConstructorReferenceContinuationAfterTypeArguments(
- Token token) {}
-
- @override
- void handleNoType(Token lastConsumed) {
- pushNode(null);
- }
-
- @override
- void beginTypeVariable(Token token) {
- inTypeVariable = true;
- }
-
- @override
- void endTypeVariable(Token token, Token extendsOrSuper) {
- inTypeVariable = false;
- NominalTypeAnnotation bound = popNode();
- Identifier name = popNode();
- pushNode(new TypeVariable(name, extendsOrSuper, bound));
- rejectBuiltInIdentifier(name);
- }
-
- @override
- void endTypeVariables(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ','));
- }
-
- @override
- void handleNoTypeVariables(Token token) {
- pushNode(null);
- }
-
- @override
- void endTypeArguments(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ','));
- }
-
- @override
- void handleNoTypeArguments(Token token) {
- pushNode(null);
- }
-
- @override
- void handleType(Token beginToken, Token endToken) {
- NodeList typeArguments = popNode();
- Expression typeName = popNode();
- pushNode(new NominalTypeAnnotation(typeName, typeArguments));
- }
-
- void handleNoName(Token token) {
- pushNode(null);
- }
-
- @override
- void endFunctionType(Token functionToken, Token endToken) {
- popNode(); // Return type.
- popNode(); // Type parameters.
- pushNode(null);
- }
-
- @override
- void handleParenthesizedExpression(Token token) {
- Expression expression = popNode();
- pushNode(new ParenthesizedExpression(expression, token));
- }
-
- @override
- Token handleUnrecoverableError(Token token, Message message) {
- Token next = handleError(token, message);
- if (next == null &&
- message.code != codes.codeUnterminatedComment &&
- message.code != codes.codeUnterminatedString) {
- throw new ParserError.fromTokens(token, token, message);
- } else {
- return next;
- }
- }
-
- @override
- void handleRecoverableError(
- Message message, Token startToken, Token endToken) {
- if (message == codes.messageNativeClauseShouldBeAnnotation) {
- native.checkAllowedLibrary(this, startToken);
- return;
- }
- handleError(startToken, message);
- }
-
- @override
- void handleInvalidExpression(Token token) {
- pushNode(new ErrorExpression(token));
- }
-
- @override
- void handleInvalidFunctionBody(Token token) {
- lastErrorWasNativeFunctionBody = false;
- }
-
- @override
- void handleInvalidTypeReference(Token token) {
- pushNode(null);
- }
-
- Token handleError(Token token, Message message) {
- MessageKind errorCode;
- Map<String, dynamic> arguments = message.arguments;
-
- switch (message.code.dart2jsCode) {
- case "MISSING_TOKEN_BEFORE_THIS":
- String expected = arguments["string"];
- // TODO(danrubel): This functionality is being replaced by
- // the parser's ensureSemicolon method.
- if (identical(";", expected)) {
- // When a semicolon is missing, it often leads to an error on the
- // following line. So we try to find the token preceding the semicolon
- // and report that something is missing *after* it.
- Token preceding = findPrecedingToken(token);
- if (preceding == token) {
- reportErrorFromToken(token, MessageKind.MISSING_TOKEN_BEFORE_THIS,
- {'token': expected});
- } else {
- reportErrorFromToken(preceding,
- MessageKind.MISSING_TOKEN_AFTER_THIS, {'token': expected});
- }
- return preceding;
- } else {
- reportFatalError(
- reporter.spanFromToken(token),
- MessageTemplate.TEMPLATES[MessageKind.MISSING_TOKEN_BEFORE_THIS]
- .message({'token': expected}, true).toString());
- return null;
- }
- break;
-
- case "EXPECTED_IDENTIFIER":
- if (token is KeywordToken) {
- reportErrorFromToken(
- token,
- MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
- {'keyword': token.lexeme});
- } else if (token is ErrorToken) {
- // TODO(ahe): This is dead code.
- return newSyntheticToken(synthesizeIdentifier(token));
- } else {
- reportFatalError(reporter.spanFromToken(token),
- "Expected identifier, but got '${token.lexeme}'.");
- }
- return newSyntheticToken(token);
-
- case "NATIVE_OR_BODY_EXPECTED":
- if (optional("native", token)) {
- return newSyntheticToken(native.handleNativeBlockToSkip(this, token));
- } else {
- errorCode = MessageKind.BODY_EXPECTED;
- }
- break;
-
- case "NATIVE_OR_FATAL":
- if (optional("native", token)) {
- lastErrorWasNativeFunctionBody = true;
- return newSyntheticToken(
- native.handleNativeFunctionBody(this, token));
- } else {
- reportFatalError(reporter.spanFromToken(token), message.message);
- }
- return null;
-
- case "UNMATCHED_TOKEN":
- reportErrorFromToken(token, MessageKind.UNMATCHED_TOKEN,
- {"end": arguments["string"], "begin": arguments["token"]});
- Token next = token;
- while (next.next is ErrorToken) {
- next = next.next;
- }
- return next;
-
- case "EMPTY_NAMED_PARAMETER_LIST":
- errorCode = MessageKind.EMPTY_NAMED_PARAMETER_LIST;
- break;
-
- case "EMPTY_OPTIONAL_PARAMETER_LIST":
- errorCode = MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST;
- break;
-
- case "BODY_EXPECTED":
- errorCode = MessageKind.BODY_EXPECTED;
- break;
-
- case "HEX_DIGIT_EXPECTED":
- errorCode = MessageKind.HEX_DIGIT_EXPECTED;
- break;
-
- case "GENERIC":
- errorCode = MessageKind.GENERIC;
- arguments = {"text": message.message};
- break;
-
- case "EXTRANEOUS_MODIFIER":
- errorCode = MessageKind.EXTRANEOUS_MODIFIER;
- arguments = {"modifier": arguments["token"]};
- break;
-
- case "EXTRANEOUS_MODIFIER_REPLACE":
- errorCode = MessageKind.EXTRANEOUS_MODIFIER_REPLACE;
- arguments = {"modifier": arguments["token"]};
- break;
-
- case "INVALID_AWAIT_FOR":
- errorCode = MessageKind.INVALID_AWAIT_FOR;
- break;
-
- case "BAD_INPUT_CHARACTER":
- errorCode = MessageKind.BAD_INPUT_CHARACTER;
- int codePoint = arguments["codePoint"];
- String hex = codePoint.toRadixString(16);
- String padding = "0000".substring(hex.length);
- arguments = {'characterHex': padding};
- break;
-
- case "INVALID_INLINE_FUNCTION_TYPE":
- errorCode = MessageKind.INVALID_INLINE_FUNCTION_TYPE;
- break;
-
- case "INVALID_SYNC_MODIFIER":
- errorCode = MessageKind.INVALID_SYNC_MODIFIER;
- break;
-
- case "VOID_NOT_ALLOWED":
- errorCode = MessageKind.VOID_NOT_ALLOWED;
- break;
-
- case "MALFORMED_STRING_LITERAL":
- errorCode = MessageKind.MALFORMED_STRING_LITERAL;
- break;
-
- case "EXPONENT_MISSING":
- errorCode = MessageKind.EXPONENT_MISSING;
- break;
-
- case "POSITIONAL_PARAMETER_WITH_EQUALS":
- errorCode = MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS;
- break;
-
- case "REQUIRED_PARAMETER_WITH_DEFAULT":
- errorCode = MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT;
- break;
-
- case "UNMATCHED_TOKEN":
- errorCode = MessageKind.UNMATCHED_TOKEN;
- break;
-
- case "UNSUPPORTED_PREFIX_PLUS":
- errorCode = MessageKind.UNSUPPORTED_PREFIX_PLUS;
- break;
-
- case "UNTERMINATED_COMMENT":
- errorCode = MessageKind.UNTERMINATED_COMMENT;
- break;
-
- case "UNTERMINATED_STRING":
- errorCode = MessageKind.UNTERMINATED_STRING;
- arguments = {"quote": arguments["string"]};
- break;
-
- case "UNTERMINATED_TOKEN":
- errorCode = MessageKind.UNTERMINATED_TOKEN;
- break;
-
- case "*fatal*":
- // This is an error that Fasta can recover from, but dart2js can't.
- reportFatalError(reporter.spanFromToken(token), message.message);
- return null;
-
- case "*ignored*":
- // This is an error that Fasta reports as a recoverable error during
- // parsing. For historical reasons, dart2js implements this in a later
- // phase already, so we just ignore it. Another possibilty is that we
- // wan't to avoid introducing a breaking change to dart2js.
- return null;
-
- default:
- throw "Unexpected message code: ${message.code}";
- }
- SourceSpan span = reporter.spanFromToken(token);
- reportError(span, errorCode, arguments);
- return null;
- }
-
- /// Finds the preceding token via the begin token of the last AST node pushed
- /// on the [nodes] stack.
- Token findPrecedingToken(Token token) {
- Token result;
- Link<Node> nodes = this.nodes;
- while (!nodes.isEmpty) {
- result = findPrecedingTokenFromNode(nodes.head, token);
- if (result != null) {
- return result;
- }
- nodes = nodes.tail;
- }
- if (compilationUnitElement != null) {
- if (compilationUnitElement is CompilationUnitElementX) {
- CompilationUnitElementX unit = compilationUnitElement;
- Link<Element> members = unit.localMembers;
- while (!members.isEmpty) {
- ElementX member = members.head;
- DeclarationSite site = member.declarationSite;
- if (site is PartialElement) {
- result = findPrecedingTokenFromToken(site.endToken, token);
- if (result != null) {
- return result;
- }
- }
- members = members.tail;
- }
- result =
- findPrecedingTokenFromNode(compilationUnitElement.partTag, token);
- if (result != null) {
- return result;
- }
- }
- }
- return token;
- }
-
- Token findPrecedingTokenFromNode(Node node, Token token) {
- if (node != null) {
- return findPrecedingTokenFromToken(node.getBeginToken(), token);
- }
- return null;
- }
-
- Token findPrecedingTokenFromToken(Token start, Token token) {
- if (start != null) {
- Token current = start;
- while (current.kind != Tokens.EOF_TOKEN && current.next != token) {
- current = current.next;
- }
- if (current.kind != Tokens.EOF_TOKEN) {
- return current;
- }
- }
- return null;
- }
-
- /// Finds the preceding token via the begin token of the last AST node pushed
- /// on the [nodes] stack.
- Token synthesizeIdentifier(Token token) {
- Token synthesizedToken =
- new StringToken.fromString(TokenType.IDENTIFIER, '?', token.charOffset);
- synthesizedToken.setNext(token.next);
- return synthesizedToken;
- }
-
- void recoverableError(Spannable node, String message) {
- // TODO(johnniwinther): Make recoverable errors non-fatal.
- reportFatalError(node, message);
- }
-
- void pushElement(ElementX element) {
- assert(element.declarationSite != null,
- failedAt(element, 'Missing declaration site for $element.'));
- popMetadata(element);
- compilationUnitElement.addMember(element, reporter);
- }
-
- List<MetadataAnnotation> popMetadata(ElementX element) {
- List<MetadataAnnotation> result = metadata.toList();
- element.metadata = result;
- metadata.clear();
- return result;
- }
-
- void pushMetadata(MetadataAnnotation annotation) {
- metadata.addLast(annotation);
- }
-
- void addLibraryTag(LibraryTag tag) {
- if (!allowLibraryTags()) {
- recoverableError(tag, 'Library tags not allowed here.');
- }
- LibraryElementX implementationLibrary =
- compilationUnitElement.implementationLibrary;
- implementationLibrary.addTag(tag, reporter);
- }
-
- void pushNode(Node node) {
- nodes = nodes.prepend(node);
- if (VERBOSE) log("push $nodes");
- }
-
- Node popNode() {
- assert(!nodes.isEmpty);
- Node node = nodes.head;
- nodes = nodes.tail;
- if (VERBOSE) log("pop $nodes");
- return node;
- }
-
- void log(message) {
- print(message);
- }
-
- NodeList makeNodeList(
- int count, Token beginToken, Token endToken, String delimiter) {
- Link<Node> poppedNodes = const Link<Node>();
- for (; count > 0; --count) {
- // This effectively reverses the order of nodes so they end up
- // in correct (source) order.
- poppedNodes = poppedNodes.prepend(popNode());
- }
- return new NodeList(beginToken, poppedNodes, endToken, delimiter);
- }
-
- @override
- void beginLiteralString(Token token) {
- String source = token.lexeme;
- StringQuoting quoting = StringValidator.quotingFromString(source);
- pushQuoting(quoting);
- // Just wrap the token for now. At the end of the interpolation,
- // when we know how many there are, go back and validate the tokens.
- pushNode(new LiteralString(token, null));
- }
-
- @override
- void handleStringPart(Token token) {
- // Just push an unvalidated token now, and replace it when we know the
- // end of the interpolation.
- pushNode(new LiteralString(token, null));
- }
-
- @override
- void endLiteralString(int interpolationCount, Token endToken) {
- StringQuoting quoting = popQuoting();
-
- Link<StringInterpolationPart> parts = const Link<StringInterpolationPart>();
- // Parts of the string interpolation are popped in reverse order,
- // starting with the last literal string part.
- bool isLast = true;
- for (int i = 0; i < interpolationCount; i++) {
- LiteralString string = popNode();
- DartString validation = stringValidator.validateInterpolationPart(
- string.token, quoting,
- isFirst: false, isLast: isLast);
- // Replace the unvalidated LiteralString with a new LiteralString
- // object that has the validation result included.
- string = new LiteralString(string.token, validation);
- Expression expression = popNode();
- parts = parts.prepend(new StringInterpolationPart(expression, string));
- isLast = false;
- }
-
- LiteralString string = popNode();
- DartString validation = stringValidator.validateInterpolationPart(
- string.token, quoting,
- isFirst: true, isLast: isLast);
- string = new LiteralString(string.token, validation);
- if (isLast) {
- pushNode(string);
- } else {
- NodeList partNodes = new NodeList(null, parts, null, "");
- pushNode(new StringInterpolation(string, partNodes));
- }
- }
-
- @override
- void handleNativeClause(Token nativeToken, bool hasName) {
- if (hasName) {
- nativeName = popNode(); // LiteralString
- } else {
- nativeName = null;
- }
- }
-
- @override
- void handleStringJuxtaposition(int stringCount) {
- assert(stringCount != 0);
- Expression accumulator = popNode();
- stringCount--;
- while (stringCount > 0) {
- Expression expression = popNode();
- accumulator = new StringJuxtaposition(expression, accumulator);
- stringCount--;
- }
- pushNode(accumulator);
- }
-
- @override
- void beginMember() {
- memberErrors = memberErrors.prepend(false);
- }
-
- @override
- void beginTopLevelMember(Token token) {
- beginMember();
- }
-
- @override
- void endMember() {
- memberErrors = memberErrors.tail;
- }
-
- /// Don't call this method. Should only be used as a last resort when there
- /// is no feasible way to recover from a parser error.
- void reportFatalError(Spannable spannable, String message) {
- reportError(spannable, MessageKind.GENERIC, {'text': message});
- // Some parse errors are infeasible to recover from, so we throw an error.
- SourceSpan span = reporter.spanFromSpannable(spannable);
- throw new ParserError(
- span.begin, span.end, codes.templateUnspecified.withArguments(message));
- }
-
- void reportError(Spannable spannable, MessageKind errorCode,
- [Map arguments = const {}]) {
- if (currentMemberHasParseError) return; // Error already reported.
- if (suppressParseErrors) return;
- if (!memberErrors.isEmpty) {
- memberErrors = memberErrors.tail.prepend(true);
- }
- reporter.reportErrorMessage(spannable, errorCode, arguments);
- }
-
- void reportErrorFromToken(Token token, MessageKind errorCode,
- [Map arguments = const {}]) {
- reportError(reporter.spanFromToken(token), errorCode, arguments);
- }
-}
diff --git a/pkg/compiler/lib/src/parser/member_listener.dart b/pkg/compiler/lib/src/parser/member_listener.dart
deleted file mode 100644
index 3d1ed39..0000000
--- a/pkg/compiler/lib/src/parser/member_listener.dart
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.member_listener;
-
-import '../common.dart';
-import '../elements/elements.dart' show Element, ElementKind, Elements;
-import '../elements/modelx.dart'
- show ClassElementX, ElementX, FieldElementX, VariableList;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart';
-import 'element_listener.dart' show ScannerOptions;
-import 'node_listener.dart' show NodeListener;
-import 'partial_elements.dart'
- show
- PartialConstructorElement,
- PartialFunctionElement,
- PartialMetadataAnnotation;
-
-class MemberListener extends NodeListener {
- final ClassElementX enclosingClass;
-
- MemberListener(ScannerOptions scannerOptions, DiagnosticReporter listener,
- ClassElementX enclosingElement)
- : this.enclosingClass = enclosingElement,
- super(scannerOptions, listener, enclosingElement.compilationUnit);
-
- bool isConstructorName(Node nameNode) {
- if (enclosingClass == null || enclosingClass.kind != ElementKind.CLASS) {
- return false;
- }
- String name;
- if (nameNode.asIdentifier() != null) {
- name = nameNode.asIdentifier().source;
- } else {
- Send send = nameNode.asSend();
- name = send.receiver.asIdentifier().source;
- }
- return enclosingClass.name == name;
- }
-
- // TODO(johnniwinther): Remove this method.
- String getMethodNameHack(Node methodName) {
- Send send = methodName.asSend();
- if (send == null) {
- if (isConstructorName(methodName)) return '';
- return methodName.asIdentifier().source;
- }
- Identifier receiver = send.receiver.asIdentifier();
- Identifier selector = send.selector.asIdentifier();
- Operator operator = selector.asOperator();
- if (operator != null) {
- assert(identical(receiver.source, 'operator'));
- // TODO(ahe): It is a hack to compare to ')', but it beats
- // parsing the node.
- bool isUnary = identical(operator.token.next.next.stringValue, ')');
- return Elements.constructOperatorName(operator.source, isUnary);
- } else {
- if (receiver == null || receiver.source != enclosingClass.name) {
- reporter.reportErrorMessage(
- send.receiver,
- MessageKind.INVALID_CONSTRUCTOR_NAME,
- {'name': enclosingClass.name});
- }
- return selector.source;
- }
- }
-
- @override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
- super.endMethod(getOrSet, beginToken, beginParam, endToken);
- FunctionExpression method = popNode();
- pushNode(null);
- bool isConstructor = isConstructorName(method.name);
- String name = getMethodNameHack(method.name);
- Element memberElement;
- if (isConstructor) {
- if (getOrSet != null) {
- recoverableError(reporter.spanFromToken(getOrSet), 'illegal modifier');
- }
- memberElement = new PartialConstructorElement(name, beginToken, endToken,
- ElementKind.GENERATIVE_CONSTRUCTOR, method.modifiers, enclosingClass);
- } else {
- memberElement = new PartialFunctionElement(name, beginToken, getOrSet,
- endToken, method.modifiers, enclosingClass,
- hasBody: method.hasBody);
- }
- addMember(memberElement);
- }
-
- @override
- void endFactoryMethod(
- Token beginToken, Token factoryKeyword, Token endToken) {
- super.endFactoryMethod(beginToken, factoryKeyword, endToken);
- FunctionExpression method = popNode();
- pushNode(null);
- String name = getMethodNameHack(method.name);
- Identifier singleIdentifierName = method.name.asIdentifier();
- if (singleIdentifierName != null && singleIdentifierName.source == name) {
- if (name != enclosingClass.name) {
- reporter.reportErrorMessage(
- singleIdentifierName,
- MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
- {'name': enclosingClass.name});
- }
- }
- Element memberElement = new PartialConstructorElement(
- name,
- beginToken,
- endToken,
- ElementKind.FACTORY_CONSTRUCTOR,
- method.modifiers,
- enclosingClass);
- addMember(memberElement);
- }
-
- @override
- void endFields(Token staticToken, Token covariantToken, Token varFinalOrConst,
- int count, Token beginToken, Token endToken) {
- bool hasParseError = memberErrors.head;
- super.endFields(staticToken, covariantToken, varFinalOrConst, count,
- beginToken, endToken);
- VariableDefinitions variableDefinitions = popNode();
- Modifiers modifiers = variableDefinitions.modifiers;
- pushNode(null);
- void buildFieldElement(Identifier name, VariableList fields) {
- Element element = new FieldElementX(name, enclosingClass, fields);
- addMember(element);
- }
-
- buildFieldElements(modifiers, variableDefinitions.definitions,
- enclosingClass, buildFieldElement, beginToken, endToken, hasParseError);
- }
-
- @override
- void endFieldInitializer(Token assignmentOperator, Token token) {
- pushNode(null); // Super expects an expression, but
- // ClassElementParser just skips expressions.
- super.endFieldInitializer(assignmentOperator, token);
- }
-
- @override
- void endInitializers(int count, Token beginToken, Token endToken) {
- pushNode(null);
- }
-
- void addMetadata(ElementX memberElement) {
- memberElement.metadata = metadata.toList();
- }
-
- void addMember(ElementX memberElement) {
- addMetadata(memberElement);
- enclosingClass.addMember(memberElement, reporter);
- }
-
- @override
- void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
- super.endMetadata(beginToken, periodBeforeName, endToken);
- // TODO(paulberry,ahe): type variable metadata should not be ignored. See
- // dartbug.com/5841.
- if (!inTypeVariable) {
- pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
- }
- }
-}
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
deleted file mode 100644
index 4ac6f34..0000000
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ /dev/null
@@ -1,1254 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.node_listener;
-
-import 'package:front_end/src/fasta/parser.dart'
- show FormalParameterKind, IdentifierContext, MemberKind;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/scanner/token.dart' show TokenType;
-
-import '../common.dart';
-import '../elements/elements.dart' show CompilationUnitElement;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link;
-import 'element_listener.dart' show ElementListener, ScannerOptions;
-
-import 'package:front_end/src/fasta/parser.dart' as fasta show Assert;
-
-class NodeListener extends ElementListener {
- int invalidTopLevelDeclarationCount = 0;
- int invalidMemberCount = 0;
-
- NodeListener(ScannerOptions scannerOptions, DiagnosticReporter reporter,
- CompilationUnitElement element)
- : super(scannerOptions, reporter, element, null);
-
- @override
- void addLibraryTag(LibraryTag tag) {
- pushNode(tag);
- }
-
- @override
- void addPartOfTag(PartOf tag) {
- pushNode(tag);
- }
-
- @override
- void endLibraryName(Token libraryKeyword, Token semicolon) {
- Expression name = popNode();
- pushNode(new LibraryName(
- libraryKeyword,
- name,
- // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
- // (element) instead of Metatada (node).
- null));
- }
-
- @override
- void endImport(Token importKeyword, Token semicolon) {
- NodeList combinators = popNode();
- Flag flag = popNode();
- bool isDeferred = flag == Flag.TRUE;
- Identifier prefix = popNode();
- NodeList conditionalUris = popNode();
- StringNode uri = popLiteralString();
- pushNode(new Import(
- importKeyword,
- uri,
- conditionalUris,
- prefix,
- combinators,
- // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
- // (element) instead of Metatada (node).
- null,
- isDeferred: isDeferred));
- }
-
- @override
- void endExport(Token exportKeyword, Token semicolon) {
- NodeList combinators = popNode();
- NodeList conditionalUris = popNode();
- StringNode uri = popLiteralString();
- pushNode(new Export(
- exportKeyword,
- uri,
- conditionalUris,
- combinators,
- // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
- // (element) instead of Metatada (node).
- null));
- }
-
- @override
- void endPart(Token partKeyword, Token semicolon) {
- StringNode uri = popLiteralString();
- pushNode(new Part(
- partKeyword,
- uri,
- // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
- // (element) instead of Metatada (node).
- null));
- }
-
- @override
- void endPartOf(
- Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
- Expression name = popNode(); // name
- pushNode(new PartOf(
- partKeyword,
- name,
- // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
- // (element) instead of Metatada (node).
- null));
- }
-
- @override
- void handleClassExtends(Token extendsKeyword) {
- pushNode(new TokenNode(extendsKeyword));
- }
-
- @override
- void handleClassImplements(Token implementsKeyword, int interfacesCount) {
- pushNode(makeNodeList(interfacesCount, implementsKeyword, null, ","));
- }
-
- @override
- void handleRecoverClassHeader() {
- popNode(); // interfaces
- popNode(); // extendsNode
- popNode(); // supertype
- }
-
- @override
- void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
- if (abstractToken == null) {
- pushNode(Modifiers.EMPTY);
- } else {
- Link<Node> poppedNodes = const Link<Node>();
- poppedNodes = poppedNodes.prepend(new Identifier(abstractToken));
- NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- }
- }
-
- @override
- void endClassDeclaration(Token beginToken, Token endToken) {
- NodeList body = popNode();
- NodeList interfaces = popNode();
- TokenNode extendsNode = popNode();
- Node supertype = popNode();
- Modifiers modifiers = popNode();
- NodeList typeParameters = popNode();
- Identifier name = popNode();
- // TODO(danrubel): can we remove the extends keyword from ClassNode ?
- pushNode(new ClassNode(modifiers, name, typeParameters, supertype,
- interfaces, beginToken, extendsNode.token, body, endToken));
- }
-
- @override
- void handleInvalidTopLevelDeclaration(Token endToken) {
- ++invalidTopLevelDeclarationCount;
- }
-
- @override
- void endTopLevelDeclaration(Token token) {
- // TODO(sigmund): consider moving metadata into each declaration
- // element instead.
- Node node = popNode(); // top-level declaration
- popNode(); // Discard metadata
- pushNode(node);
- super.endTopLevelDeclaration(token);
- }
-
- @override
- void beginCompilationUnit(Token token) {
- invalidTopLevelDeclarationCount = 0;
- }
-
- @override
- void endCompilationUnit(int count, Token token) {
- pushNode(makeNodeList(
- count - invalidTopLevelDeclarationCount, null, null, '\n'));
- }
-
- @override
- void endFunctionTypeAlias(
- Token typedefKeyword, Token equals, Token endToken) {
- bool isGeneralizedTypeAlias;
- NodeList templateParameters;
- TypeAnnotation returnType;
- Identifier name;
- NodeList typeParameters;
- NodeList formals;
- if (equals == null) {
- isGeneralizedTypeAlias = false;
- formals = popNode();
- templateParameters = popNode();
- name = popNode();
- returnType = popNode();
- } else {
- // TODO(floitsch): keep using the `FunctionTypeAnnotation' node.
- isGeneralizedTypeAlias = true;
- Node type = popNode();
- if (type.asFunctionTypeAnnotation() == null) {
- // TODO(floitsch): The parser should diagnose this problem, not
- // this listener.
- // However, this problem goes away, when we allow aliases for
- // non-function types too.
- reportFatalError(type, 'Expected a function type.');
- }
- FunctionTypeAnnotation functionType = type;
- templateParameters = popNode();
- name = popNode();
- returnType = functionType.returnType;
- typeParameters = functionType.typeParameters;
- formals = functionType.formals;
- }
- pushNode(new Typedef(isGeneralizedTypeAlias, templateParameters, returnType,
- name, typeParameters, formals, typedefKeyword, endToken));
- }
-
- void handleNoName(Token token) {
- pushNode(null);
- }
-
- @override
- void endFunctionType(Token functionToken, Token endToken) {
- NodeList formals = popNode();
- TypeAnnotation returnType = popNode();
- NodeList typeParameters = popNode();
- pushNode(new FunctionTypeAnnotation(
- returnType, functionToken, typeParameters, formals));
- }
-
- @override
- void endNamedMixinApplication(Token beginToken, Token classKeyword,
- Token equals, Token implementsKeyword, Token endToken) {
- NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
- Node mixinApplication = popNode();
- Modifiers modifiers = popNode();
- NodeList typeParameters = popNode();
- Identifier name = popNode();
- pushNode(new NamedMixinApplication(name, typeParameters, modifiers,
- mixinApplication, interfaces, beginToken, endToken));
- }
-
- @override
- void endEnum(Token enumKeyword, Token leftBrace, int count) {
- NodeList names = makeNodeList(count, leftBrace, leftBrace?.endGroup, ",");
- Identifier name = popNode();
- pushNode(new Enum(enumKeyword, name, names));
- }
-
- @override
- void endClassBody(int memberCount, Token beginToken, Token endToken) {
- pushNode(makeNodeList(
- memberCount - invalidMemberCount, beginToken, endToken, null));
- invalidMemberCount = 0;
- }
-
- @override
- void endTopLevelFields(Token staticToken, Token covariantToken,
- Token varFinalOrConst, int count, Token beginToken, Token endToken) {
- NodeList variables = makeNodeList(count, null, endToken, ",");
- TypeAnnotation type = popNode();
- Modifiers modifiers =
- newFieldModifiers(staticToken, covariantToken, varFinalOrConst);
- pushNode(new VariableDefinitions(type, modifiers, variables));
- }
-
- @override
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList formals = popNode();
- NodeList typeVariables = popNode();
- Identifier name = popNode();
- TypeAnnotation type = popNode();
- Modifiers modifiers = popNode();
- pushNode(new FunctionExpression(name, typeVariables, formals, body, type,
- modifiers, null, getOrSet, asyncModifier));
- }
-
- @override
- void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
- Token varFinalOrConst) {
- if (covariantToken == null && varFinalOrConst == null) {
- pushNode(Modifiers.EMPTY);
- } else {
- Link<Node> poppedNodes = const Link<Node>();
- if (covariantToken != null) {
- poppedNodes = poppedNodes.prepend(new Identifier(covariantToken));
- }
- if (varFinalOrConst != null) {
- poppedNodes = poppedNodes.prepend(new Identifier(varFinalOrConst));
- }
- NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- }
- }
-
- @override
- void endFormalParameter(Token thisKeyword, Token periodAfterThis,
- Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
- Expression name = popNode();
- if (thisKeyword != null) {
- Identifier thisIdentifier = new Identifier(thisKeyword);
- if (name.asSend() == null) {
- name = new Send(thisIdentifier, name);
- } else {
- name = name.asSend().copyWithReceiver(thisIdentifier, false);
- }
- }
- TypeAnnotation type = popNode();
- Modifiers modifiers = popNode();
- NodeList metadata = popNode();
- pushNode(new VariableDefinitions.forParameter(
- metadata, type, modifiers, new NodeList.singleton(name)));
- }
-
- @override
- void endFormalParameters(
- int count, Token beginToken, Token endToken, MemberKind kind) {
- pushNode(makeNodeList(count, beginToken, endToken, ","));
- }
-
- @override
- void handleNoFormalParameters(Token token, MemberKind kind) {
- pushNode(null);
- }
-
- @override
- void endArguments(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ","));
- }
-
- @override
- void handleNoArguments(Token token) {
- pushNode(null);
- }
-
- @override
- void endConstructorReference(
- Token start, Token periodBeforeName, Token endToken) {
- Identifier name = null;
- if (periodBeforeName != null) {
- name = popNode();
- }
- NodeList typeArguments = popNode();
- Node classReference = popNode();
- if (typeArguments != null) {
- classReference = new NominalTypeAnnotation(classReference, typeArguments);
- } else {
- Identifier identifier = classReference.asIdentifier();
- Send send = classReference.asSend();
- if (identifier != null) {
- // TODO(ahe): Should be:
- // classReference = new Send(null, identifier);
- classReference = identifier;
- } else if (send != null) {
- classReference = send;
- } else {
- internalError(node: classReference);
- }
- }
- Node constructor = classReference;
- if (name != null) {
- // Either typeName<args>.name or x.y.name.
- constructor = new Send(classReference, name);
- }
- pushNode(constructor);
- }
-
- @override
- void endRedirectingFactoryBody(Token beginToken, Token endToken) {
- pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
- }
-
- @override
- void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
- pushNode(new Return(nativeToken, semicolon, nativeName));
- }
-
- @override
- void handleEmptyFunctionBody(Token semicolon) {
- endBlockFunctionBody(0, null, semicolon);
- }
-
- void handleExpressionFunctionBody(Token arrowToken, Token endToken) {
- endReturnStatement(true, arrowToken, endToken);
- }
-
- @override
- void endReturnStatement(
- bool hasExpression, Token beginToken, Token endToken) {
- Expression expression = hasExpression ? popNode() : null;
- pushNode(new Return(beginToken, endToken, expression));
- }
-
- @override
- void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
- Expression expression = popNode();
- pushNode(new Yield(yieldToken, starToken, expression, endToken));
- }
-
- @override
- void endExpressionStatement(Token token) {
- pushNode(new ExpressionStatement(popNode(), token));
- }
-
- void handleOnError(Token token, var errorInformation) {
- reporter.internalError(reporter.spanFromToken(token),
- "'${token.lexeme}': ${errorInformation}");
- }
-
- @override
- void handleLiteralInt(Token token) {
- pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e)));
- }
-
- @override
- void handleLiteralDouble(Token token) {
- pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e)));
- }
-
- @override
- void handleLiteralBool(Token token) {
- pushNode(new LiteralBool(token, (t, e) => handleOnError(t, e)));
- }
-
- @override
- void handleLiteralNull(Token token) {
- pushNode(new LiteralNull(token));
- }
-
- @override
- void endLiteralSymbol(Token hashToken, int identifierCount) {
- NodeList identifiers = makeNodeList(identifierCount, null, null, '.');
- pushNode(new LiteralSymbol(hashToken, identifiers));
- }
-
- @override
- void endBinaryExpression(Token token) {
- Node argument = popNode();
- Node receiver = popNode();
- String tokenString = token.stringValue;
- if (identical(tokenString, '.') ||
- identical(tokenString, '..') ||
- identical(tokenString, '?.')) {
- Send argumentSend = argument.asSend();
- if (argumentSend == null) {
- // TODO(ahe): The parser should diagnose this problem, not
- // this listener.
- reportFatalError(
- reporter.spanFromSpannable(argument), "Expected an identifier.");
- }
- if (argumentSend.receiver != null) internalError(node: argument);
- if (argument is SendSet) internalError(node: argument);
- pushNode(argument
- .asSend()
- .copyWithReceiver(receiver, identical(tokenString, '?.')));
- } else {
- NodeList arguments = new NodeList.singleton(argument);
- pushNode(new Send(receiver, new Operator(token), arguments));
- }
- if (identical(tokenString, '===')) {
- reporter.reportErrorMessage(reporter.spanFromToken(token),
- MessageKind.UNSUPPORTED_EQ_EQ_EQ, {'lhs': receiver, 'rhs': argument});
- }
- if (identical(tokenString, '!==')) {
- reporter.reportErrorMessage(
- reporter.spanFromToken(token),
- MessageKind.UNSUPPORTED_BANG_EQ_EQ,
- {'lhs': receiver, 'rhs': argument});
- }
- }
-
- @override
- void beginCascade(Token token) {
- pushNode(new CascadeReceiver(popNode(), token));
- }
-
- @override
- void endCascade() {
- pushNode(new Cascade(popNode()));
- }
-
- @override
- void handleAsOperator(Token operator, Token endToken) {
- TypeAnnotation type = popNode();
- Expression expression = popNode();
- NodeList arguments = new NodeList.singleton(type);
- pushNode(new Send(expression, new Operator(operator), arguments));
- }
-
- @override
- void handleAssignmentExpression(Token token) {
- Node arg = popNode();
- Node node = popNode();
- Send send = node.asSend();
- if (send == null || !(send.isPropertyAccess || send.isIndex)) {
- reportNotAssignable(node);
- }
- var tokenString = token.stringValue;
- if (tokenString == '||=' || tokenString == '&&=') {
- reporter.reportErrorMessage(reporter.spanFromToken(token),
- MessageKind.UNSUPPORTED_OPERATOR, {'operator': tokenString});
- pushNode(arg);
- return;
- }
- if (send.asSendSet() != null) internalError(node: send);
- NodeList arguments;
- if (send.isIndex) {
- Link<Node> link = const Link<Node>().prepend(arg);
- link = link.prepend(send.arguments.head);
- arguments = new NodeList(null, link);
- } else {
- arguments = new NodeList.singleton(arg);
- }
- Operator op = new Operator(token);
- pushNode(new SendSet(
- send.receiver, send.selector, op, arguments, send.isConditional));
- }
-
- void reportNotAssignable(Node node) {
- // TODO(ahe): The parser should diagnose this problem, not this
- // listener.
- reportFatalError(reporter.spanFromSpannable(node), "Not assignable.");
- }
-
- @override
- void endConditionalExpression(Token question, Token colon) {
- Node elseExpression = popNode();
- Node thenExpression = popNode();
- Node condition = popNode();
- pushNode(new Conditional(
- condition, thenExpression, elseExpression, question, colon));
- }
-
- @override
- void handleSend(Token beginToken, Token endToken) {
- NodeList arguments = popNode();
- NodeList typeArguments = popNode();
- Node selector = popNode();
- // TODO(ahe): Handle receiver.
- pushNode(new Send(null, selector, arguments, typeArguments));
- }
-
- @override
- void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
- if (count == 0 && beginToken == null) {
- pushNode(new EmptyStatement(endToken));
- } else {
- pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
- }
- }
-
- @override
- void handleAsyncModifier(Token asyncToken, Token starToken) {
- if (asyncToken != null) {
- pushNode(new AsyncModifier(asyncToken, starToken));
- } else {
- pushNode(null);
- }
- }
-
- @override
- void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
- pushNode(new Block(new NodeList.empty()));
- }
-
- @override
- void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {}
-
- @override
- void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
- pushNode(new Block(new NodeList.empty()));
- }
-
- @override
- void handleNoFunctionBody(Token token) {
- pushNode(new EmptyStatement(token));
- }
-
- @override
- void endNamedFunctionExpression(Token endToken) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList initializers = popNode();
- NodeList formals = popNode();
- // The name can be an identifier or a send in case of named constructors.
- Expression name = popNode();
- TypeAnnotation type = popNode();
- Modifiers modifiers = new Modifiers(new NodeList.empty());
- NodeList typeVariables = popNode();
- pushNode(new FunctionExpression(name, typeVariables, formals, body, type,
- modifiers, initializers, null, asyncModifier));
- }
-
- @override
- void endLocalFunctionDeclaration(Token endToken) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList initializers = popNode();
- NodeList formals = popNode();
- // The name can be an identifier or a send in case of named constructors.
- Expression name = popNode();
- TypeAnnotation type = popNode();
- Modifiers modifiers = new Modifiers(new NodeList.empty());
- NodeList typeVariables = popNode();
- popNode(); // Metadata.
- pushNode(new FunctionDeclaration(new FunctionExpression(name, typeVariables,
- formals, body, type, modifiers, initializers, null, asyncModifier)));
- }
-
- @override
- void beginVariablesDeclaration(Token token, Token varFinalOrConst) {
- if (varFinalOrConst == null) {
- pushNode(Modifiers.EMPTY);
- } else {
- Link<Node> nodes =
- const Link<Node>().prepend(new Identifier(varFinalOrConst));
- pushNode(new Modifiers(new NodeList(null, nodes, null, ' ')));
- }
- }
-
- @override
- void endVariablesDeclaration(int count, Token endToken) {
- // TODO(ahe): Pick one name for this concept, either
- // VariablesDeclaration or VariableDefinitions.
- NodeList variables = makeNodeList(count, null, endToken, ",");
- Modifiers modifiers = popNode();
- TypeAnnotation type = popNode();
- popNode();
- pushNode(new VariableDefinitions(type, modifiers, variables));
- }
-
- @override
- void endVariableInitializer(Token assignmentOperator) {
- Expression initializer = popNode();
- NodeList arguments =
- initializer == null ? null : new NodeList.singleton(initializer);
- Expression name = popNode();
- Operator op = new Operator(assignmentOperator);
- pushNode(new SendSet(null, name, op, arguments));
- }
-
- @override
- void endFieldInitializer(Token assignmentOperator, Token token) {
- endVariableInitializer(assignmentOperator);
- }
-
- @override
- void endIfStatement(Token ifToken, Token elseToken) {
- Statement elsePart = (elseToken == null) ? null : popNode();
- Statement thenPart = popNode();
- ParenthesizedExpression condition = popNode();
- pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken));
- }
-
- @override
- void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
- int updateExpressionCount, Token endToken) {
- Statement body = popNode();
- NodeList updates = makeNodeList(updateExpressionCount, null, null, ',');
- Statement condition = popNode();
- Node initializer = popNode();
- pushNode(new For(initializer, condition, updates, body, forKeyword));
- }
-
- @override
- void handleNoExpression(Token token) {
- pushNode(null);
- }
-
- @override
- void endDoWhileStatement(
- Token doKeyword, Token whileKeyword, Token endToken) {
- Expression condition = popNode();
- Statement body = popNode();
- pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken));
- }
-
- @override
- void endWhileStatement(Token whileKeyword, Token endToken) {
- Statement body = popNode();
- Expression condition = popNode();
- pushNode(new While(condition, body, whileKeyword));
- }
-
- @override
- void endBlock(int count, Token beginToken, Token endToken) {
- pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
- }
-
- void handleInvalidTopLevelBlock(Token token) {
- popNode(); // block
- }
-
- @override
- void handleThrowExpression(Token throwToken, Token endToken) {
- Expression expression = popNode();
- pushNode(new Throw(expression, throwToken, endToken));
- }
-
- @override
- void endAwaitExpression(Token awaitToken, Token endToken) {
- Expression expression = popNode();
- pushNode(new Await(awaitToken, expression));
- }
-
- @override
- void endRethrowStatement(Token throwToken, Token endToken) {
- pushNode(new Rethrow(throwToken, endToken));
- if (identical(throwToken.stringValue, 'throw')) {
- reporter.reportErrorMessage(reporter.spanFromToken(throwToken),
- MessageKind.MISSING_EXPRESSION_IN_THROW);
- }
- }
-
- @override
- void handleUnaryPrefixExpression(Token token) {
- pushNode(new Send.prefix(popNode(), new Operator(token)));
- }
-
- @override
- void handleSuperExpression(Token token, IdentifierContext context) {
- pushNode(new Identifier(token));
- }
-
- @override
- void handleThisExpression(Token token, IdentifierContext context) {
- pushNode(new Identifier(token));
- }
-
- void handleUnaryAssignmentExpression(Token token, bool isPrefix) {
- Node node = popNode();
- Send send = node.asSend();
- if (send == null) {
- reportNotAssignable(node);
- }
- if (!(send.isPropertyAccess || send.isIndex)) {
- reportNotAssignable(node);
- }
- if (send.asSendSet() != null) internalError(node: send);
- Node argument = null;
- if (send.isIndex) argument = send.arguments.head;
- Operator op = new Operator(token);
-
- if (isPrefix) {
- pushNode(new SendSet.prefix(
- send.receiver, send.selector, op, argument, send.isConditional));
- } else {
- pushNode(new SendSet.postfix(
- send.receiver, send.selector, op, argument, send.isConditional));
- }
- }
-
- @override
- void handleUnaryPostfixAssignmentExpression(Token token) {
- handleUnaryAssignmentExpression(token, false);
- }
-
- @override
- void handleUnaryPrefixAssignmentExpression(Token token) {
- handleUnaryAssignmentExpression(token, true);
- }
-
- @override
- void endInitializers(int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, null, ','));
- }
-
- @override
- void handleNoInitializers() {
- pushNode(null);
- }
-
- @override
- void handleInvalidMember(Token endToken) {
- popNode(); // Discard metadata
- ++invalidMemberCount;
- }
-
- @override
- void endMember() {
- // TODO(sigmund): consider moving metadata into each declaration
- // element instead.
- Node node = popNode(); // member
- popNode(); // Discard metadata
- pushNode(node);
- super.endMember();
- }
-
- @override
- void endFields(Token staticToken, Token covariantToken, Token varFinalOrConst,
- int count, Token beginToken, Token endToken) {
- NodeList variables = makeNodeList(count, null, endToken, ",");
- TypeAnnotation type = popNode();
- Modifiers modifiers =
- newFieldModifiers(staticToken, covariantToken, varFinalOrConst);
- pushNode(new VariableDefinitions(type, modifiers, variables));
- }
-
- @override
- void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
- Token varFinalOrConst, Token name) {
- Link<Node> modifiers = const Link<Node>();
- if (varFinalOrConst != null) {
- modifiers = modifiers.prepend(new Identifier(varFinalOrConst));
- }
- if (covariantToken != null) {
- modifiers = modifiers.prepend(new Identifier(covariantToken));
- }
- if (staticToken != null) {
- modifiers = modifiers.prepend(new Identifier(staticToken));
- }
- if (externalToken != null) {
- modifiers = modifiers.prepend(new Identifier(externalToken));
- }
- if (modifiers.isEmpty) {
- pushNode(Modifiers.EMPTY);
- } else {
- pushNode(new Modifiers(new NodeList(null, modifiers, null, ' ')));
- }
- }
-
- @override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList initializers = popNode();
- NodeList formalParameters = popNode();
- NodeList typeVariables = popNode();
- Expression name = popNode();
- TypeAnnotation returnType = popNode();
- Modifiers modifiers = popNode();
- pushNode(new FunctionExpression(name, typeVariables, formalParameters, body,
- returnType, modifiers, initializers, getOrSet, asyncModifier));
- }
-
- @override
- void handleLiteralMap(
- int count, Token beginToken, Token constKeyword, Token endToken) {
- NodeList entries = makeNodeList(count, beginToken, endToken, ',');
- NodeList typeArguments = popNode();
- pushNode(new LiteralMap(typeArguments, entries, constKeyword));
- }
-
- @override
- void endLiteralMapEntry(Token colon, Token endToken) {
- Expression value = popNode();
- Expression key = popNode();
- pushNode(new LiteralMapEntry(key, colon, value));
- }
-
- @override
- void handleLiteralList(
- int count, Token beginToken, Token constKeyword, Token endToken) {
- NodeList elements = makeNodeList(count, beginToken, endToken, ',');
- pushNode(new LiteralList(popNode(), elements, constKeyword));
- }
-
- @override
- void handleIndexedExpression(
- Token openSquareBracket, Token closeSquareBracket) {
- NodeList arguments =
- makeNodeList(1, openSquareBracket, closeSquareBracket, null);
- Node receiver = popNode();
- Token token = new Token(TokenType.INDEX, openSquareBracket.charOffset);
- Node selector = new Operator(token);
- pushNode(new Send(receiver, selector, arguments));
- }
-
- @override
- void endNewExpression(Token token) {
- NodeList arguments = popNode();
- Node name = popNode();
- pushNode(new NewExpression(token, new Send(null, name, arguments)));
- }
-
- @override
- void endConstExpression(Token token) {
- // [token] carries the 'const' information.
- endNewExpression(token);
- }
-
- @override
- void handleOperator(Token token) {
- pushNode(new Operator(token));
- }
-
- @override
- void handleSymbolVoid(Token token) {
- logEvent('SymbolVoid');
- }
-
- @override
- void handleOperatorName(Token operatorKeyword, Token token) {
- Operator op = new Operator(token);
- pushNode(new Send(new Identifier(operatorKeyword), op, null));
- }
-
- @override
- void handleInvalidOperatorName(Token operatorKeyword, Token token) {
- Operator op = new Operator(token);
- pushNode(new Send(new Identifier(operatorKeyword), op, null));
- }
-
- @override
- void handleNamedArgument(Token colon) {
- Expression expression = popNode();
- Identifier name = popNode();
- pushNode(new NamedArgument(name, colon, expression));
- }
-
- @override
- void endOptionalFormalParameters(
- int count, Token beginToken, Token endToken) {
- pushNode(makeNodeList(count, beginToken, endToken, ','));
- }
-
- @override
- void handleIdentifier(Token token, IdentifierContext context) {
- if (IdentifierContext.formalParameterDeclaration == context ||
- IdentifierContext.fieldInitializer == context) {
- var typeAnnotation = popNode();
- if (typeAnnotation is FunctionExpression) {
- pushNode(null); // Signal "no type" to endFormalParameter.
- pushNode(new FunctionExpression(
- new Identifier(token),
- typeAnnotation.typeVariables,
- typeAnnotation.parameters,
- null,
- typeAnnotation.returnType,
- typeAnnotation.modifiers,
- null,
- null,
- null));
- return;
- } else {
- pushNode(typeAnnotation);
- }
- } else if (context == IdentifierContext.enumValueDeclaration) {
- popNode();
- }
- pushNode(new Identifier(token));
- }
-
- @override
- void endFunctionTypedFormalParameter() {
- NodeList formals = popNode();
- TypeAnnotation returnType = popNode();
- NodeList typeVariables = popNode();
- pushNode(new FunctionExpression(null, typeVariables, formals, null,
- returnType, Modifiers.EMPTY, null, null, null));
- }
-
- @override
- void handleValuedFormalParameter(Token equals, Token token) {
- Expression defaultValue = popNode();
- Expression parameterName = popNode();
- pushNode(new SendSet(null, parameterName, new Operator(equals),
- new NodeList.singleton(defaultValue)));
- }
-
- @override
- void handleFormalParameterWithoutValue(Token token) {}
-
- @override
- void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
- Block finallyBlock = null;
- if (finallyKeyword != null) {
- finallyBlock = popNode();
- }
- NodeList catchBlocks = makeNodeList(catchCount, null, null, null);
- Block tryBlock = popNode();
- pushNode(new TryStatement(
- tryBlock, catchBlocks, finallyBlock, tryKeyword, finallyKeyword));
- }
-
- @override
- void handleCaseMatch(Token caseKeyword, Token colon) {
- pushNode(new CaseMatch(caseKeyword, popNode(), colon));
- }
-
- @override
- void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
- Block block = popNode();
- NodeList formals = catchKeyword != null ? popNode() : null;
- TypeAnnotation type = onKeyword != null ? popNode() : null;
- pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword));
- }
-
- @override
- void endSwitchStatement(Token switchKeyword, Token endToken) {
- NodeList cases = popNode();
- ParenthesizedExpression expression = popNode();
- pushNode(new SwitchStatement(expression, cases, switchKeyword));
- }
-
- @override
- void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
- Link<Node> caseNodes = const Link<Node>();
- while (caseCount > 0) {
- SwitchCase switchCase = popNode();
- caseNodes = caseNodes.prepend(switchCase);
- caseCount--;
- }
- pushNode(new NodeList(beginToken, caseNodes, endToken, null));
- }
-
- @override
- void endSwitchCase(
- int labelCount,
- int caseCount,
- Token defaultKeyword,
- Token colonAfterDefault,
- int statementCount,
- Token firstToken,
- Token endToken) {
- NodeList statements = makeNodeList(statementCount, null, null, null);
- NodeList labelsAndCases =
- makeNodeList(labelCount + caseCount, null, null, null);
- pushNode(
- new SwitchCase(labelsAndCases, defaultKeyword, statements, firstToken));
- }
-
- @override
- void handleBreakStatement(
- bool hasTarget, Token breakKeyword, Token endToken) {
- Identifier target = null;
- if (hasTarget) {
- target = popNode();
- }
- pushNode(new BreakStatement(target, breakKeyword, endToken));
- }
-
- @override
- void handleContinueStatement(
- bool hasTarget, Token continueKeyword, Token endToken) {
- Identifier target = null;
- if (hasTarget) {
- target = popNode();
- }
- pushNode(new ContinueStatement(target, continueKeyword, endToken));
- }
-
- @override
- void handleEmptyStatement(Token token) {
- pushNode(new EmptyStatement(token));
- }
-
- @override
- void beginFactoryMethod(
- Token lastConsumed, Token externalToken, Token constToken) {
- if (externalToken != null) {
- Link<Node> poppedNodes = const Link<Node>();
- if (constToken != null) {
- poppedNodes = poppedNodes.prepend(new Identifier(constToken));
- }
- poppedNodes = poppedNodes.prepend(new Identifier(externalToken));
- NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- } else if (constToken != null) {
- Link<Node> poppedNodes = const Link<Node>();
- poppedNodes = poppedNodes.prepend(new Identifier(constToken));
- NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- } else {
- pushNode(Modifiers.EMPTY);
- }
- }
-
- @override
- void endFactoryMethod(
- Token beginToken, Token factoryKeyword, Token endToken) {
- super.endFactoryMethod(beginToken, factoryKeyword, endToken);
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList formals = popNode();
- Node name = popNode();
- Modifiers modifiers = popNode();
-
- // The parser does not report `factory` as a modifier,
- // but NodeListener considers it to be a modifier.
- // We cannot simply add all tokens from beginToken to factoryToken
- // inclusive because there may be invalid tokens that the parser
- // has skipped and the factoryKeyword may itself be out of order.
- // Because modifiers may be out of order, and some code relies
- // on the order of the nodes in modifiers, we must insert the factory
- // keyword in the correct place by rebuilding the modifiers.
- int modifierCount = 0;
- Identifier factoryNode = new Identifier(factoryKeyword);
- modifiers.nodes.nodes.forEach((Node node) {
- if (factoryNode != null &&
- factoryNode.token.charOffset < node.getBeginToken().charOffset) {
- pushNode(factoryNode);
- ++modifierCount;
- factoryNode = null;
- }
- pushNode(node);
- ++modifierCount;
- });
- if (factoryNode != null) {
- pushNode(factoryNode);
- ++modifierCount;
- }
- if (modifierCount == 0) {
- pushNode(Modifiers.EMPTY);
- } else {
- NodeList modifierNodes = makeNodeList(modifierCount, null, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- }
- modifiers = popNode();
-
- pushNode(new FunctionExpression(
- name, null, formals, body, null, modifiers, null, null, asyncModifier));
- }
-
- @override
- void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
- Token inKeyword, Token endToken) {
- Statement body = popNode();
- Expression expression = popNode();
- Node declaredIdentifier = popNode();
- if (awaitToken == null) {
- pushNode(new SyncForIn(
- declaredIdentifier, expression, body, forToken, inKeyword));
- } else {
- pushNode(new AsyncForIn(declaredIdentifier, expression, body, awaitToken,
- forToken, inKeyword));
- }
- }
-
- @override
- void endMetadataStar(int count) {
- if (0 == count) {
- pushNode(null);
- } else {
- pushNode(makeNodeList(count, null, null, ' '));
- }
- }
-
- @override
- void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
- NodeList arguments = popNode();
- if (arguments == null) {
- // This is a constant expression.
- Identifier name;
- if (periodBeforeName != null) {
- name = popNode();
- }
- NodeList typeArguments = popNode();
- Node receiver = popNode();
- if (typeArguments != null) {
- receiver = new NominalTypeAnnotation(receiver, typeArguments);
- recoverableError(typeArguments, 'Type arguments are not allowed here.');
- } else {
- Identifier identifier = receiver.asIdentifier();
- Send send = receiver.asSend();
- if (identifier != null) {
- receiver = new Send(null, identifier);
- } else if (send == null) {
- internalError(node: receiver);
- }
- }
- Send send = receiver;
- if (name != null) {
- send = new Send(receiver, name);
- }
- pushNode(new Metadata(beginToken, send));
- } else {
- // This is a const constructor call.
- endConstructorReference(beginToken, periodBeforeName, endToken);
- Node constructor = popNode();
- pushNode(new Metadata(beginToken,
- new NewExpression(null, new Send(null, constructor, arguments))));
- }
- }
-
- @override
- void endAssert(Token assertKeyword, fasta.Assert kind, Token leftParenthesis,
- Token commaToken, Token semicolonToken) {
- Node message;
- Node condition;
- if (commaToken != null) {
- message = popNode();
- }
- condition = popNode();
- pushNode(new Assert(assertKeyword, condition, message, semicolonToken));
- }
-
- @override
- void endFunctionExpression(Token beginToken, Token token) {
- Statement body = popNode();
- AsyncModifier asyncModifier = popNode();
- NodeList formals = popNode();
- NodeList typeVariables = popNode();
- pushNode(new FunctionExpression(null, typeVariables, formals, body, null,
- Modifiers.EMPTY, null, null, asyncModifier));
- }
-
- @override
- void handleIsOperator(Token operator, Token not, Token endToken) {
- TypeAnnotation type = popNode();
- Expression expression = popNode();
- Node argument;
- if (not != null) {
- argument = new Send.prefix(type, new Operator(not));
- } else {
- argument = type;
- }
-
- NodeList arguments = new NodeList.singleton(argument);
- pushNode(new Send(expression, new Operator(operator), arguments));
- }
-
- @override
- void handleLabel(Token colon) {
- Identifier name = popNode();
- pushNode(new Label(name, colon));
- }
-
- @override
- void endLabeledStatement(int labelCount) {
- Statement statement = popNode();
- NodeList labels = makeNodeList(labelCount, null, null, null);
- pushNode(new LabeledStatement(labels, statement));
- }
-
- @override
- void endTypeVariable(Token token, Token extendsOrSuper) {
- inTypeVariable = false;
- NominalTypeAnnotation bound = popNode();
- Identifier name = popNode();
- // TODO(paulberry): type variable metadata should not be ignored. See
- // dartbug.com/5841.
- popNode(); // Metadata
- pushNode(new TypeVariable(name, extendsOrSuper, bound));
- rejectBuiltInIdentifier(name);
- }
-
- @override
- void log(message) {
- reporter.log(message);
- }
-
- @override
- void handleInvalidFunctionBody(Token token) {
- if (!lastErrorWasNativeFunctionBody) {
- pushNode(null);
- }
- lastErrorWasNativeFunctionBody = false;
- }
-
- void internalError({Token token, Node node}) {
- // TODO(ahe): This should call reporter.internalError.
- Spannable spannable = (token == null) ? node : token;
- failedAt(spannable, 'Internal error in parser.');
- }
-}
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
deleted file mode 100644
index cc101ce..0000000
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.task;
-
-import '../common.dart';
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../elements/modelx.dart' show ElementX;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart' show Node;
-import 'element_listener.dart' show ScannerOptions;
-import 'package:front_end/src/fasta/parser.dart' show Parser, ParserError;
-import 'node_listener.dart' show NodeListener;
-
-class ParserTask extends CompilerTask {
- final Compiler compiler;
-
- ParserTask(Compiler compiler)
- : compiler = compiler,
- super(compiler.measurer);
-
- String get name => 'Parser';
-
- Node parse(ElementX element) {
- return measure(() => element.parseNode(compiler.parsingContext));
- }
-
- Node parseCompilationUnit(Token token) {
- return measure(() {
- NodeListener listener =
- new NodeListener(const ScannerOptions(), compiler.reporter, null);
- Parser parser = new Parser(listener);
- try {
- parser.parseUnit(token);
- } on ParserError catch (_) {
- assert(compiler.compilationFailed,
- failedAt(compiler.reporter.spanFromToken(token)));
- return listener.makeNodeList(0, null, null, '\n');
- }
- Node result = listener.popNode();
- assert(listener.nodes.isEmpty);
- return result;
- });
- }
-}
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
deleted file mode 100644
index 8207794..0000000
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.partial_elements;
-
-import '../common.dart';
-import '../common/resolution.dart' show ParsingContext, Resolution;
-import '../elements/resolution_types.dart' show ResolutionDynamicType;
-import '../elements/elements.dart'
- show
- CompilationUnitElement,
- Element,
- ElementKind,
- GetterElement,
- MetadataAnnotation,
- SetterElement,
- STATE_NOT_STARTED,
- STATE_DONE;
-import '../elements/modelx.dart'
- show
- BaseFunctionElementX,
- ClassElementX,
- ConstructorElementX,
- DeclarationSite,
- ElementX,
- GetterElementX,
- MetadataAnnotationX,
- MethodElementX,
- SetterElementX,
- TypedefElementX,
- VariableList;
-import '../elements/visitor.dart' show ElementVisitor;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import '../tree/tree.dart';
-import 'package:front_end/src/fasta/parser.dart'
- show ClassMemberParser, Listener, MemberKind, Parser, ParserError;
-import 'member_listener.dart' show MemberListener;
-import 'node_listener.dart' show NodeListener;
-
-class ClassElementParser extends ClassMemberParser {
- ClassElementParser(Listener listener) : super(listener);
-
- Token parseFormalParameters(Token token, MemberKind kind) {
- return skipFormalParameters(token, kind);
- }
-}
-
-abstract class PartialElement implements DeclarationSite {
- Token beginToken;
- Token endToken;
-
- bool hasParseError = false;
-
- bool get isMalformed => hasParseError;
-
- DeclarationSite get declarationSite => this;
-}
-
-abstract class PartialFunctionMixin implements BaseFunctionElementX {
- FunctionExpression cachedNode;
- Modifiers get modifiers;
- Token beginToken;
- Token getOrSet;
- Token endToken;
-
- /**
- * The position is computed in the constructor using [findMyName]. Computing
- * it on demand fails in case tokens are GC'd.
- */
- Token _position;
-
- void init(Token beginToken, Token getOrSet, Token endToken) {
- this.beginToken = beginToken;
- this.getOrSet = getOrSet;
- this.endToken = endToken;
- _position = ElementX.findNameToken(
- beginToken,
- modifiers.isFactory || isGenerativeConstructor,
- name,
- enclosingElement.name);
- }
-
- bool get hasNode => cachedNode != null;
-
- FunctionExpression get node {
- assert(cachedNode != null,
- failedAt(this, "Node has not been computed for $this."));
- return cachedNode;
- }
-
- FunctionExpression parseNode(ParsingContext parsing) {
- if (cachedNode != null) return cachedNode;
- parseFunction(Parser p) {
- if (isClassMember) {
- p.parseClassMember(beginToken);
- } else {
- p.parseTopLevelMemberImpl(p.syntheticPreviousToken(beginToken));
- }
- }
-
- cachedNode = parse(parsing, this, declarationSite, parseFunction);
- return cachedNode;
- }
-
- Token get position => _position;
-
- void reusePartialFunctionMixin() {
- cachedNode = null;
- }
-
- DeclarationSite get declarationSite;
-}
-
-abstract class PartialFunctionElement
- implements PartialElement, PartialFunctionMixin {
- factory PartialFunctionElement(String name, Token beginToken, Token getOrSet,
- Token endToken, Modifiers modifiers, Element enclosingElement,
- {bool hasBody: true}) {
- if (getOrSet == null) {
- return new PartialMethodElement(
- name, beginToken, endToken, modifiers, enclosingElement,
- hasBody: hasBody);
- } else if (identical(getOrSet.stringValue, 'get')) {
- return new PartialGetterElement(
- name, beginToken, getOrSet, endToken, modifiers, enclosingElement,
- hasBody: hasBody);
- } else {
- assert(identical(getOrSet.stringValue, 'set'));
- return new PartialSetterElement(
- name, beginToken, getOrSet, endToken, modifiers, enclosingElement,
- hasBody: hasBody);
- }
- }
-
- PartialFunctionElement copyWithEnclosing(Element enclosing);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class PartialMethodElement extends MethodElementX
- with PartialElement, PartialFunctionMixin
- implements PartialFunctionElement {
- PartialMethodElement(String name, Token beginToken, Token endToken,
- Modifiers modifiers, Element enclosing,
- {bool hasBody: true})
- : super(name, ElementKind.FUNCTION, modifiers, enclosing, hasBody) {
- init(beginToken, null, endToken);
- }
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-
- PartialMethodElement copyWithEnclosing(Element enclosing) {
- return new PartialMethodElement(
- name, beginToken, endToken, modifiers, enclosing,
- hasBody: hasBody);
- }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class PartialGetterElement extends GetterElementX
- with PartialElement, PartialFunctionMixin
- implements GetterElement, PartialFunctionElement {
- PartialGetterElement(String name, Token beginToken, Token getToken,
- Token endToken, Modifiers modifiers, Element enclosing,
- {bool hasBody: true})
- : super(name, modifiers, enclosing, hasBody) {
- init(beginToken, getToken, endToken);
- }
-
- @override
- SetterElement get setter => abstractField.setter;
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-
- PartialGetterElement copyWithEnclosing(Element enclosing) {
- return new PartialGetterElement(
- name, beginToken, getOrSet, endToken, modifiers, enclosing,
- hasBody: hasBody);
- }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class PartialSetterElement extends SetterElementX
- with PartialElement, PartialFunctionMixin
- implements SetterElement, PartialFunctionElement {
- PartialSetterElement(String name, Token beginToken, Token setToken,
- Token endToken, Modifiers modifiers, Element enclosing,
- {bool hasBody: true})
- : super(name, modifiers, enclosing, hasBody) {
- init(beginToken, setToken, endToken);
- }
-
- @override
- GetterElement get getter => abstractField.getter;
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-
- PartialSetterElement copyWithEnclosing(Element enclosing) {
- return new PartialSetterElement(
- name, beginToken, getOrSet, endToken, modifiers, enclosing,
- hasBody: hasBody);
- }
-}
-
-// TODO(johnniwinther): Create [PartialGenerativeConstructor] and
-// [PartialFactoryConstructor] subclasses and make this abstract.
-class PartialConstructorElement extends ConstructorElementX
- with PartialElement, PartialFunctionMixin {
- PartialConstructorElement(String name, Token beginToken, Token endToken,
- ElementKind kind, Modifiers modifiers, Element enclosing)
- : super(name, kind, modifiers, enclosing) {
- init(beginToken, null, endToken);
- }
-
- void reuseElement() {
- super.reuseElement();
- reusePartialFunctionMixin();
- }
-}
-
-class PartialFieldList extends VariableList with PartialElement {
- PartialFieldList(
- Token beginToken, Token endToken, Modifiers modifiers, bool hasParseError)
- : super(modifiers) {
- super.beginToken = beginToken;
- super.endToken = endToken;
- super.hasParseError = hasParseError;
- }
-
- VariableDefinitions parseNode(Element element, ParsingContext parsing) {
- if (definitions != null) return definitions;
- DiagnosticReporter reporter = parsing.reporter;
- reporter.withCurrentElement(element, () {
- definitions = parse(parsing, element, declarationSite,
- (Parser parser) => parser.parseClassMember(beginToken));
-
- if (!hasParseError &&
- !definitions.modifiers.isVar &&
- !definitions.modifiers.isFinal &&
- !definitions.modifiers.isConst &&
- definitions.type == null &&
- !definitions.isErroneous) {
- reporter.reportErrorMessage(definitions, MessageKind.GENERIC, {
- 'text': 'A field declaration must start with var, final, '
- 'const, or a type annotation.'
- });
- }
- });
- return definitions;
- }
-
- computeType(Element element, Resolution resolution) {
- if (type != null) return type;
- // TODO(johnniwinther): Compute this in the resolver.
- VariableDefinitions node = parseNode(element, resolution.parsingContext);
- if (node.type != null) {
- type = resolution.reporter.withCurrentElement(element, () {
- return resolution.resolveTypeAnnotation(element, node.type);
- });
- } else {
- type = const ResolutionDynamicType();
- }
- assert(type != null);
- return type;
- }
-}
-
-class PartialTypedefElement extends TypedefElementX with PartialElement {
- PartialTypedefElement(
- String name, Element enclosing, Token beginToken, Token endToken)
- : super(name, enclosing) {
- this.beginToken = beginToken;
- this.endToken = endToken;
- }
-
- Token get token => beginToken;
-
- Node parseNode(ParsingContext parsing) {
- if (cachedNode != null) return cachedNode;
- cachedNode = parse(parsing, this, declarationSite,
- (p) => p.parseTopLevelDeclaration(token));
- return cachedNode;
- }
-
- Token get position => findMyName(token);
-}
-
-/// A [MetadataAnnotation] which is constructed on demand.
-class PartialMetadataAnnotation extends MetadataAnnotationX
- implements PartialElement {
- Token beginToken; // TODO(ahe): Make this final when issue 22065 is fixed.
-
- final Token tokenAfterEndToken;
-
- Expression cachedNode;
-
- bool hasParseError = false;
-
- PartialMetadataAnnotation(this.beginToken, this.tokenAfterEndToken);
-
- bool get isMalformed => hasParseError;
-
- DeclarationSite get declarationSite => this;
-
- Token get endToken {
- Token token = beginToken;
- while (token.kind != Tokens.EOF_TOKEN) {
- if (identical(token.next, tokenAfterEndToken)) break;
- token = token.next;
- }
- assert(token != null);
- return token;
- }
-
- void set endToken(_) {
- throw new UnsupportedError("endToken=");
- }
-
- Node parseNode(ParsingContext parsing) {
- if (cachedNode != null) return cachedNode;
- var metadata = parse(parsing, annotatedElement, declarationSite,
- (p) => p.parseMetadata(p.syntheticPreviousToken(beginToken)).next);
- if (metadata is Metadata) {
- cachedNode = metadata.expression;
- return cachedNode;
- } else {
- assert(metadata is ErrorNode);
- return metadata;
- }
- }
-
- bool get hasNode => cachedNode != null;
-
- Node get node {
- assert(hasNode, failedAt(this));
- return cachedNode;
- }
-}
-
-class PartialClassElement extends ClassElementX with PartialElement {
- ClassNode cachedNode;
-
- PartialClassElement(
- String name, Token beginToken, Token endToken, Element enclosing, int id)
- : super(name, enclosing, id, STATE_NOT_STARTED) {
- this.beginToken = beginToken;
- this.endToken = endToken;
- }
-
- void set supertypeLoadState(int state) {
- assert(state == STATE_NOT_STARTED || state == supertypeLoadState + 1);
- assert(state <= STATE_DONE);
- super.supertypeLoadState = state;
- }
-
- void set resolutionState(int state) {
- assert(state == STATE_NOT_STARTED || state == resolutionState + 1);
- assert(state <= STATE_DONE);
- super.resolutionState = state;
- }
-
- bool get hasNode => cachedNode != null;
-
- ClassNode get node {
- assert(cachedNode != null,
- failedAt(this, "Node has not been computed for $this."));
- return cachedNode;
- }
-
- ClassNode parseNode(ParsingContext parsing) {
- if (cachedNode != null) return cachedNode;
- DiagnosticReporter reporter = parsing.reporter;
- reporter.withCurrentElement(this, () {
- parsing.measure(() {
- MemberListener listener = new MemberListener(
- parsing.getScannerOptionsFor(this), reporter, this);
- Parser parser = new ClassElementParser(listener);
- try {
- Token token = parser.parseTopLevelDeclaration(beginToken);
- assert(identical(token, endToken.next));
- cachedNode = listener.popNode();
- assert(
- listener.nodes.isEmpty,
- failedAt(reporter.spanFromToken(beginToken),
- "Non-empty listener stack: ${listener.nodes}"));
- } on ParserError {
- // TODO(ahe): Often, a ParserError is thrown while parsing the class
- // body. This means that the stack actually contains most of the
- // information synthesized below. Consider rewriting the parser so
- // endClassDeclaration is called before parsing the class body.
- Identifier name = new Identifier(findMyName(beginToken));
- NodeList typeParameters = null;
- Node supertype = null;
- NodeList interfaces = listener.makeNodeList(0, null, null, ",");
- Token extendsKeyword = null;
- NodeList body = listener.makeNodeList(0, beginToken, endToken, null);
- cachedNode = new ClassNode(
- Modifiers.EMPTY,
- name,
- typeParameters,
- supertype,
- interfaces,
- beginToken,
- extendsKeyword,
- body,
- endToken);
- hasParseError = true;
- }
- });
- if (isPatched) {
- parsing.parsePatchClass(patch);
- }
- });
- return cachedNode;
- }
-
- Token get position => beginToken;
-
- // TODO(johnniwinther): Ensure that modifiers are always available.
- Modifiers get modifiers =>
- cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY;
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitClassElement(this, arg);
- }
-
- PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) {
- return new PartialClassElement(name, beginToken, endToken, enclosing, id);
- }
-}
-
-Node parse(ParsingContext parsing, ElementX element, PartialElement partial,
- doParse(Parser parser)) {
- DiagnosticReporter reporter = parsing.reporter;
- return parsing.measure(() {
- return reporter.withCurrentElement(element, () {
- CompilationUnitElement unit = element.compilationUnit;
- NodeListener listener = new NodeListener(
- parsing.getScannerOptionsFor(element), reporter, unit);
- listener.memberErrors = listener.memberErrors.prepend(false);
- try {
- if (partial.hasParseError) {
- listener.suppressParseErrors = true;
- }
- doParse(new Parser(listener));
- } on ParserError catch (e) {
- partial.hasParseError = true;
- return new ErrorNode(element.position, e.message);
- }
- Node node = listener.popNode();
- assert(listener.nodes.isEmpty);
- return node;
- });
- });
-}
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
deleted file mode 100644
index 00cb3d7..0000000
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ /dev/null
@@ -1,507 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * This library contains the infrastructure to parse and integrate patch files.
- *
- * Three types of elements can be patched: [LibraryElement], [ClassElement],
- * [FunctionElement]. Patches are introduced in patch libraries which are loaded
- * together with the corresponding origin library. Which libraries that are
- * patched is determined by the dart2jsPatchPath field of LibraryInfo found
- * in [:lib/_internal/sdk_library_metadata/lib/libraries.dart:].
- *
- * Patch libraries are parsed like regular library and thus provided with their
- * own elements. These elements which are distinct from the elements from the
- * patched library and the relation between patched and patch elements is
- * established through the [:patch:] and [:origin:] fields found on
- * [LibraryElement], [ClassElement] and [FunctionElement]. The [:patch:] fields
- * are set on the patched elements to point to their corresponding patch
- * element, and the [:origin:] elements are set on the patch elements to point
- * their corresponding patched elements.
- *
- * The fields [Element.isPatched] and [Element.isPatch] can be used to determine
- * whether the [:patch:] or [:origin:] field, respectively, has been set on an
- * element, regardless of whether the element is one of the three patchable
- * element types or not.
- *
- * ## Variants of classes and functions ##
- *
- * With patches there are four variants of classes and function:
- *
- * Regular: A class or function which is not declared in a patch library and
- * which has no corresponding patch.
- * Origin: A class or function which is not declared in a patch library and
- * which has a corresponding patch. Origin functions must use the [:external:]
- * modifier and can have no body. Origin classes and functions are also
- * called 'patched'.
- * Patch: A class or function which is declared in a patch library and which
- * has a corresponding origin. Both patch classes and patch functions must use
- * the [:patch:] modifier.
- * Injected: A class or function (or even field) which is declared in a
- * patch library and which has no corresponding origin. An injected element
- * cannot use the [:patch:] modifier. Injected elements are never visible from
- * outside the patch library in which they have been declared. For this
- * reason, injected elements are often declared private and therefore called
- * also called 'patch private'.
- *
- * Examples of the variants is shown in the code below:
- *
- * // In the origin library:
- * class RegularClass { // A regular class.
- * void regularMethod() {} // A regular method.
- * }
- * class PatchedClass { // An origin class.
- * int regularField; // A regular field.
- * void regularMethod() {} // A regular method.
- * external void patchedMethod(); // An origin method.
- * }
- *
- * // In the patch library:
- * class _InjectedClass { // An injected class.
- * void _injectedMethod() {} // An injected method.
- * }
- * @patch class PatchedClass { // A patch class.
- * int _injectedField; { // An injected field.
- * @patch void patchedMethod() {} // A patch method.
- * }
- *
- *
- * ## Declaration and implementation ##
- *
- * With patches we have two views on elements: as the 'declaration' which
- * introduces the entity and defines its interface, and as the 'implementation'
- * which defines the actual implementation of the entity.
- *
- * Every element has a 'declaration' and an 'implementation' element. For
- * regular and injected elements these are the same. For origin elements the
- * declaration is the element itself and the implementation is the patch element
- * found through its [:patch:] field. For patch elements the implementation is
- * the element itself and the declaration is the origin element found through
- * its [:origin:] field. The declaration and implementation of any element is
- * conveniently available through the [Element.declaration] and
- * [Element.implementation] getters.
- *
- * Most patch-related invariants enforced through-out the compiler are defined
- * in terms of 'declaration' and 'implementation', and tested through the
- * predicate getters [Element.isDeclaration] and [Element.isImplementation].
- * Patch invariants are stated both in comments and as assertions.
- *
- *
- * ## General invariant guidelines ##
- *
- * For [LibraryElement] we always use declarations. This means the
- * [Element.getLibrary] method will only return library declarations. Patch
- * library implementations are only accessed through calls to
- * [Element.getImplementationLibrary] which is used to setup the correct
- * [Element.enclosingElement] relation between patch/injected elements and the
- * patch library.
- *
- * For [ClassElement] and [FunctionElement] we use declarations for determining
- * identity and implementations for work based on the AST nodes, such as
- * resolution, type-checking, type inference, building SSA graphs, etc.
- * - Worklist only contain declaration elements.
- * - Most maps and sets use declarations exclusively, and their individual
- * invariants are stated in the field comments.
- * - [tree.TreeElements] only map to patch elements from inside a patch library.
- * TODO(johnniwinther): Simplify this invariant to use only declarations in
- * [tree.TreeElements].
- * - Builders shift between declaration and implementation depending on usages.
- * - Compile-time constants use constructor implementation exclusively.
- * - Work on function parameters is performed on the declaration of the function
- * element.
- */
-
-library dart2js.patchparser;
-
-import 'dart:async';
-
-import 'package:front_end/src/fasta/parser.dart'
- show Listener, Parser, ParserError;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import 'common/tasks.dart' show CompilerTask;
-import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constants/values.dart' show ConstantValue;
-import 'elements/resolution_types.dart' show ResolutionDartType;
-import 'elements/elements.dart';
-import 'elements/modelx.dart'
- show
- BaseFunctionElementX,
- ClassElementX,
- GetterElementX,
- LibraryElementX,
- MetadataAnnotationX,
- SetterElementX;
-import 'elements/names.dart';
-import 'enqueue.dart' show DeferredAction;
-import 'id_generator.dart';
-import 'library_loader.dart' show LibraryLoader;
-import 'parser/element_listener.dart' show ElementListener;
-import 'parser/member_listener.dart' show MemberListener;
-import 'parser/partial_elements.dart'
- show ClassElementParser, PartialClassElement;
-import 'parser/diet_parser_task.dart' show PartialParser;
-import 'script.dart';
-
-class PatchParserTask extends CompilerTask {
- final String name = "Patching Parser";
- final Compiler compiler;
- DiagnosticReporter get reporter => compiler.reporter;
-
- PatchParserTask(Compiler compiler)
- : compiler = compiler,
- super(compiler.measurer);
-
- /**
- * Scans a library patch file, applies the method patches and
- * injections to the library, and returns a list of class
- * patches.
- */
- Future patchLibrary(
- LibraryLoader loader, Uri patchUri, LibraryElement originLibrary) {
- return compiler.readScript(patchUri, originLibrary).then((Script script) {
- var patchLibrary = new LibraryElementX(script, null, originLibrary);
- return reporter.withCurrentElement(patchLibrary, () {
- loader.registerNewLibrary(patchLibrary);
- reporter.withCurrentElement(patchLibrary.entryCompilationUnit, () {
- // This patches the elements of the patch library into [library].
- // Injected elements are added directly under the compilation unit.
- // Patch elements are stored on the patched functions or classes.
- scanLibraryElements(patchLibrary.entryCompilationUnit);
- });
- return loader.processLibraryTags(patchLibrary);
- });
- });
- }
-
- void scanLibraryElements(CompilationUnitElement compilationUnit) {
- measure(() {
- // TODO(johnniwinther): Test that parts and exports are handled correctly.
- Script script = compilationUnit.script;
- Token tokens = compiler.scanner.scanFile(script.file);
- Listener patchListener = new PatchElementListener(
- compiler, compilationUnit, compiler.idGenerator);
- try {
- new PartialParser(patchListener).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.
- reporter.internalError(
- compilationUnit, "Parser error in patch file: $e");
- }
- });
- }
-
- void parsePatchClassNode(PartialClassElement cls) {
- // Parse [PartialClassElement] using a "patch"-aware parser instead
- // of calling its [parseNode] method.
- if (cls.cachedNode != null) return;
-
- measure(() => reporter.withCurrentElement(cls, () {
- MemberListener listener = new PatchMemberListener(compiler, cls);
- Parser parser = new ClassElementParser(listener);
- try {
- Token token = parser.parseTopLevelDeclaration(cls.beginToken);
- assert(identical(token, cls.endToken.next));
- } 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.
- reporter.internalError(cls, "Parser error in patch file: $e");
- }
- cls.cachedNode = listener.popNode();
- assert(listener.nodes.isEmpty);
- }));
- }
-}
-
-class PatchMemberListener extends MemberListener {
- final Compiler compiler;
-
- PatchMemberListener(Compiler compiler, ClassElement enclosingClass)
- : this.compiler = compiler,
- super(compiler.parsingContext.getScannerOptionsFor(enclosingClass),
- compiler.reporter, enclosingClass);
-
- @override
- void addMember(Element patch) {
- addMetadata(patch);
-
- if (_isMarkedAsPatch(compiler, patch)) {
- Element origin = enclosingClass.origin.localLookup(patch.name);
- patchElement(compiler, reporter, origin, patch);
- enclosingClass.addMember(patch, reporter);
- } else {
- if (Name.isPublicName(patch.name)) {
- reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
- }
- enclosingClass.addMember(patch, reporter);
- }
- }
-}
-
-/**
- * Extension of [ElementListener] for parsing patch files.
- */
-class PatchElementListener extends ElementListener implements Listener {
- final Compiler compiler;
-
- PatchElementListener(Compiler compiler, CompilationUnitElement patchElement,
- IdGenerator idGenerator)
- : this.compiler = compiler,
- super(compiler.parsingContext.getScannerOptionsFor(patchElement),
- compiler.reporter, patchElement, idGenerator);
-
- @override
- void pushElement(Element patch) {
- popMetadata(patch);
-
- if (_isMarkedAsPatch(compiler, patch)) {
- LibraryElement originLibrary = compilationUnitElement.library;
- assert(originLibrary.isPatched);
- Element origin = originLibrary.localLookup(patch.name);
- patchElement(compiler, reporter, origin, patch);
- compilationUnitElement.addMember(patch, reporter);
- } else {
- if (Name.isPublicName(patch.name)) {
- reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
- }
- compilationUnitElement.addMember(patch, reporter);
- }
- }
-}
-
-void patchElement(Compiler compiler, DiagnosticReporter reporter,
- Element origin, Element patch) {
- if (origin == null) {
- reporter.reportErrorMessage(
- patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
- return;
- }
-
- if (!(origin.isClass ||
- origin.isConstructor ||
- origin.isFunction ||
- origin.isAbstractField)) {
- // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
- reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE);
- return;
- }
- if (patch.isClass) {
- tryPatchClass(compiler, reporter, origin, patch);
- } else if (patch.isGetter) {
- tryPatchGetter(reporter, origin, patch);
- } else if (patch.isSetter) {
- tryPatchSetter(reporter, origin, patch);
- } else if (patch.isConstructor) {
- tryPatchConstructor(reporter, origin, patch);
- } else if (patch.isFunction) {
- tryPatchFunction(reporter, origin, patch);
- } else {
- // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
- reporter.reportErrorMessage(patch, MessageKind.PATCH_NONPATCHABLE);
- }
-}
-
-void tryPatchClass(Compiler compiler, DiagnosticReporter reporter,
- Element origin, ClassElement patch) {
- if (!origin.isClass) {
- reporter.reportError(
- reporter.createMessage(
- origin, MessageKind.PATCH_NON_CLASS, {'className': patch.name}),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_CLASS,
- {'className': patch.name}),
- ]);
- return;
- }
- patchClass(compiler, reporter, origin, patch);
-}
-
-void patchClass(Compiler compiler, DiagnosticReporter reporter,
- ClassElementX origin, ClassElementX patch) {
- if (origin.isPatched) {
- reporter.internalError(origin, "Patching the same class more than once.");
- }
- origin.applyPatch(patch);
-}
-
-/// Abstract interface for pre-resolution detection of metadata.
-///
-/// The detection is handled in two steps:
-/// - match the annotation syntactically and assume that the annotation is valid
-/// if it looks correct,
-/// - setup a deferred action to check that the annotation has a valid constant
-/// value and report an internal error if not.
-abstract class EagerAnnotationHandler<T> {
- const EagerAnnotationHandler();
-
- /// Checks that [annotation] looks like a matching annotation and optionally
- /// applies actions on [element]. Returns a non-null annotation marker if the
- /// annotation matched and should be validated.
- T apply(Compiler compiler, Element element, MetadataAnnotation annotation);
-
- /// Checks that the annotation value is valid.
- void validate(Compiler compiler, Element element,
- MetadataAnnotation annotation, ConstantValue constant);
-
- /// Checks [element] for metadata matching the [handler]. Return a non-null
- /// annotation marker matching metadata was found.
- static T checkAnnotation<T>(
- Compiler compiler, Element element, EagerAnnotationHandler<T> handler) {
- for (MetadataAnnotation annotation in element.implementation.metadata) {
- T result = handler.apply(compiler, element, annotation);
- if (result != handler.defaultResult) {
- // TODO(johnniwinther): Perform this check in
- // [Compiler.processLoadedLibraries].
- compiler.libraryLoader
- .registerDeferredAction(new DeferredAction(element, () {
- annotation.ensureResolved(compiler.resolution);
- handler.validate(compiler, element, annotation,
- compiler.constants.getConstantValue(annotation.constant));
- }));
- return result;
- }
- }
- return handler.defaultResult;
- }
-
- /// Result that signals the absence of annotations.
- T get defaultResult => null;
-}
-
-/// Annotation handler for pre-resolution detection of `@patch` annotations.
-class PatchAnnotationHandler extends EagerAnnotationHandler<bool> {
- const PatchAnnotationHandler();
-
- @override
- bool apply(
- Compiler compiler, Element element, MetadataAnnotation annotation) {
- MetadataAnnotationX meta = annotation;
- if (meta.beginToken?.next?.lexeme == 'patch') {
- return true;
- }
- return null;
- }
-
- @override
- void validate(Compiler compiler, Element element,
- MetadataAnnotation annotation, ConstantValue constant) {
- ResolutionDartType annotationType =
- constant.getType(compiler.resolution.commonElements);
- if (annotationType.element !=
- compiler.resolution.commonElements.patchAnnotationClass) {
- DiagnosticReporter reporter = compiler.reporter;
- reporter.internalError(annotation, 'Invalid patch annotation.');
- }
- }
-}
-
-void tryPatchGetter(
- DiagnosticReporter reporter, Element origin, FunctionElement patch) {
- if (!origin.isAbstractField) {
- reporter.reportError(
- reporter.createMessage(
- origin, MessageKind.PATCH_NON_GETTER, {'name': origin.name}),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_GETTER,
- {'getterName': patch.name}),
- ]);
- return;
- }
- AbstractFieldElement originField = origin;
- if (originField.getter == null) {
- reporter.reportError(
- reporter.createMessage(
- origin, MessageKind.PATCH_NO_GETTER, {'getterName': patch.name}),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_GETTER,
- {'getterName': patch.name}),
- ]);
- return;
- }
- GetterElementX getter = originField.getter;
- patchFunction(reporter, getter, patch);
-}
-
-void tryPatchSetter(
- DiagnosticReporter reporter, Element origin, FunctionElement patch) {
- if (!origin.isAbstractField) {
- reporter.reportError(
- reporter.createMessage(
- origin, MessageKind.PATCH_NON_SETTER, {'name': origin.name}),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_SETTER,
- {'setterName': patch.name}),
- ]);
- return;
- }
- AbstractFieldElement originField = origin;
- if (originField.setter == null) {
- reporter.reportError(
- reporter.createMessage(
- origin, MessageKind.PATCH_NO_SETTER, {'setterName': patch.name}),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_SETTER,
- {'setterName': patch.name}),
- ]);
- return;
- }
- SetterElementX setter = originField.setter;
- patchFunction(reporter, setter, patch);
-}
-
-void tryPatchConstructor(
- DiagnosticReporter reporter, Element origin, FunctionElement patch) {
- if (!origin.isConstructor) {
- reporter.reportError(
- reporter.createMessage(origin, MessageKind.PATCH_NON_CONSTRUCTOR,
- {'constructorName': patch.name}),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
- {'constructorName': patch.name}),
- ]);
- return;
- }
- patchFunction(reporter, origin, patch);
-}
-
-void tryPatchFunction(
- DiagnosticReporter reporter, Element origin, FunctionElement patch) {
- if (!origin.isFunction) {
- reporter.reportError(
- reporter.createMessage(origin, MessageKind.PATCH_NON_FUNCTION,
- {'functionName': patch.name}),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_FUNCTION,
- {'functionName': patch.name}),
- ]);
- return;
- }
- patchFunction(reporter, origin, patch);
-}
-
-void patchFunction(DiagnosticReporter reporter, BaseFunctionElementX origin,
- BaseFunctionElementX patch) {
- if (!origin.modifiers.isExternal) {
- reporter.reportError(
- reporter.createMessage(origin, MessageKind.PATCH_NON_EXTERNAL),
- <DiagnosticMessage>[
- reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_FUNCTION,
- {'functionName': patch.name}),
- ]);
- return;
- }
- if (origin.isPatched) {
- reporter.internalError(
- origin, "Trying to patch a function more than once.");
- }
- origin.applyPatch(patch);
-}
-
-bool _isMarkedAsPatch(Compiler compiler, Element element) {
- return EagerAnnotationHandler.checkAnnotation(
- compiler, element, const PatchAnnotationHandler()) ==
- true;
-}
diff --git a/pkg/compiler/lib/src/resolution/access_semantics.dart b/pkg/compiler/lib/src/resolution/access_semantics.dart
deleted file mode 100644
index 647e14d..0000000
--- a/pkg/compiler/lib/src/resolution/access_semantics.dart
+++ /dev/null
@@ -1,486 +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.
-
-/**
- * Code for classifying the semantics of identifiers appearing in a Dart file.
- */
-library dart2js.access_semantics;
-
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/names.dart';
-
-/// Enum representing the different kinds of destinations which a property
-/// access or method or function invocation might refer to.
-enum AccessKind {
- /// The destination of the conditional access is an instance method, property,
- /// or field of a class, and thus must be determined dynamically.
- CONDITIONAL_DYNAMIC_PROPERTY,
-
- /// The destination of the access is an instance method, property, or field
- /// of a class, and thus must be determined dynamically.
- DYNAMIC_PROPERTY,
-
- // TODO(johnniwinther): Split these cases into captured and non-captured
- // local access.
- /// The destination of the access is a function that is defined locally within
- /// an enclosing function or method.
- LOCAL_FUNCTION,
-
- /// The destination of the access is a non-final variable that is defined
- /// locally within an enclosing function or method.
- LOCAL_VARIABLE,
-
- /// The destination of the access is a final variable that is defined locally
- /// within an enclosing function or method.
- FINAL_LOCAL_VARIABLE,
-
- /// The destination of the access is a variable that is defined as a non-final
- /// parameter to an enclosing function or method.
- PARAMETER,
-
- /// The destination of the access is a variable that is defined as a final
- /// parameter to an enclosing function or method.
- FINAL_PARAMETER,
-
- /// The destination of the access is a non-final field that is defined
- /// statically within a class.
- STATIC_FIELD,
-
- /// The destination of the access is a final field that is defined statically
- /// within a class.
- FINAL_STATIC_FIELD,
-
- /// The destination of the access is a method that is defined statically
- /// within a class.
- STATIC_METHOD,
-
- /// The destination of the access is a property getter that is defined
- /// statically within a class.
- STATIC_GETTER,
-
- /// The destination of the access is a property setter that is defined
- /// statically within a class.
- STATIC_SETTER,
-
- /// The destination of the access is a non-final top level variable defined
- /// within a library.
- TOPLEVEL_FIELD,
-
- /// The destination of the access is a final top level variable defined within
- /// a library.
- FINAL_TOPLEVEL_FIELD,
-
- /// The destination of the access is a top level method defined within a
- /// library.
- TOPLEVEL_METHOD,
-
- /// The destination of the access is a top level property getter defined
- /// within a library.
- TOPLEVEL_GETTER,
-
- /// The destination of the access is a top level property setter defined
- /// within a library.
- TOPLEVEL_SETTER,
-
- /// The destination of the access is a toplevel class, or named mixin
- /// application.
- CLASS_TYPE_LITERAL,
-
- /// The destination of the access is a function typedef.
- TYPEDEF_TYPE_LITERAL,
-
- /// The destination of the access is the built-in type "dynamic".
- DYNAMIC_TYPE_LITERAL,
-
- /// The destination of the access is a type parameter of the enclosing class.
- TYPE_PARAMETER_TYPE_LITERAL,
-
- /// The destination of the access is a (complex) expression. For instance the
- /// function expression `(){}` in the function expression invocation `(){}()`.
- EXPRESSION,
-
- /// The destination of the access is `this` of the enclosing class.
- THIS,
-
- /// The destination of the access is an instance method, property, or field
- /// of the enclosing class.
- THIS_PROPERTY,
-
- /// The destination of the access is a non-final field of the super class of
- /// the enclosing class.
- SUPER_FIELD,
-
- /// The destination of the access is a final field of the super class of the
- /// enclosing class.
- SUPER_FINAL_FIELD,
-
- /// The destination of the access is a method of the super class of the
- /// enclosing class.
- SUPER_METHOD,
-
- /// The destination of the access is a getter of the super class of the
- /// enclosing class.
- SUPER_GETTER,
-
- /// The destination of the access is a setter of the super class of the
- /// enclosing class.
- SUPER_SETTER,
-
- /// Compound access where read and write access different elements.
- /// See [CompoundAccessKind].
- COMPOUND,
-
- /// The destination of the access is a compile-time constant.
- CONSTANT,
-
- /// The destination of the access is unresolved in a static context.
- UNRESOLVED,
-
- /// The destination of the access is unresolved super access.
- UNRESOLVED_SUPER,
-
- /// The destination is invalid as an access. For instance a prefix used
- /// as an expression.
- INVALID,
-}
-
-enum CompoundAccessKind {
- /// Read from a static getter and write to a static setter.
- STATIC_GETTER_SETTER,
-
- /// Read from a static method (closurize) and write to a static setter.
- STATIC_METHOD_SETTER,
-
- /// Read from an unresolved static getter and write to a static setter.
- UNRESOLVED_STATIC_GETTER,
-
- /// Read from a static getter and write to an unresolved static setter.
- UNRESOLVED_STATIC_SETTER,
-
- /// Read from a top level getter and write to a top level setter.
- TOPLEVEL_GETTER_SETTER,
-
- /// Read from a top level method (closurize) and write to top level setter.
- TOPLEVEL_METHOD_SETTER,
-
- /// Read from an unresolved top level getter and write to a top level setter.
- UNRESOLVED_TOPLEVEL_GETTER,
-
- /// Read from a top level getter and write to an unresolved top level setter.
- UNRESOLVED_TOPLEVEL_SETTER,
-
- /// Read from one superclass field and write to another.
- SUPER_FIELD_FIELD,
-
- /// Read from a superclass field and write to a superclass setter.
- SUPER_FIELD_SETTER,
-
- /// Read from a superclass getter and write to a superclass setter.
- SUPER_GETTER_SETTER,
-
- /// Read from a superclass method (closurize) and write to a superclass
- /// setter.
- SUPER_METHOD_SETTER,
-
- /// Read from a superclass getter and write to a superclass field.
- SUPER_GETTER_FIELD,
-
- /// Read from a superclass where the getter is unresolved.
- // TODO(johnniwinther): Use [AccessKind.SUPER_GETTER] when the erroneous
- // element is no longer needed.
- UNRESOLVED_SUPER_GETTER,
-
- /// Read from a superclass getter and write to an unresolved setter.
- // TODO(johnniwinther): Use [AccessKind.SUPER_SETTER] when the erroneous
- // element is no longer needed.
- UNRESOLVED_SUPER_SETTER,
-}
-
-/**
- * Data structure used to classify the semantics of a property access or method
- * or function invocation.
- */
-abstract class AccessSemantics {
- /**
- * The kind of access.
- */
- final AccessKind kind;
-
- /**
- * The element being accessed, if statically known. This will be null if
- * [kind] is DYNAMIC or if the element is undefined (e.g. an attempt to
- * access a non-existent static method in a class).
- */
- Element get element => null;
-
- ConstantExpression get constant => null;
-
- /// The element for the getter in case of a compound access,
- /// [element] otherwise.
- Element get getter => element;
-
- /// The element for the setter in case of a compound access,
- /// [element] otherwise.
- Element get setter => element;
-
- Name get name => null;
-
- const AccessSemantics._(this.kind);
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.write('AccessSemantics[');
- sb.write('kind=$kind,');
- if (element != null) {
- if (getter != setter) {
- sb.write('getter=');
- sb.write('${getter}');
- sb.write(',setter=');
- sb.write('${setter}');
- } else {
- sb.write('element=');
- sb.write('${element}');
- }
- } else if (name != null) {
- sb.write('name=');
- sb.write(name);
- }
- sb.write(']');
- return sb.toString();
- }
-}
-
-class DynamicAccess extends AccessSemantics {
- final Name name;
-
- const DynamicAccess.expression()
- : name = null,
- super._(AccessKind.EXPRESSION);
-
- const DynamicAccess.thisAccess()
- : name = null,
- super._(AccessKind.THIS);
-
- const DynamicAccess.thisProperty(this.name)
- : super._(AccessKind.THIS_PROPERTY);
-
- const DynamicAccess.dynamicProperty(this.name)
- : super._(AccessKind.DYNAMIC_PROPERTY);
-
- const DynamicAccess.ifNotNullProperty(this.name)
- : super._(AccessKind.CONDITIONAL_DYNAMIC_PROPERTY);
-}
-
-class ConstantAccess extends AccessSemantics {
- final ConstantExpression constant;
-
- ConstantAccess(AccessKind kind, this.constant) : super._(kind);
-
- ConstantAccess.classTypeLiteral(this.constant)
- : super._(AccessKind.CLASS_TYPE_LITERAL);
-
- ConstantAccess.typedefTypeLiteral(this.constant)
- : super._(AccessKind.TYPEDEF_TYPE_LITERAL);
-
- ConstantAccess.dynamicTypeLiteral(this.constant)
- : super._(AccessKind.DYNAMIC_TYPE_LITERAL);
-}
-
-class StaticAccess extends AccessSemantics {
- final Element element;
-
- StaticAccess.internal(AccessKind kind, this.element) : super._(kind);
-
- StaticAccess.superSetter(MethodElement this.element)
- : super._(AccessKind.SUPER_SETTER);
-
- StaticAccess.superField(FieldElement this.element)
- : super._(AccessKind.SUPER_FIELD);
-
- StaticAccess.superFinalField(FieldElement this.element)
- : super._(AccessKind.SUPER_FINAL_FIELD);
-
- StaticAccess.superMethod(MethodElement this.element)
- : super._(AccessKind.SUPER_METHOD);
-
- StaticAccess.superGetter(MethodElement this.element)
- : super._(AccessKind.SUPER_GETTER);
-
- StaticAccess.typeParameterTypeLiteral(TypeVariableElement this.element)
- : super._(AccessKind.TYPE_PARAMETER_TYPE_LITERAL);
-
- StaticAccess.localFunction(LocalFunctionElement this.element)
- : super._(AccessKind.LOCAL_FUNCTION);
-
- StaticAccess.localVariable(LocalVariableElement this.element)
- : super._(AccessKind.LOCAL_VARIABLE);
-
- StaticAccess.finalLocalVariable(LocalVariableElement this.element)
- : super._(AccessKind.FINAL_LOCAL_VARIABLE);
-
- StaticAccess.parameter(ParameterElement this.element)
- : super._(AccessKind.PARAMETER);
-
- StaticAccess.finalParameter(ParameterElement this.element)
- : super._(AccessKind.FINAL_PARAMETER);
-
- StaticAccess.staticField(FieldElement this.element)
- : super._(AccessKind.STATIC_FIELD);
-
- StaticAccess.finalStaticField(FieldElement this.element)
- : super._(AccessKind.FINAL_STATIC_FIELD);
-
- StaticAccess.staticMethod(MethodElement this.element)
- : super._(AccessKind.STATIC_METHOD);
-
- StaticAccess.staticGetter(MethodElement this.element)
- : super._(AccessKind.STATIC_GETTER);
-
- StaticAccess.staticSetter(MethodElement this.element)
- : super._(AccessKind.STATIC_SETTER);
-
- StaticAccess.topLevelField(FieldElement this.element)
- : super._(AccessKind.TOPLEVEL_FIELD);
-
- StaticAccess.finalTopLevelField(FieldElement this.element)
- : super._(AccessKind.FINAL_TOPLEVEL_FIELD);
-
- StaticAccess.topLevelMethod(MethodElement this.element)
- : super._(AccessKind.TOPLEVEL_METHOD);
-
- StaticAccess.topLevelGetter(MethodElement this.element)
- : super._(AccessKind.TOPLEVEL_GETTER);
-
- StaticAccess.topLevelSetter(MethodElement this.element)
- : super._(AccessKind.TOPLEVEL_SETTER);
-
- StaticAccess.unresolved(this.element) : super._(AccessKind.UNRESOLVED);
-
- StaticAccess.unresolvedSuper(this.element)
- : super._(AccessKind.UNRESOLVED_SUPER);
-
- StaticAccess.invalid(this.element) : super._(AccessKind.INVALID);
-}
-
-class CompoundAccessSemantics extends AccessSemantics {
- final CompoundAccessKind compoundAccessKind;
- final Element getter;
- final Element setter;
-
- CompoundAccessSemantics(this.compoundAccessKind, this.getter, this.setter)
- : super._(AccessKind.COMPOUND);
-
- Element get element => setter;
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.write('CompoundAccessSemantics[');
- sb.write('kind=$compoundAccessKind');
- if (getter != null) {
- sb.write(',getter=');
- sb.write('${getter}');
- }
- if (setter != null) {
- sb.write(',setter=');
- sb.write('${setter}');
- }
- sb.write(']');
- return sb.toString();
- }
-}
-
-/// Enum representing the different kinds of destinations which a constructor
-/// invocation might refer to.
-enum ConstructorAccessKind {
- /// An invocation of a (redirecting) generative constructor.
- ///
- /// For instance
- /// class C {
- /// C();
- /// C.redirect() : this();
- /// }
- /// m1() => new C();
- /// m2() => new C.redirect();
- ///
- GENERATIVE,
-
- /// An invocation of a (redirecting) factory constructor.
- ///
- /// For instance
- /// class C {
- /// factory C() => new C._();
- /// factory C.redirect() => C._;
- /// C._();
- /// }
- /// m1() => new C();
- /// m2() => new C.redirect();
- ///
- FACTORY,
-
- /// An invocation of a (redirecting) generative constructor of an abstract
- /// class.
- ///
- /// For instance
- /// abstract class C {
- /// C();
- /// }
- /// m() => new C();
- ///
- ABSTRACT,
-
- /// An invocation of a constructor on an unresolved type.
- ///
- /// For instance
- /// m() => new Unresolved();
- ///
- UNRESOLVED_TYPE,
-
- /// An invocation of an unresolved constructor.
- ///
- /// For instance
- /// class C {
- /// C();
- /// }
- /// m() => new C.unresolved();
- ///
- UNRESOLVED_CONSTRUCTOR,
-
- /// An const invocation of an non-constant constructor.
- ///
- /// For instance
- /// class C {
- /// C();
- /// }
- /// m() => const C();
- ///
- NON_CONSTANT_CONSTRUCTOR,
-
- /// An invocation of a constructor with incompatible arguments.
- ///
- /// For instance
- /// class C {
- /// C();
- /// }
- /// m() => new C(true);
- ///
- INCOMPATIBLE,
-}
-
-/// Data structure used to classify the semantics of a constructor invocation.
-class ConstructorAccessSemantics {
- /// The kind of constructor invocation.
- final ConstructorAccessKind kind;
-
- /// The invoked constructor.
- final Element element;
-
- /// The type on which the constructor is invoked.
- final ResolutionDartType type;
-
- ConstructorAccessSemantics(this.kind, this.element, this.type);
-
- String toString() => 'ConstructorAccessSemantics($kind, $element, $type)';
-}
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
deleted file mode 100644
index 30e5f0d..0000000
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ /dev/null
@@ -1,660 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.class_hierarchy;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common_elements.dart' show CommonElements;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart'
- show
- BaseClassElementX,
- ErroneousElementX,
- MixinApplicationElementX,
- SynthesizedConstructorElementX,
- TypeVariableElementX,
- UnnamedMixinApplicationElementX;
-import '../elements/names.dart';
-import '../ordered_typeset.dart'
- show OrderedTypeSet, ResolutionOrderedTypeSetBuilder;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../util/util.dart' show Link, Setlet;
-import 'enum_creator.dart';
-import 'members.dart' show lookupInScope;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show CommonResolverVisitor, MappingVisitor;
-import 'scope.dart' show Scope, TypeDeclarationScope;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-class TypeDefinitionVisitor extends MappingVisitor<ResolutionDartType> {
- Scope scope;
- final TypeDeclarationElement enclosingElement;
- TypeDeclarationElement get element => enclosingElement;
-
- TypeDefinitionVisitor(Resolution resolution, TypeDeclarationElement element,
- ResolutionRegistry registry)
- : this.enclosingElement = element,
- scope = Scope.buildEnclosingScope(element),
- super(resolution, registry);
-
- CommonElements get commonElements => resolution.commonElements;
-
- ResolutionInterfaceType get objectType => commonElements.objectType;
-
- void resolveTypeVariableBounds(NodeList node) {
- if (node == null) return;
-
- Setlet<String> nameSet = new Setlet<String>();
- // Resolve the bounds of type variables.
- Iterator<ResolutionDartType> types = element.typeVariables.iterator;
- Link<Node> nodeLink = node.nodes;
- while (!nodeLink.isEmpty) {
- types.moveNext();
- ResolutionTypeVariableType typeVariable = types.current;
- String typeName = typeVariable.name;
- TypeVariable typeNode = nodeLink.head;
- registry.useType(typeNode, typeVariable);
- if (nameSet.contains(typeName)) {
- reporter.reportErrorMessage(
- typeNode,
- MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
- {'typeVariableName': typeName});
- }
- nameSet.add(typeName);
-
- TypeVariableElementX variableElement = typeVariable.element;
- if (typeNode.bound != null) {
- ResolutionDartType boundType =
- typeResolver.resolveNominalTypeAnnotation(
- this, typeNode.bound, const FunctionTypeParameterScope());
- variableElement.boundCache = boundType;
-
- void checkTypeVariableBound() {
- Link<TypeVariableElement> seenTypeVariables =
- const Link<TypeVariableElement>();
- seenTypeVariables = seenTypeVariables.prepend(variableElement);
- ResolutionDartType bound = boundType;
- while (bound.isTypeVariable) {
- TypeVariableElement element = bound.element;
- if (seenTypeVariables.contains(element)) {
- if (identical(element, variableElement)) {
- // Only report an error on the checked type variable to avoid
- // generating multiple errors for the same cyclicity.
- reporter.reportWarningMessage(
- typeNode.name,
- MessageKind.CYCLIC_TYPE_VARIABLE,
- {'typeVariableName': variableElement.name});
- }
- break;
- }
- seenTypeVariables = seenTypeVariables.prepend(element);
- bound = element.bound;
- }
- }
-
- addDeferredAction(element, checkTypeVariableBound);
- } else {
- variableElement.boundCache = objectType;
- }
- nodeLink = nodeLink.tail;
- }
- assert(!types.moveNext());
- }
-}
-
-/**
- * The implementation of [ResolverTask.resolveClass].
- *
- * This visitor has to be extra careful as it is building the basic
- * element information, and cannot safely look at other elements as
- * this may lead to cycles.
- *
- * This visitor can assume that the supertypes have already been
- * resolved, but it cannot call [ResolverTask.resolveClass] directly
- * or indirectly (through [ClassElement.ensureResolved]) for any other
- * types.
- */
-class ClassResolverVisitor extends TypeDefinitionVisitor {
- BaseClassElementX get element => enclosingElement;
-
- ClassResolverVisitor(Resolution resolution, ClassElement classElement,
- ResolutionRegistry registry)
- : super(resolution, classElement, registry);
-
- ResolutionDartType visitClassNode(ClassNode node) {
- if (element == null) {
- throw reporter.internalError(node, 'element is null');
- }
- if (element.resolutionState != STATE_STARTED) {
- throw reporter.internalError(
- element, 'cyclic resolution of class $element');
- }
-
- element.computeType(resolution);
- scope = new TypeDeclarationScope(scope, element);
- // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet.
- // As a side-effect, this may get us back here trying to
- // resolve this class again.
- resolveTypeVariableBounds(node.typeParameters);
-
- // Setup the supertype for the element (if there is a cycle in the
- // class hierarchy, it has already been set to Object).
- if (element.supertype == null && node.superclass != null) {
- MixinApplication superMixin = node.superclass.asMixinApplication();
- if (superMixin != null) {
- element.supertype = createMixins(element, superMixin);
- } else {
- element.supertype = resolveSupertype(element, node.superclass);
- }
- }
- // If the super type isn't specified, we provide a default. The language
- // specifies [Object] but the backend can pick a specific 'implementation'
- // of Object - the JavaScript backend chooses between Object and
- // Interceptor.
- if (element.supertype == null) {
- ClassElement superElement = registry.defaultSuperclass(element);
- // Avoid making the superclass (usually Object) extend itself.
- if (element != superElement) {
- if (superElement == null) {
- reporter.internalError(
- node, "Cannot resolve default superclass for $element.");
- } else {
- superElement.ensureResolved(resolution);
- }
- element.supertype = superElement.computeType(resolution);
- }
- }
-
- if (element.interfaces == null) {
- element.interfaces = resolveInterfaces(node.interfaces, node.superclass);
- } else {
- assert(element.hasIncompleteHierarchy, failedAt(element));
- }
- calculateAllSupertypes(element);
-
- if (!element.hasConstructor) {
- Element superMember = element.superclass.localLookup('');
- if (superMember == null) {
- MessageKind kind = MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR;
- Map arguments = {'className': element.superclass.name};
- // TODO(ahe): Why is this a compile-time error? Or if it is an error,
- // why do we bother to registerThrowNoSuchMethod below?
- reporter.reportErrorMessage(node, kind, arguments);
- superMember = new ErroneousElementX(kind, arguments, '', element);
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- } else if (!superMember.isGenerativeConstructor) {
- MessageKind kind = MessageKind.SUPER_CALL_TO_FACTORY;
- Map arguments = {'className': element.superclass.name};
- // TODO(ahe): Why is this a compile-time error? Or if it is an error,
- // why do we bother to registerThrowNoSuchMethod below?
- reporter.reportErrorMessage(node, kind, arguments);
- superMember = new ErroneousElementX(kind, arguments, '', element);
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- } else {
- ConstructorElement superConstructor = superMember;
- superConstructor.computeType(resolution);
- if (!CallStructure.NO_ARGS
- .signatureApplies(superConstructor.parameterStructure)) {
- MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT;
- reporter.reportErrorMessage(node, kind);
- superMember = new ErroneousElementX(kind, {}, '', element);
- }
- }
- FunctionElement constructor =
- new SynthesizedConstructorElementX.forDefault(superMember, element);
- if (superMember.isMalformed) {
- ErroneousElement erroneousElement = superMember;
- resolution.registerCompileTimeError(
- constructor,
- reporter.createMessage(node, erroneousElement.messageKind,
- erroneousElement.messageArguments));
- }
- element.setDefaultConstructor(constructor, reporter);
- }
- return element.computeType(resolution);
- }
-
- @override
- ResolutionDartType visitEnum(Enum node) {
- if (element == null) {
- throw reporter.internalError(node, 'element is null');
- }
- if (element.resolutionState != STATE_STARTED) {
- throw reporter.internalError(
- element, 'cyclic resolution of class $element');
- }
-
- ResolutionInterfaceType enumType = element.computeType(resolution);
- element.supertype = objectType;
- element.interfaces = const Link<ResolutionDartType>();
- calculateAllSupertypes(element);
-
- if (node.names.nodes.isEmpty) {
- reporter.reportErrorMessage(
- node, MessageKind.EMPTY_ENUM_DECLARATION, {'enumName': element.name});
- }
-
- EnumCreator creator =
- new EnumCreator(reporter, resolution.commonElements, element);
- creator.createMembers();
- return enumType;
- }
-
- /// Resolves the mixed type for [mixinNode] and checks that the mixin type
- /// is a valid, non-blacklisted interface type. The mixin type is returned.
- ResolutionDartType checkMixinType(NominalTypeAnnotation mixinNode) {
- ResolutionDartType mixinType = resolveNominalType(mixinNode);
- if (isBlackListed(mixinType)) {
- reporter.reportErrorMessage(
- mixinNode, MessageKind.CANNOT_MIXIN, {'type': mixinType});
- } else if (mixinType.isTypeVariable) {
- reporter.reportErrorMessage(mixinNode, MessageKind.CLASS_NAME_EXPECTED);
- } else if (mixinType.isMalformed) {
- reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED,
- {'className': element.name, 'malformedType': mixinType});
- } else if (mixinType.isEnumType) {
- reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_ENUM,
- {'className': element.name, 'enumType': mixinType});
- }
- return mixinType;
- }
-
- ResolutionDartType visitNamedMixinApplication(NamedMixinApplication node) {
- if (element == null) {
- throw reporter.internalError(node, 'element is null');
- }
- if (element.resolutionState != STATE_STARTED) {
- throw reporter.internalError(
- element, 'cyclic resolution of class $element');
- }
-
- element.computeType(resolution);
- scope = new TypeDeclarationScope(scope, element);
- resolveTypeVariableBounds(node.typeParameters);
-
- // Generate anonymous mixin application elements for the
- // intermediate mixin applications (excluding the last).
- createMixins(element, node, isNamed: true);
- return element.computeType(resolution);
- }
-
- ResolutionDartType createMixins(ClassElement element, MixinApplication node,
- {bool isNamed: false}) {
- ResolutionDartType supertype = resolveSupertype(element, node.superclass);
- Link<Node> link = node.mixins.nodes;
- while (!link.isEmpty) {
- if (isNamed && link.tail.isEmpty) {
- doApplyMixinTo(element, supertype, checkMixinType(link.head));
- return supertype;
- }
- supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
- link = link.tail;
- }
- return supertype;
- }
-
- ResolutionDartType applyMixin(
- ResolutionDartType supertype, ResolutionDartType mixinType, Node node) {
- String superName = supertype.name;
- String mixinName = mixinType.name;
- MixinApplicationElementX mixinApplication =
- new UnnamedMixinApplicationElementX("${superName}+${mixinName}",
- element, resolution.idGenerator.getNextFreeId(), node);
- // Create synthetic type variables for the mixin application.
- List<ResolutionDartType> typeVariables = <ResolutionDartType>[];
- int index = 0;
- for (ResolutionTypeVariableType type in element.typeVariables) {
- TypeVariableElementX typeVariableElement = new TypeVariableElementX(
- type.name, mixinApplication, index, type.element.node);
- ResolutionTypeVariableType typeVariable =
- new ResolutionTypeVariableType(typeVariableElement);
- typeVariables.add(typeVariable);
- index++;
- }
- // Setup bounds on the synthetic type variables.
- for (ResolutionTypeVariableType type in element.typeVariables) {
- ResolutionTypeVariableType typeVariable =
- typeVariables[type.element.index];
- TypeVariableElementX typeVariableElement = typeVariable.element;
- typeVariableElement.typeCache = typeVariable;
- typeVariableElement.boundCache =
- type.element.bound.subst(typeVariables, element.typeVariables);
- }
- // Setup this and raw type for the mixin application.
- mixinApplication.computeThisAndRawType(resolution, typeVariables);
- // Substitute in synthetic type variables in super and mixin types.
- supertype = supertype.subst(typeVariables, element.typeVariables);
- mixinType = mixinType.subst(typeVariables, element.typeVariables);
-
- doApplyMixinTo(mixinApplication, supertype, mixinType);
- mixinApplication.resolutionState = STATE_DONE;
- mixinApplication.supertypeLoadState = STATE_DONE;
- // Replace the synthetic type variables by the original type variables in
- // the returned type (which should be the type actually extended).
- ResolutionInterfaceType mixinThisType = mixinApplication.thisType;
- return mixinThisType.subst(
- element.typeVariables, mixinThisType.typeArguments);
- }
-
- bool isDefaultConstructor(FunctionElement constructor) {
- if (constructor.name != '') return false;
- constructor.computeType(resolution);
- return constructor.functionSignature.parameterCount == 0;
- }
-
- FunctionElement createForwardingConstructor(
- ConstructorElement target, ClassElement enclosing) {
- FunctionElement constructor =
- new SynthesizedConstructorElementX.notForDefault(
- target.name, target, enclosing);
- constructor.computeType(resolution);
- return constructor;
- }
-
- void doApplyMixinTo(MixinApplicationElementX mixinApplication,
- ResolutionDartType supertype, ResolutionDartType mixinType) {
- Node node = mixinApplication.parseNode(resolution.parsingContext);
-
- if (mixinApplication.supertype != null) {
- // [supertype] is not null if there was a cycle.
- assert(reporter.hasReportedError, failedAt(node));
- supertype = mixinApplication.supertype;
- assert(supertype.isObject, failedAt(node));
- } else {
- mixinApplication.supertype = supertype;
- }
-
- // Named mixin application may have an 'implements' clause.
- NamedMixinApplication namedMixinApplication =
- node.asNamedMixinApplication();
- Link<ResolutionDartType> interfaces = (namedMixinApplication != null)
- ? resolveInterfaces(
- namedMixinApplication.interfaces, namedMixinApplication.superclass)
- : const Link<ResolutionDartType>();
-
- // The class that is the result of a mixin application implements
- // the interface of the class that was mixed in so always prepend
- // that to the interface list.
- if (mixinApplication.interfaces == null) {
- if (mixinType.isInterfaceType) {
- // Avoid malformed types in the interfaces.
- interfaces = interfaces.prepend(mixinType);
- }
- mixinApplication.interfaces = interfaces;
- } else {
- assert(
- mixinApplication.hasIncompleteHierarchy, failedAt(mixinApplication));
- }
-
- ClassElement superclass = supertype.element;
- if (mixinType.kind != ResolutionTypeKind.INTERFACE) {
- mixinApplication.hasIncompleteHierarchy = true;
- mixinApplication.allSupertypesAndSelf = superclass.allSupertypesAndSelf;
- return;
- }
-
- assert(mixinApplication.mixinType == null);
- mixinApplication.mixinType = resolveMixinFor(mixinApplication, mixinType);
-
- // Create forwarding constructors for constructor defined in the superclass
- // because they are now hidden by the mixin application.
- superclass.forEachLocalMember((Element member) {
- if (!member.isGenerativeConstructor) return;
- FunctionElement forwarder =
- createForwardingConstructor(member, mixinApplication);
- if (Name.isPrivateName(member.name) &&
- mixinApplication.library != superclass.library) {
- // Do not create a forwarder to the super constructor, because the mixin
- // application is in a different library than the constructor in the
- // super class and it is not possible to call that constructor from the
- // library using the mixin application.
- return;
- }
- mixinApplication.addConstructor(forwarder);
- });
- calculateAllSupertypes(mixinApplication);
- }
-
- ResolutionInterfaceType resolveMixinFor(
- MixinApplicationElement mixinApplication, ResolutionDartType mixinType) {
- ClassElement mixin = mixinType.element;
- mixin.ensureResolved(resolution);
-
- // Check for cycles in the mixin chain.
- ClassElement previous = mixinApplication; // For better error messages.
- ClassElement current = mixin;
- while (current != null && current.isMixinApplication) {
- MixinApplicationElement currentMixinApplication = current;
- if (currentMixinApplication == mixinApplication) {
- reporter.reportErrorMessage(
- mixinApplication,
- MessageKind.ILLEGAL_MIXIN_CYCLE,
- {'mixinName1': current.name, 'mixinName2': previous.name});
- // We have found a cycle in the mixin chain. Return null as
- // the mixin for this application to avoid getting into
- // infinite recursion when traversing members.
- return null;
- }
- previous = current;
- current = currentMixinApplication.mixin;
- }
- return mixinType;
- }
-
- ResolutionDartType resolveNominalType(NominalTypeAnnotation node) {
- return typeResolver.resolveNominalTypeAnnotation(
- this, node, const FunctionTypeParameterScope());
- }
-
- ResolutionDartType resolveSupertype(
- ClassElement cls, NominalTypeAnnotation superclass) {
- ResolutionDartType supertype = resolveNominalType(superclass);
- if (supertype != null) {
- if (supertype.isMalformed) {
- reporter.reportErrorMessage(
- superclass,
- MessageKind.CANNOT_EXTEND_MALFORMED,
- {'className': element.name, 'malformedType': supertype});
- return objectType;
- } else if (supertype.isEnumType) {
- reporter.reportErrorMessage(superclass, MessageKind.CANNOT_EXTEND_ENUM,
- {'className': element.name, 'enumType': supertype});
- return objectType;
- } else if (!supertype.isInterfaceType) {
- reporter.reportErrorMessage(
- superclass.typeName, MessageKind.CLASS_NAME_EXPECTED);
- return objectType;
- } else if (isBlackListed(supertype)) {
- reporter.reportErrorMessage(
- superclass, MessageKind.CANNOT_EXTEND, {'type': supertype});
- return objectType;
- }
- }
- return supertype;
- }
-
- Link<ResolutionDartType> resolveInterfaces(
- NodeList interfaces, Node superclass) {
- Link<ResolutionDartType> result = const Link<ResolutionDartType>();
- if (interfaces == null) return result;
- for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
- ResolutionDartType interfaceType = resolveNominalType(link.head);
- if (interfaceType != null) {
- if (interfaceType.isMalformed) {
- reporter.reportErrorMessage(
- link.head,
- MessageKind.CANNOT_IMPLEMENT_MALFORMED,
- {'className': element.name, 'malformedType': interfaceType});
- } else if (interfaceType.isEnumType) {
- reporter.reportErrorMessage(
- link.head,
- MessageKind.CANNOT_IMPLEMENT_ENUM,
- {'className': element.name, 'enumType': interfaceType});
- } else if (!interfaceType.isInterfaceType) {
- // TODO(johnniwinther): Handle dynamic.
- NominalTypeAnnotation typeAnnotation = link.head;
- reporter.reportErrorMessage(
- typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
- } else {
- if (interfaceType == element.supertype) {
- reporter.reportErrorMessage(
- superclass,
- MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
- {'type': interfaceType});
- reporter.reportErrorMessage(
- link.head,
- MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
- {'type': interfaceType});
- }
- if (result.contains(interfaceType)) {
- reporter.reportErrorMessage(link.head,
- MessageKind.DUPLICATE_IMPLEMENTS, {'type': interfaceType});
- }
- result = result.prepend(interfaceType);
- if (isBlackListed(interfaceType)) {
- reporter.reportErrorMessage(link.head, MessageKind.CANNOT_IMPLEMENT,
- {'type': interfaceType});
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Compute the list of all supertypes.
- *
- * The elements of this list are ordered as follows: first the supertype that
- * the class extends, then the implemented interfaces, and then the supertypes
- * of these. The class [Object] appears only once, at the end of the list.
- *
- * For example, for a class `class C extends S implements I1, I2`, we compute
- * supertypes(C) = [S, I1, I2] ++ supertypes(S) ++ supertypes(I1)
- * ++ supertypes(I2),
- * where ++ stands for list concatenation.
- *
- * This order makes sure that if a class implements an interface twice with
- * different type arguments, the type used in the most specific class comes
- * first.
- */
- void calculateAllSupertypes(BaseClassElementX cls) {
- if (cls.allSupertypesAndSelf != null) return;
- final ResolutionInterfaceType supertype = cls.supertype;
- if (supertype != null) {
- cls.allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(
- cls, commonElements.objectType,
- reporter: reporter)
- .createOrderedTypeSet(supertype, cls.interfaces);
- } else {
- assert(cls == resolution.commonElements.objectClass);
- cls.allSupertypesAndSelf =
- new OrderedTypeSet.singleton(cls.computeType(resolution));
- }
- }
-
- isBlackListed(ResolutionDartType type) {
- LibraryElement lib = element.library;
- return !identical(lib, resolution.commonElements.coreLibrary) &&
- !resolution.target.isTargetSpecificLibrary(lib) &&
- (type.isDynamic ||
- type == commonElements.boolType ||
- type == commonElements.numType ||
- type == commonElements.intType ||
- type == commonElements.doubleType ||
- type == commonElements.stringType ||
- type == commonElements.nullType);
- }
-}
-
-class ClassSupertypeResolver extends CommonResolverVisitor {
- Scope context;
- ClassElement classElement;
-
- ClassSupertypeResolver(Resolution resolution, ClassElement cls)
- : context = Scope.buildEnclosingScope(cls),
- this.classElement = cls,
- super(resolution);
-
- CommonElements get commonElements => resolution.commonElements;
-
- void loadSupertype(ClassElement element, Node from) {
- if (!element.isResolved) {
- resolution.resolver.loadSupertypes(element, from);
- element.ensureResolved(resolution);
- }
- }
-
- void visitNodeList(NodeList node) {
- if (node != null) {
- for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
- link.head.accept(this);
- }
- }
- }
-
- void visitClassNode(ClassNode node) {
- if (node.superclass == null) {
- if (classElement != commonElements.objectClass) {
- loadSupertype(commonElements.objectClass, node);
- }
- } else {
- node.superclass.accept(this);
- }
- visitNodeList(node.interfaces);
- }
-
- void visitEnum(Enum node) {
- loadSupertype(commonElements.objectClass, node);
- }
-
- void visitMixinApplication(MixinApplication node) {
- node.superclass.accept(this);
- visitNodeList(node.mixins);
- }
-
- void visitNamedMixinApplication(NamedMixinApplication node) {
- node.superclass.accept(this);
- visitNodeList(node.mixins);
- visitNodeList(node.interfaces);
- }
-
- void visitNominalTypeAnnotation(NominalTypeAnnotation node) {
- node.typeName.accept(this);
- }
-
- void visitIdentifier(Identifier node) {
- Element element = lookupInScope(reporter, node, context, node.source);
- if (element != null && element.isClass) {
- loadSupertype(element, node);
- }
- }
-
- void visitSend(Send node) {
- Identifier prefix = node.receiver.asIdentifier();
- if (prefix == null) {
- reporter.reportErrorMessage(
- node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
- return;
- }
- Element element = lookupInScope(reporter, prefix, context, prefix.source);
- if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
- reporter.reportErrorMessage(
- node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
- return;
- }
- PrefixElement prefixElement = element;
- Identifier selector = node.selector.asIdentifier();
- var e = prefixElement.lookupLocalMember(selector.source);
- if (e == null || !e.impliesType) {
- reporter.reportErrorMessage(node.selector,
- MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector});
- return;
- }
- loadSupertype(e, node);
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
deleted file mode 100644
index c3063f3..0000000
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ /dev/null
@@ -1,974 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.compute_members;
-
-import '../common.dart';
-import '../common/names.dart' show Identifiers, Names;
-import '../common/resolution.dart' show Resolution;
-import '../elements/elements.dart'
- show
- ClassElement,
- Element,
- LibraryElement,
- Member,
- MemberElement,
- MemberSignature,
- MixinApplicationElement;
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../elements/names.dart';
-import '../util/util.dart';
-
-part 'member_impl.dart';
-
-abstract class MembersCreator {
- final ClassElement cls;
- final Resolution resolution;
-
- final Iterable<String> computedMemberNames;
- final Map<Name, Member> classMembers;
-
- Map<dynamic /* Member | Element */, Set<MessageKind>> reportedMessages =
- new Map<dynamic, Set<MessageKind>>();
-
- MembersCreator(
- this.resolution, this.cls, this.computedMemberNames, this.classMembers) {
- assert(cls.isDeclaration,
- failedAt(cls, "Members may only be computed on declarations."));
- }
-
- DiagnosticReporter get reporter => resolution.reporter;
-
- void reportMessage(var marker, MessageKind kind, report()) {
- Set<MessageKind> messages =
- reportedMessages.putIfAbsent(marker, () => new Set<MessageKind>());
- if (messages.add(kind)) {
- report();
- }
- }
-
- bool shouldSkipMember(MemberSignature member) {
- return member == null || shouldSkipName(member.name.text);
- }
-
- bool shouldSkipName(String name) {
- return computedMemberNames != null &&
- // 'call' is implicitly contained in [computedMemberNames].
- (name == Identifiers.call || computedMemberNames.contains(name));
- }
-
- /// Compute all members of [cls] with the given names.
- void computeMembersByName(String name, Setlet<Name> names) {
- computeMembers(name, names);
- }
-
- /// Compute all members of [cls] and checked that [cls] implements its
- /// interface unless it is abstract or declares a `noSuchMethod` method.
- void computeAllMembers() {
- computeMembers(null, null);
- if (!cls.isAbstract) {
- Member member = classMembers[Names.noSuchMethod_];
- if (member != null &&
- !resolution.target.isDefaultNoSuchMethod(member.element)) {
- return;
- }
- // Check for unimplemented members on concrete classes that neither have
- // a `@proxy` annotation nor declare a `noSuchMethod` method.
- checkInterfaceImplementation();
- }
- }
-
- /// Compute declared and inherited members of [cls] and return a map of the
- /// declared members.
- ///
- /// If [name] and [names] are not null, the computation is restricted to
- /// members with these names.
- Map<Name, Member> computeMembers(String name, Setlet<Name> names);
-
- /// Compute the members of the super type(s) of [cls] and store them in
- /// [classMembers].
- ///
- /// If [name] and [names] are not null, the computation is restricted to
- /// members with these names.
- void computeSuperMembers(String name, Setlet<Name> names);
-
- /// Compute the members of the super class of [cls] and store them in
- /// [classMembers].
- ///
- /// If [name] and [names] are not null, the computation is restricted to
- /// members with these names.
- void computeSuperClassMembers(String name, Setlet<Name> names) {
- ResolutionInterfaceType supertype = cls.supertype;
- if (supertype == null) return;
- ClassElement superclass = supertype.element;
-
- // Inherit class and interface members from superclass.
- void inheritClassMember(Member _member) {
- DeclaredMember member = _member;
- if (shouldSkipMember(member)) return;
- if (!member.isStatic) {
- DeclaredMember inherited = member.inheritFrom(supertype);
- classMembers[member.name] = inherited;
- }
- }
-
- if (names != null) {
- _computeClassMember(resolution, superclass, name, names);
- for (Name memberName in names) {
- inheritClassMember(superclass.lookupClassMember(memberName));
- }
- } else {
- computeAllClassMembers(resolution, superclass);
- superclass.forEachClassMember(inheritClassMember);
- }
- }
-
- /// Compute the members declared or directly mixed in [cls].
- ///
- /// If [name] and [names] are not null, the computation is restricted to
- /// members with these names.
- Map<Name, Member> computeClassMembers(String nameText, Setlet<Name> names) {
- Map<Name, Member> declaredMembers = new Map<Name, Member>();
-
- if (cls.isMixinApplication) {
- MixinApplicationElement mixinApplication = cls;
- if (mixinApplication.mixin != null) {
- // Only mix in class members when the mixin type is not malformed.
-
- void inheritMixinMember(Member _member) {
- DeclaredMember member = _member;
- if (shouldSkipMember(member)) return;
- Name name = member.name;
- if (!member.isAbstract && !member.isStatic) {
- // Abstract and static members are not mixed in.
- DeclaredMember mixedInMember =
- member.inheritFrom(mixinApplication.mixinType);
- DeclaredMember inherited = classMembers[name];
- classMembers[name] = mixedInMember;
- checkValidOverride(mixedInMember, inherited);
- }
- }
-
- if (names != null) {
- _computeClassMember(
- resolution, mixinApplication.mixin, nameText, names);
- for (Name memberName in names) {
- inheritMixinMember(
- mixinApplication.mixin.lookupClassMember(memberName));
- }
- } else {
- computeAllClassMembers(resolution, mixinApplication.mixin);
- mixinApplication.mixin.forEachClassMember(inheritMixinMember);
- }
- }
- } else {
- LibraryElement library = cls.library;
- ResolutionInterfaceType thisType = cls.thisType;
-
- void createMember(Element _element) {
- MemberElement element = _element;
- if (element.isConstructor) return;
- String elementName = element.name;
- if (shouldSkipName(elementName)) return;
- if (nameText != null && elementName != nameText) return;
-
- void addDeclaredMember(Name name, ResolutionDartType type,
- ResolutionFunctionType functionType) {
- DeclaredMember inherited = classMembers[name];
- DeclaredMember declared;
- if (element.isAbstract) {
- declared = new DeclaredAbstractMember(
- name, element, thisType, type, functionType, inherited);
- } else {
- declared =
- new DeclaredMember(name, element, thisType, type, functionType);
- }
- declaredMembers[name] = declared;
- classMembers[name] = declared;
- checkValidOverride(declared, inherited);
- }
-
- Name name = new Name(element.name, library);
- if (element.isField) {
- ResolutionDartType type = element.computeType(resolution);
- addDeclaredMember(
- name, type, new ResolutionFunctionType.synthesized(type));
- if (!element.isConst && !element.isFinal) {
- addDeclaredMember(
- name.setter,
- type,
- new ResolutionFunctionType.synthesized(
- const ResolutionVoidType(), <ResolutionDartType>[type]));
- }
- } else if (element.isGetter) {
- ResolutionFunctionType functionType = element.computeType(resolution);
- ResolutionDartType type = functionType.returnType;
- addDeclaredMember(name, type, functionType);
- } else if (element.isSetter) {
- ResolutionFunctionType functionType = element.computeType(resolution);
- ResolutionDartType type;
- if (!functionType.parameterTypes.isEmpty) {
- type = functionType.parameterTypes.first;
- } else {
- type = const ResolutionDynamicType();
- }
- name = name.setter;
- addDeclaredMember(name, type, functionType);
- } else {
- assert(element.isFunction, failedAt(element));
- ResolutionFunctionType type = element.computeType(resolution);
- addDeclaredMember(name, type, type);
- }
- }
-
- cls.forEachLocalMember(createMember);
- if (cls.isPatched) {
- cls.implementation.forEachLocalMember((Element element) {
- if (element.isDeclaration) {
- createMember(element);
- }
- });
- }
- }
-
- return declaredMembers;
- }
-
- /// Checks that [classMember] is a valid implementation for [interfaceMember].
- void checkInterfaceMember(
- Name name, MemberSignature interfaceMember, Member classMember) {
- if (classMember != null) {
- // TODO(johnniwinther): Check that the class member is a valid override
- // of the interface member.
- return;
- }
- if (interfaceMember is DeclaredMember &&
- interfaceMember.declarer.element == cls) {
- // Abstract method declared in [cls].
- MessageKind kind = MessageKind.ABSTRACT_METHOD;
- if (interfaceMember.isSetter) {
- kind = MessageKind.ABSTRACT_SETTER;
- } else if (interfaceMember.isGetter) {
- kind = MessageKind.ABSTRACT_GETTER;
- }
- reportMessage(interfaceMember.element, MessageKind.ABSTRACT_METHOD, () {
- reporter.reportWarningMessage(interfaceMember.element, kind,
- {'class': cls.name, 'name': name.text});
- });
- } else {
- reportWarning(MessageKind singleKind, MessageKind multipleKind,
- MessageKind explicitlyDeclaredKind,
- [MessageKind implicitlyDeclaredKind]) {
- Member inherited = interfaceMember.declarations.first;
- reportMessage(interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () {
- DiagnosticMessage warning = reporter.createMessage(
- cls,
- interfaceMember.declarations.length == 1
- ? singleKind
- : multipleKind,
- {
- 'class': cls.name,
- 'name': name.text,
- 'method': interfaceMember,
- 'declarer': inherited.declarer
- });
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- for (Member inherited in interfaceMember.declarations) {
- infos.add(reporter.createMessage(
- inherited.element,
- inherited.isDeclaredByField
- ? implicitlyDeclaredKind
- : explicitlyDeclaredKind,
- {'class': inherited.declarer.name, 'name': name.text}));
- }
- reporter.reportWarning(warning, infos);
- });
- }
-
- if (interfaceMember.isSetter) {
- reportWarning(
- MessageKind.UNIMPLEMENTED_SETTER_ONE,
- MessageKind.UNIMPLEMENTED_SETTER,
- MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER);
- } else if (interfaceMember.isGetter) {
- reportWarning(
- MessageKind.UNIMPLEMENTED_GETTER_ONE,
- MessageKind.UNIMPLEMENTED_GETTER,
- MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER);
- } else if (interfaceMember.isMethod) {
- reportWarning(
- MessageKind.UNIMPLEMENTED_METHOD_ONE,
- MessageKind.UNIMPLEMENTED_METHOD,
- MessageKind.UNIMPLEMENTED_METHOD_CONT);
- }
- }
- // TODO(johnniwinther): If [cls] is not abstract, check that for all
- // interface members, there is a class member whose type is a subtype of
- // the interface member.
- }
-
- /// Checks that [cls], if it implements Function, has defined call().
- void checkImplementsFunctionWithCall() {
- assert(!cls.isAbstract);
-
- ClassElement functionClass = resolution.commonElements.functionClass;
- functionClass.ensureResolved(resolution);
- if (cls.asInstanceOf(functionClass) == null) return;
- if (cls.lookupMember(Identifiers.call) != null) return;
- // TODO(johnniwinther): Make separate methods for backend exceptions.
- // Avoid warnings on backend implementation classes for closures.
- if (resolution.target.isTargetSpecificLibrary(cls.library)) return;
-
- reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () {
- reporter.reportWarningMessage(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, {
- 'class': cls.name,
- 'name': Identifiers.call,
- 'method': Identifiers.call,
- 'declarer': functionClass.name
- });
- });
- }
-
- /// Checks that a class member exists for every interface member.
- void checkInterfaceImplementation();
-
- /// Check that [declared] is a valid override of [superMember].
- void checkValidOverride(Member declared, MemberSignature superMember) {
- if (superMember == null) {
- // No override.
- if (!declared.isStatic) {
- ClassElement superclass = cls.superclass;
- while (superclass != null) {
- Member superMember = superclass.lookupClassMember(declared.name);
- if (superMember != null && superMember.isStatic) {
- reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME,
- () {
- reporter.reportWarning(
- reporter.createMessage(
- declared.element, MessageKind.INSTANCE_STATIC_SAME_NAME, {
- 'memberName': declared.name,
- 'className': superclass.name
- }),
- <DiagnosticMessage>[
- reporter.createMessage(superMember.element,
- MessageKind.INSTANCE_STATIC_SAME_NAME_CONT),
- ]);
- });
- break;
- }
- superclass = superclass.superclass;
- }
- }
- } else {
- assert(declared.name == superMember.name);
-
- if (declared.isStatic) {
- for (Member inherited in superMember.declarations) {
- if (cls == inherited.declarer.element) {
- // An error should already have been reported.
- assert(resolution.reporter.hasReportedError,
- failedAt(declared.element));
- continue;
- }
-
- reportMessage(inherited.element, MessageKind.NO_STATIC_OVERRIDE, () {
- reportErrorWithContext(
- declared.element,
- MessageKind.NO_STATIC_OVERRIDE,
- inherited.element,
- MessageKind.NO_STATIC_OVERRIDE_CONT);
- });
- }
- }
-
- ResolutionDartType declaredType = declared.functionType;
- for (Member inherited in superMember.declarations) {
- if (inherited.element == declared.element) {
- // TODO(ahe): For some reason, "call" elements are repeated in
- // superMember.declarations. Investigate why.
- } else if (cls == inherited.declarer.element) {
- // An error should already have been reported.
- assert(
- resolution.reporter.hasReportedError,
- failedAt(
- declared.element,
- "Member $inherited inherited from its "
- "declaring class: ${cls}."));
- continue;
- }
-
- void reportError(MessageKind errorKind, MessageKind infoKind) {
- reportMessage(inherited.element, MessageKind.INVALID_OVERRIDE_METHOD,
- () {
- reporter.reportError(
- reporter.createMessage(declared.element, errorKind, {
- 'name': declared.name.text,
- 'class': cls.thisType,
- 'inheritedClass': inherited.declarer
- }),
- <DiagnosticMessage>[
- reporter.createMessage(inherited.element, infoKind, {
- 'name': declared.name.text,
- 'class': inherited.declarer
- }),
- ]);
- });
- }
-
- if (declared.isDeclaredByField && inherited.isMethod) {
- reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT);
- } else if (declared.isMethod && inherited.isDeclaredByField) {
- reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
- MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT);
- } else if (declared.isGetter && inherited.isMethod) {
- reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT);
- } else if (declared.isMethod && inherited.isGetter) {
- reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
- MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT);
- } else {
- ResolutionDartType inheritedType = inherited.functionType;
- if (!resolution.types.isSubtype(declaredType, inheritedType)) {
- void reportWarning(
- var marker, MessageKind warningKind, MessageKind infoKind) {
- reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () {
- reporter.reportWarning(
- reporter.createMessage(declared.element, warningKind, {
- 'declaredType': declared.type,
- 'name': declared.name.text,
- 'class': cls.thisType,
- 'inheritedType': inherited.type,
- 'inheritedClass': inherited.declarer
- }),
- <DiagnosticMessage>[
- reporter.createMessage(inherited.element, infoKind, {
- 'name': declared.name.text,
- 'class': inherited.declarer
- }),
- ]);
- });
- }
-
- if (declared.isDeclaredByField) {
- if (inherited.isDeclaredByField) {
- reportWarning(
- inherited.element,
- MessageKind.INVALID_OVERRIDE_FIELD,
- MessageKind.INVALID_OVERRIDDEN_FIELD);
- } else if (inherited.isGetter) {
- reportWarning(
- inherited,
- MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
- MessageKind.INVALID_OVERRIDDEN_GETTER);
- } else if (inherited.isSetter) {
- reportWarning(
- inherited,
- MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
- MessageKind.INVALID_OVERRIDDEN_SETTER);
- }
- } else if (declared.isGetter) {
- if (inherited.isDeclaredByField) {
- reportWarning(
- inherited,
- MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
- MessageKind.INVALID_OVERRIDDEN_FIELD);
- } else {
- reportWarning(inherited, MessageKind.INVALID_OVERRIDE_GETTER,
- MessageKind.INVALID_OVERRIDDEN_GETTER);
- }
- } else if (declared.isSetter) {
- if (inherited.isDeclaredByField) {
- reportWarning(
- inherited,
- MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
- MessageKind.INVALID_OVERRIDDEN_FIELD);
- } else {
- reportWarning(inherited, MessageKind.INVALID_OVERRIDE_SETTER,
- MessageKind.INVALID_OVERRIDDEN_SETTER);
- }
- } else {
- reportWarning(inherited, MessageKind.INVALID_OVERRIDE_METHOD,
- MessageKind.INVALID_OVERRIDDEN_METHOD);
- }
- }
- }
- }
- }
- }
-
- void reportErrorWithContext(
- Element errorneousElement,
- MessageKind errorMessage,
- Element contextElement,
- MessageKind contextMessage) {
- reporter.reportError(
- reporter.createMessage(errorneousElement, errorMessage, {
- 'memberName': contextElement.name,
- 'className': contextElement.enclosingClass.name
- }),
- <DiagnosticMessage>[
- reporter.createMessage(contextElement, contextMessage),
- ]);
- }
-
- /// Compute all class and interface names by the [name] in [cls].
- static void computeClassMembersByName(
- Resolution resolution, ClassMemberMixin cls, String name) {
- if (cls.isMemberComputed(name)) return;
- LibraryElement library = cls.library;
- _computeClassMember(
- resolution,
- cls,
- name,
- new Setlet<Name>()
- ..add(new Name(name, library))
- ..add(new Name(name, library, isSetter: true)));
- }
-
- static void _computeClassMember(Resolution resolution, ClassMemberMixin cls,
- String name, Setlet<Name> names) {
- cls.computeClassMember(resolution, name, names);
- }
-
- /// Compute all class and interface names in [cls].
- static void computeAllClassMembers(
- Resolution resolution, ClassMemberMixin cls) {
- cls.computeAllClassMembers(resolution);
- }
-}
-
-/// Class member creator for classes where the interface members are known to
-/// be a subset of the class members.
-class ClassMembersCreator extends MembersCreator {
- ClassMembersCreator(Resolution resolution, ClassElement cls,
- Iterable<String> computedMemberNames, Map<Name, Member> classMembers)
- : super(resolution, cls, computedMemberNames, classMembers);
-
- Map<Name, Member> computeMembers(String name, Setlet<Name> names) {
- computeSuperMembers(name, names);
- return computeClassMembers(name, names);
- }
-
- void computeSuperMembers(String name, Setlet<Name> names) {
- computeSuperClassMembers(name, names);
- }
-
- void checkInterfaceImplementation() {
- LibraryElement library = cls.library;
- classMembers.forEach((Name name, Member classMember) {
- if (!name.isAccessibleFrom(library)) return;
- checkInterfaceMember(name, classMember, classMember.implementation);
- });
- }
-}
-
-/// Class Member creator for classes where the interface members might be
-/// different from the class members.
-class InterfaceMembersCreator extends MembersCreator {
- final Map<Name, MemberSignature> interfaceMembers;
-
- InterfaceMembersCreator(
- Resolution resolution,
- ClassElement cls,
- Iterable<String> computedMemberNames,
- Map<Name, Member> classMembers,
- Map<Name, MemberSignature> this.interfaceMembers)
- : super(resolution, cls, computedMemberNames, classMembers);
-
- Map<Name, Member> computeMembers(String name, Setlet<Name> names) {
- Map<Name, Setlet<Member>> inheritedInterfaceMembers =
- computeSuperMembers(name, names);
- Map<Name, Member> declaredMembers = computeClassMembers(name, names);
- computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers);
- return declaredMembers;
- }
-
- /// Compute the members of the super type(s) of [cls]. The class members are
- /// stored if the [classMembers] map and the inherited interface members are
- /// returned.
- ///
- /// If [name] and [names] are not null, the computation is restricted to
- /// members with these names.
- Map<Name, Setlet<Member>> computeSuperMembers(
- String name, Setlet<Name> names) {
- computeSuperClassMembers(name, names);
- return computeSuperInterfaceMembers(name, names);
- }
-
- Map<Name, Setlet<Member>> computeSuperInterfaceMembers(
- String name, Setlet<Name> names) {
- ResolutionInterfaceType supertype = cls.supertype;
- assert(supertype != null,
- failedAt(cls, "Interface members computed for $cls."));
- ClassElement superclass = supertype.element;
-
- Map<Name, Setlet<Member>> inheritedInterfaceMembers =
- new Map<Name, Setlet<Member>>();
-
- void inheritInterfaceMember(
- ResolutionInterfaceType supertype, MemberSignature member) {
- if (shouldSkipMember(member)) return;
- Setlet<Member> members = inheritedInterfaceMembers.putIfAbsent(
- member.name, () => new Setlet<Member>());
- for (DeclaredMember declaredMember in member.declarations) {
- members.add(declaredMember.inheritFrom(supertype));
- }
- }
-
- void inheritInterfaceMembers(ResolutionInterfaceType supertype) {
- supertype.element.forEachInterfaceMember((MemberSignature member) {
- inheritInterfaceMember(supertype, member);
- });
- }
-
- if (names != null) {
- for (Name memberName in names) {
- inheritInterfaceMember(
- supertype, superclass.lookupInterfaceMember(memberName));
- }
- } else {
- inheritInterfaceMembers(supertype);
- }
-
- // Inherit interface members from superinterfaces.
- for (Link<ResolutionDartType> link = cls.interfaces;
- !link.isEmpty;
- link = link.tail) {
- ResolutionInterfaceType superinterface = link.head;
- if (names != null) {
- MembersCreator._computeClassMember(
- resolution, superinterface.element, name, names);
- for (Name memberName in names) {
- inheritInterfaceMember(superinterface,
- superinterface.element.lookupInterfaceMember(memberName));
- }
- } else {
- MembersCreator.computeAllClassMembers(
- resolution, superinterface.element);
- inheritInterfaceMembers(superinterface);
- }
- }
-
- return inheritedInterfaceMembers;
- }
-
- /// Checks that a class member exists for every interface member.
- void checkInterfaceImplementation() {
- LibraryElement library = cls.library;
- checkImplementsFunctionWithCall();
- interfaceMembers.forEach((Name name, MemberSignature interfaceMember) {
- if (!name.isAccessibleFrom(library)) return;
- Member classMember = classMembers[name];
- if (classMember != null) classMember = classMember.implementation;
- checkInterfaceMember(name, interfaceMember, classMember);
- });
- }
-
- /// Compute the interface members of [cls] given the set of inherited
- /// interface members [inheritedInterfaceMembers] and declared members
- /// [declaredMembers]. The computed members are stored in [interfaceMembers].
- void computeInterfaceMembers(
- Map<Name, Setlet<Member>> inheritedInterfaceMembers,
- Map<Name, Member> declaredMembers) {
- ResolutionInterfaceType thisType = cls.thisType;
- // Compute the interface members by overriding the inherited members with
- // a declared member or by computing a single, possibly synthesized,
- // inherited member.
- inheritedInterfaceMembers
- .forEach((Name name, Setlet<Member> inheritedMembers) {
- Member declared = declaredMembers[name];
- if (declared != null) {
- // Check that [declaredMember] is a valid override
- for (Member inherited in inheritedMembers) {
- checkValidOverride(declared, inherited);
- }
- if (!declared.isStatic) {
- interfaceMembers[name] = declared;
- }
- } else if (inheritedMembers.length == 1) {
- interfaceMembers[name] = inheritedMembers.single;
- } else {
- bool someAreGetters = false;
- bool allAreGetters = true;
- Map<ResolutionDartType, Setlet<Member>> subtypesOfAllInherited =
- new Map<ResolutionDartType, Setlet<Member>>();
- outer:
- for (Member inherited in inheritedMembers) {
- if (inherited.isGetter) {
- someAreGetters = true;
- if (!allAreGetters) break outer;
- } else {
- allAreGetters = false;
- if (someAreGetters) break outer;
- }
- for (MemberSignature other in inheritedMembers) {
- if (!resolution.types
- .isSubtype(inherited.functionType, other.functionType)) {
- continue outer;
- }
- }
- subtypesOfAllInherited
- .putIfAbsent(inherited.functionType, () => new Setlet<Member>())
- .add(inherited);
- }
- if (someAreGetters && !allAreGetters) {
- DiagnosticMessage warning = reporter.createMessage(
- cls,
- MessageKind.INHERIT_GETTER_AND_METHOD,
- {'class': thisType, 'name': name.text});
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- for (Member inherited in inheritedMembers) {
- MessageKind kind;
- if (inherited.isMethod) {
- kind = MessageKind.INHERITED_METHOD;
- } else {
- assert(
- inherited.isGetter,
- failedAt(cls,
- 'Conflicting member is neither a method nor a getter.'));
- if (inherited.isDeclaredByField) {
- kind = MessageKind.INHERITED_IMPLICIT_GETTER;
- } else {
- kind = MessageKind.INHERITED_EXPLICIT_GETTER;
- }
- }
- infos.add(reporter.createMessage(inherited.element, kind,
- {'class': inherited.declarer, 'name': name.text}));
- }
- reporter.reportWarning(warning, infos);
- interfaceMembers[name] = new ErroneousMember(inheritedMembers);
- } else if (subtypesOfAllInherited.length == 1) {
- // All signatures have the same type.
- Setlet<Member> members = subtypesOfAllInherited.values.first;
- MemberSignature inherited = members.first;
- if (members.length != 1) {
- // Multiple signatures with the same type => return a
- // synthesized signature.
- inherited = new SyntheticMember(
- members, inherited.type, inherited.functionType);
- }
- interfaceMembers[name] = inherited;
- } else {
- _inheritedSynthesizedMember(name, inheritedMembers);
- }
- }
- });
-
- // Add the non-overriding instance methods to the interface members.
- declaredMembers.forEach((Name name, Member member) {
- if (!member.isStatic) {
- interfaceMembers.putIfAbsent(name, () => member);
- }
- });
- }
-
- /// Create and inherit a synthesized member for [inheritedMembers].
- void _inheritedSynthesizedMember(Name name, Setlet<Member> inheritedMembers) {
- // Multiple signatures with different types => create the synthesized
- // version.
- int minRequiredParameters;
- int maxPositionalParameters;
- Set<String> names = new Set<String>();
- for (MemberSignature member in inheritedMembers) {
- int requiredParameters = 0;
- int optionalParameters = 0;
- if (member.isSetter) {
- requiredParameters = 1;
- }
- if (member.type.isFunctionType) {
- ResolutionFunctionType type = member.type;
- type.namedParameters.forEach((String name) => names.add(name));
- requiredParameters = type.parameterTypes.length;
- optionalParameters = type.optionalParameterTypes.length;
- }
- int positionalParameters = requiredParameters + optionalParameters;
- if (minRequiredParameters == null ||
- minRequiredParameters > requiredParameters) {
- minRequiredParameters = requiredParameters;
- }
- if (maxPositionalParameters == null ||
- maxPositionalParameters < positionalParameters) {
- maxPositionalParameters = positionalParameters;
- }
- }
- int optionalParameters = maxPositionalParameters - minRequiredParameters;
- // TODO(johnniwinther): Support function types with both optional
- // and named parameters?
- if (optionalParameters == 0 || names.isEmpty) {
- ResolutionDartType dynamic = const ResolutionDynamicType();
- List<ResolutionDartType> requiredParameterTypes =
- new List.filled(minRequiredParameters, dynamic);
- List<ResolutionDartType> optionalParameterTypes =
- new List.filled(optionalParameters, dynamic);
- List<String> namedParameters = names.toList()
- ..sort((a, b) => a.compareTo(b));
- List<ResolutionDartType> namedParameterTypes =
- new List.filled(namedParameters.length, dynamic);
- ResolutionFunctionType memberType =
- new ResolutionFunctionType.synthesized(
- const ResolutionDynamicType(),
- requiredParameterTypes,
- optionalParameterTypes,
- namedParameters,
- namedParameterTypes);
- ResolutionDartType type = memberType;
- if (inheritedMembers.first.isGetter || inheritedMembers.first.isSetter) {
- type = const ResolutionDynamicType();
- }
- interfaceMembers[name] =
- new SyntheticMember(inheritedMembers, type, memberType);
- }
- }
-}
-
-abstract class ClassMemberMixin implements ClassElement {
- /// When [classMembers] and [interfaceMembers] have not been fully computed
- /// [computedMembersNames] holds the names for which members have already been
- /// computed.
- ///
- /// If [computedMemberNames], [classMembers] and [interfaceMembers] are `null`
- /// no members have been computed, if only [computedMemberNames] is `null` all
- /// members have been computed. A non-null [computedMemberNames] implicitly
- /// includes `call`.
- Iterable<String> computedMemberNames;
-
- bool _interfaceMembersAreClassMembers;
-
- /// Compute value of the [_interfaceMembersAreClassMembers] for this class
- /// and its superclasses.
- void _computeInterfaceMembersAreClassMembers(Resolution resolution) {
- if (_interfaceMembersAreClassMembers == null) {
- ensureResolved(resolution);
- ClassMemberMixin superclass = this.superclass;
- if (superclass != null) {
- superclass._computeInterfaceMembersAreClassMembers(resolution);
- }
- if ((superclass != null &&
- (!superclass.interfaceMembersAreClassMembers ||
- superclass.isMixinApplication)) ||
- !interfaces.isEmpty) {
- _interfaceMembersAreClassMembers = false;
- } else {
- _interfaceMembersAreClassMembers = true;
- }
- }
- }
-
- /// If `true` interface members are the non-static class member.
- bool get interfaceMembersAreClassMembers => _interfaceMembersAreClassMembers;
-
- Map<Name, Member> classMembers;
- Map<Name, MemberSignature> interfaceMembers;
-
- /// Creates the necessary maps and [MembersCreator] for compute members of
- /// this class.
- MembersCreator _prepareCreator(Resolution resolution) {
- if (classMembers == null) {
- _computeInterfaceMembersAreClassMembers(resolution);
- classMembers = new Map<Name, Member>();
- if (!interfaceMembersAreClassMembers) {
- interfaceMembers = new Map<Name, MemberSignature>();
- }
- }
- return interfaceMembersAreClassMembers
- ? new ClassMembersCreator(
- resolution, this, computedMemberNames, classMembers)
- : new InterfaceMembersCreator(resolution, this, computedMemberNames,
- classMembers, interfaceMembers);
- }
-
- static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[];
-
- /// Compute the members by the name [name] for this class. [names] collects
- /// the set of possible variations of [name], including getter, setter and
- /// and private names.
- void computeClassMember(
- Resolution resolution, String name, Setlet<Name> names) {
- // TODO(johnniwinther): Should we assert that the class has been resolved
- // instead?
- ensureResolved(resolution);
- if (isMemberComputed(name)) return;
- if (Name.isPrivateName(name)) {
- names
- ..add(new Name(name, library))
- ..add(new Name(name, library, isSetter: true));
- }
- MembersCreator creator = _prepareCreator(resolution);
- creator.computeMembersByName(name, names);
- if (computedMemberNames == null) {
- computedMemberNames = _EMPTY_MEMBERS_NAMES;
- }
- if (name != Identifiers.call) {
- Setlet<String> set;
- if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) {
- computedMemberNames = set = new Setlet<String>();
- } else {
- set = computedMemberNames;
- }
- set.add(name);
- }
- }
-
- void computeAllClassMembers(Resolution resolution) {
- // TODO(johnniwinther): Should we assert that the class has been resolved
- // instead?
- ensureResolved(resolution);
- if (areAllMembersComputed()) return;
- MembersCreator creator = _prepareCreator(resolution);
- creator.computeAllMembers();
- computedMemberNames = null;
- assert(areAllMembersComputed(), failedAt(this));
- }
-
- bool areAllMembersComputed() {
- return computedMemberNames == null && classMembers != null;
- }
-
- bool isMemberComputed(String name) {
- if (computedMemberNames == null) {
- return classMembers != null;
- } else {
- return name == Identifiers.call || computedMemberNames.contains(name);
- }
- }
-
- Member lookupClassMember(Name name) {
- assert(isMemberComputed(name.text),
- failedAt(this, "Member ${name} has not been computed for $this."));
- return classMembers[name];
- }
-
- void forEachClassMember(f(Member member)) {
- assert(areAllMembersComputed(),
- failedAt(this, "Members have not been fully computed for $this."));
- classMembers.forEach((_, member) => f(member));
- }
-
- MemberSignature lookupInterfaceMember(Name name) {
- assert(isMemberComputed(name.text),
- failedAt(this, "Member ${name.text} has not been computed for $this."));
- if (interfaceMembersAreClassMembers) {
- Member member = classMembers[name];
- if (member != null && member.isStatic) return null;
- return member;
- }
- return interfaceMembers[name];
- }
-
- void forEachInterfaceMember(f(MemberSignature member)) {
- assert(areAllMembersComputed(),
- failedAt(this, "Members have not been fully computed for $this."));
- if (interfaceMembersAreClassMembers) {
- classMembers.forEach((_, member) {
- if (!member.isStatic) f(member);
- });
- } else {
- interfaceMembers.forEach((_, member) => f(member));
- }
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
deleted file mode 100644
index ba5ec7b..0000000
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ /dev/null
@@ -1,910 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.constructors;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../constants/constructors.dart'
- show
- GenerativeConstantConstructor,
- RedirectingGenerativeConstantConstructor;
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart'
- show
- ConstructorElementX,
- ErroneousConstructorElementX,
- ErroneousElementX,
- ErroneousFieldElementX,
- FieldElementX,
- InitializingFormalElementX,
- ParameterElementX;
-import '../elements/names.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../universe/use.dart' show StaticUse;
-import '../util/util.dart' show Link;
-import 'members.dart' show lookupInScope, ResolverVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show CommonResolverVisitor;
-import 'resolution_result.dart';
-import 'scope.dart' show Scope, ExtensionScope;
-
-class InitializerResolver {
- final ResolverVisitor visitor;
- final ConstructorElementX constructor;
- final FunctionExpression functionNode;
- final Map<FieldElement, Node> initialized = <FieldElement, Node>{};
- final Map<FieldElement, ConstantExpression> fieldInitializers =
- <FieldElement, ConstantExpression>{};
- Link<Node> initializers;
- bool hasSuper = false;
- bool isValidAsConstant = true;
-
- bool get isConst => constructor.isConst;
-
- InitializerResolver(this.visitor, this.constructor, this.functionNode);
-
- ResolutionRegistry get registry => visitor.registry;
-
- DiagnosticReporter get reporter => visitor.reporter;
-
- bool isFieldInitializer(SendSet node) {
- if (node.selector.asIdentifier() == null) return false;
- if (node.receiver == null) return true;
- if (node.receiver.asIdentifier() == null) return false;
- return node.receiver.asIdentifier().isThis();
- }
-
- reportDuplicateInitializerError(
- Element field, Node init, Spannable existing) {
- reporter.reportError(
- reporter.createMessage(
- init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': field.name}),
- <DiagnosticMessage>[
- reporter.createMessage(existing, MessageKind.ALREADY_INITIALIZED,
- {'fieldName': field.name}),
- ]);
- isValidAsConstant = false;
- }
-
- void checkForDuplicateInitializers(FieldElementX field, Node init) {
- // [field] can be null if it could not be resolved.
- if (field == null) return;
- if (initialized.containsKey(field)) {
- reportDuplicateInitializerError(field, init, initialized[field]);
- } else if (field.isFinal) {
- field.parseNode(visitor.resolution.parsingContext);
- Expression initializer = field.initializer;
- if (initializer != null) {
- reportDuplicateInitializerError(
- field,
- init,
- reporter.withCurrentElement(
- field, () => reporter.spanFromSpannable(initializer)));
- }
- }
- initialized[field] = init;
- }
-
- void resolveFieldInitializer(SendSet init) {
- // init is of the form [this.]field = value.
- final Node selector = init.selector;
- final String name = selector.asIdentifier().source;
- // Lookup target field.
- Element target;
- FieldElement field;
- if (isFieldInitializer(init)) {
- // Use [enclosingElement] instead of [enclosingClass] to ensure lookup in
- // patch class when necessary.
- ClassElement cls = constructor.enclosingElement;
- target = cls.lookupLocalMember(name);
- if (target == null) {
- reporter.reportErrorMessage(
- selector, MessageKind.CANNOT_RESOLVE, {'name': name});
- target = new ErroneousFieldElementX(
- selector.asIdentifier(), constructor.enclosingClass);
- } else if (target.kind != ElementKind.FIELD) {
- reporter.reportErrorMessage(
- selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
- target = new ErroneousFieldElementX(
- selector.asIdentifier(), constructor.enclosingClass);
- } else if (!target.isInstanceMember) {
- reporter.reportErrorMessage(
- selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
- } else {
- field = target;
- }
- } else {
- reporter.reportErrorMessage(
- init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
- }
- if (target != null) {
- registry.useElement(init, target);
- checkForDuplicateInitializers(target, init);
- }
- if (field != null) {
- registry.registerStaticUse(new StaticUse.fieldInit(field));
- }
- // Resolve initializing value.
- ResolutionResult result = visitor.visitInStaticContext(init.arguments.head,
- inConstantInitializer: isConst);
- if (isConst) {
- if (result.isConstant && field != null) {
- // TODO(johnniwinther): Report error if `result.constant` is `null`.
- fieldInitializers[field] = result.constant;
- } else {
- isValidAsConstant = false;
- }
- }
- }
-
- ResolutionInterfaceType getSuperOrThisLookupTarget(Node diagnosticNode,
- {bool isSuperCall}) {
- if (isSuperCall) {
- // Calculate correct lookup target and constructor name.
- if (constructor.enclosingClass.isObject) {
- reporter.reportErrorMessage(
- diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
- isValidAsConstant = false;
- } else {
- return constructor.enclosingClass.supertype;
- }
- }
- return constructor.enclosingClass.thisType;
- }
-
- ResolutionResult resolveSuperOrThisForSend(Send node) {
- // Resolve the selector and the arguments.
- ArgumentsResult argumentsResult = visitor.inStaticContext(() {
- // TODO(johnniwinther): Remove this when [SendStructure] is used directly.
- visitor.resolveSelector(node, null);
- return visitor.resolveArguments(node.argumentsNode);
- }, inConstantInitializer: isConst);
-
- bool isSuperCall = Initializers.isSuperConstructorCall(node);
- ResolutionInterfaceType targetType =
- getSuperOrThisLookupTarget(node, isSuperCall: isSuperCall);
- ClassElement lookupTarget = targetType.element;
- String constructorName =
- visitor.getRedirectingThisOrSuperConstructorName(node).text;
- ConstructorElement foundConstructor =
- findConstructor(constructor.library, lookupTarget, constructorName);
-
- final String className = lookupTarget.name;
- CallStructure callStructure = argumentsResult.callStructure;
- ConstructorElement calledConstructor = verifyThatConstructorMatchesCall(
- node, foundConstructor, callStructure, className,
- constructorName: constructorName,
- isThisCall: !isSuperCall,
- isImplicitSuperCall: false);
- // TODO(johnniwinther): Remove this when information is pulled from an
- // [InitializerStructure].
- registry.useElement(node, calledConstructor);
- if (!calledConstructor.isError) {
- registry.registerStaticUse(new StaticUse.superConstructorInvoke(
- calledConstructor, callStructure));
- }
- if (isConst) {
- if (isValidAsConstant &&
- calledConstructor.isConst &&
- argumentsResult.isValidAsConstant) {
- List<ConstantExpression> arguments = argumentsResult.constantArguments;
- return new ConstantResult(
- node,
- new ConstructedConstantExpression(
- targetType, calledConstructor, callStructure, arguments),
- element: calledConstructor);
- } else {
- isValidAsConstant = false;
- }
- }
- return new ResolutionResult.forElement(calledConstructor);
- }
-
- ConstructedConstantExpression resolveImplicitSuperConstructorSend() {
- // If the class has a super resolve the implicit super call.
- ClassElement classElement = constructor.enclosingClass;
- ClassElement superClass = classElement.superclass;
- if (!classElement.isObject) {
- assert(superClass != null);
- assert(superClass.isResolved);
-
- ResolutionInterfaceType targetType =
- getSuperOrThisLookupTarget(functionNode, isSuperCall: true);
- ClassElement lookupTarget = targetType.element;
- ConstructorElement calledConstructor =
- findConstructor(constructor.library, lookupTarget, '');
-
- final String className = lookupTarget.name;
- CallStructure callStructure = CallStructure.NO_ARGS;
- ConstructorElement result = verifyThatConstructorMatchesCall(
- functionNode, calledConstructor, callStructure, className,
- isImplicitSuperCall: true);
- if (!result.isError) {
- registry.registerStaticUse(new StaticUse.superConstructorInvoke(
- calledConstructor, callStructure));
- }
-
- if (isConst && isValidAsConstant) {
- return new ConstructedConstantExpression(targetType, result,
- CallStructure.NO_ARGS, const <ConstantExpression>[]);
- }
- }
- return null;
- }
-
- ConstructorElement reportAndCreateErroneousConstructor(
- Spannable diagnosticNode, String name, MessageKind kind, Map arguments) {
- isValidAsConstant = false;
- reporter.reportErrorMessage(diagnosticNode, kind, arguments);
- return new ErroneousConstructorElementX(
- kind, arguments, name, visitor.currentClass);
- }
-
- /// Checks that [lookedupConstructor] is valid as a target for the super/this
- /// constructor call using with the given [callStructure].
- ///
- /// If [lookedupConstructor] is valid it is returned, otherwise an error is
- /// reported and an [ErroneousConstructorElement] is returned.
- ConstructorElement verifyThatConstructorMatchesCall(
- Node node,
- ConstructorElement lookedupConstructor,
- CallStructure callStructure,
- String className,
- {String constructorName: '',
- bool isImplicitSuperCall: false,
- bool isThisCall: false}) {
- Element result = lookedupConstructor;
- if (lookedupConstructor == null) {
- String fullConstructorName =
- Elements.constructorNameForDiagnostics(className, constructorName);
- MessageKind kind = isImplicitSuperCall
- ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
- : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
- result = reportAndCreateErroneousConstructor(node, constructorName, kind,
- {'constructorName': fullConstructorName});
- } else if (!lookedupConstructor.isGenerativeConstructor) {
- MessageKind kind = isThisCall
- ? MessageKind.THIS_CALL_TO_FACTORY
- : MessageKind.SUPER_CALL_TO_FACTORY;
- result =
- reportAndCreateErroneousConstructor(node, constructorName, kind, {});
- } else {
- lookedupConstructor.computeType(visitor.resolution);
- if (!callStructure
- .signatureApplies(lookedupConstructor.parameterStructure)) {
- MessageKind kind = isImplicitSuperCall
- ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
- : MessageKind.NO_MATCHING_CONSTRUCTOR;
- result = reportAndCreateErroneousConstructor(
- node, constructorName, kind, {});
- } else if (constructor.isConst && !lookedupConstructor.isConst) {
- MessageKind kind = isImplicitSuperCall
- ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
- : MessageKind.CONST_CALLS_NON_CONST;
- result = reportAndCreateErroneousConstructor(
- node, constructorName, kind, {});
- }
- }
- return result;
- }
-
- /**
- * Resolve all initializers of this constructor. In the case of a redirecting
- * constructor, the resolved constructor's function element is returned.
- */
- ConstructorElement resolveInitializers() {
- Map<dynamic /*String|int*/, ConstantExpression> defaultValues =
- <dynamic /*String|int*/, ConstantExpression>{};
- ConstructedConstantExpression constructorInvocation;
- // Keep track of all "this.param" parameters specified for constructor so
- // that we can ensure that fields are initialized only once.
- FunctionSignature functionParameters = constructor.functionSignature;
- Scope oldScope = visitor.scope;
- // In order to get the correct detection of name clashes between all
- // parameters (regular ones and initializing formals) we must extend
- // the parameter scope rather than adding a new nested scope.
- visitor.scope = new ExtensionScope(visitor.scope);
- Link<Node> parameterNodes = (functionNode?.parameters == null)
- ? const Link<Node>()
- : functionNode.parameters.nodes;
- functionParameters.forEachParameter((FormalElement _element) {
- ParameterElementX element = _element;
- List<Element> optionals = functionParameters.optionalParameters;
- if (!optionals.isEmpty && element == optionals.first) {
- NodeList nodes = parameterNodes.head;
- parameterNodes = nodes.nodes;
- }
- if (isConst) {
- if (element.isOptional) {
- if (element.constantCache == null) {
- // TODO(johnniwinther): Remove this when all constant expressions
- // can be computed during resolution.
- isValidAsConstant = false;
- } else {
- ConstantExpression defaultValue = element.constant;
- if (defaultValue != null) {
- if (element.isNamed) {
- defaultValues[element.name] = defaultValue;
- } else {
- int index =
- element.functionDeclaration.parameters.indexOf(element);
- defaultValues[index] = defaultValue;
- }
- } else {
- isValidAsConstant = false;
- }
- }
- }
- }
- if (element.isInitializingFormal) {
- VariableDefinitions variableDefinitions = parameterNodes.head;
- Node parameterNode = variableDefinitions.definitions.nodes.head;
- InitializingFormalElementX initializingFormal = element;
- FieldElement field = initializingFormal.fieldElement;
- if (!field.isMalformed) {
- registry.registerStaticUse(new StaticUse.fieldInit(field));
- }
- checkForDuplicateInitializers(field, parameterNode);
- visitor.defineLocalVariable(parameterNode, initializingFormal);
- visitor.addToScope(initializingFormal);
- if (isConst) {
- if (element.isNamed) {
- fieldInitializers[field] = new NamedArgumentReference(element.name);
- } else {
- int index = element.functionDeclaration.parameters.indexOf(element);
- fieldInitializers[field] = new PositionalArgumentReference(index);
- }
- } else {
- isValidAsConstant = false;
- }
- }
- parameterNodes = parameterNodes.tail;
- });
-
- if (functionNode?.initializers == null) {
- initializers = const Link<Node>();
- } else {
- initializers = functionNode.initializers.nodes;
- }
- bool resolvedSuper = false;
- for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) {
- if (link.head.asSendSet() != null) {
- final SendSet init = link.head.asSendSet();
- resolveFieldInitializer(init);
- } else if (link.head.asSend() != null) {
- final Send call = link.head.asSend();
- if (call.argumentsNode == null) {
- reporter.reportErrorMessage(
- link.head, MessageKind.INVALID_INITIALIZER);
- continue;
- }
- if (Initializers.isSuperConstructorCall(call)) {
- if (resolvedSuper) {
- reporter.reportErrorMessage(
- call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
- }
- ResolutionResult result = resolveSuperOrThisForSend(call);
- if (isConst) {
- if (result.isConstant) {
- constructorInvocation = result.constant;
- } else {
- isValidAsConstant = false;
- }
- }
- resolvedSuper = true;
- } else if (Initializers.isConstructorRedirect(call)) {
- // Check that there is no body (Language specification 7.5.1). If the
- // constructor is also const, we already reported an error in
- // [resolveMethodElement].
- if (functionNode.hasBody && !constructor.isConst) {
- reporter.reportErrorMessage(
- functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY);
- }
- // Check that there are no other initializers.
- if (!initializers.tail.isEmpty) {
- reporter.reportErrorMessage(
- call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER);
- } else {
- constructor.isRedirectingGenerativeInternal = true;
- }
- // Check that there are no field initializing parameters.
- FunctionSignature signature = constructor.functionSignature;
- signature.forEachParameter((FormalElement parameter) {
- if (parameter.isInitializingFormal) {
- Node node = parameter.node;
- reporter.reportErrorMessage(
- node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
- isValidAsConstant = false;
- }
- });
- ResolutionResult result = resolveSuperOrThisForSend(call);
- if (isConst) {
- if (result.isConstant) {
- constructorInvocation = result.constant;
- } else {
- isValidAsConstant = false;
- }
- if (isConst && isValidAsConstant) {
- constructor.constantConstructor =
- new RedirectingGenerativeConstantConstructor(
- defaultValues, constructorInvocation);
- }
- }
- return result.element;
- } else {
- reporter.reportErrorMessage(
- call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
- return null;
- }
- } else {
- reporter.reportErrorMessage(link.head, MessageKind.INVALID_INITIALIZER);
- }
- }
- if (!resolvedSuper) {
- constructorInvocation = resolveImplicitSuperConstructorSend();
- }
- constructor.enclosingClass
- .forEachInstanceField((ClassElement declarer, FieldElement field) {
- if (declarer != constructor.enclosingClass) return;
-
- if (!initialized.containsKey(field)) {
- visitor.resolution.ensureResolved(field);
- if (field.isFinal && field.initializer == null) {
- registry.registerStaticUse(new StaticUse.fieldInit(field));
- registry.registerConstantLiteral(new NullConstantExpression());
- }
- }
- });
-
- if (isConst && isValidAsConstant) {
- constructor.enclosingClass.forEachInstanceField((_, FieldElement field) {
- if (!fieldInitializers.containsKey(field)) {
- visitor.resolution.ensureResolved(field);
- // TODO(johnniwinther): Report error if `field.constant` is `null`.
- if (field.constant != null) {
- fieldInitializers[field] = field.constant;
- } else {
- isValidAsConstant = false;
- }
- }
- });
- if (isValidAsConstant) {
- constructor.constantConstructor = new GenerativeConstantConstructor(
- constructor.enclosingClass.thisType,
- defaultValues,
- fieldInitializers,
- const <AssertConstantExpression>[],
- constructorInvocation);
- }
- }
- visitor.scope = oldScope;
- return null; // If there was no redirection always return null.
- }
-}
-
-class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
- final ResolverVisitor resolver;
- final bool inConstContext;
-
- ConstructorResolver(Resolution resolution, this.resolver,
- {bool this.inConstContext: false})
- : super(resolution);
-
- ResolutionRegistry get registry => resolver.registry;
-
- Element get context => resolver.enclosingElement;
-
- visitNode(Node node) {
- throw 'not supported';
- }
-
- ConstructorResult reportAndCreateErroneousConstructorElement(
- Spannable diagnosticNode,
- ConstructorResultKind resultKind,
- ResolutionDartType type,
- String name,
- MessageKind kind,
- Map arguments,
- {bool isError: 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.reportError(message, infos);
- } else {
- reporter.reportWarning(message, infos);
- }
- ErroneousElement error =
- new ErroneousConstructorElementX(kind, arguments, name, context);
- if (type == null) {
- type = new MalformedType(error, null);
- }
- return new ConstructorResult.forError(resultKind, error, type);
- }
-
- ConstructorResult resolveConstructor(
- PrefixElement prefix,
- ResolutionInterfaceType type,
- Node diagnosticNode,
- String constructorName) {
- ClassElement cls = type.element;
- cls.ensureResolved(resolution);
- ConstructorElement constructor =
- findConstructor(context.library, cls, constructorName);
- if (constructor == null) {
- MessageKind kind = constructorName.isEmpty
- ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR
- : MessageKind.CANNOT_FIND_CONSTRUCTOR;
- return reportAndCreateErroneousConstructorElement(
- diagnosticNode,
- ConstructorResultKind.UNRESOLVED_CONSTRUCTOR,
- type,
- constructorName,
- kind,
- {'className': cls.name, 'constructorName': constructorName},
- missingConstructor: true);
- } else if (inConstContext && !constructor.isConst) {
- reporter.reportErrorMessage(
- diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
- return new ConstructorResult(
- ConstructorResultKind.NON_CONSTANT, prefix, constructor, type);
- } else {
- if (cls.isEnumClass && resolver.currentClass != cls) {
- return reportAndCreateErroneousConstructorElement(
- diagnosticNode,
- ConstructorResultKind.INVALID_TYPE,
- type,
- constructorName,
- MessageKind.CANNOT_INSTANTIATE_ENUM,
- {'enumName': cls.name},
- isError: true);
- }
- if (constructor.isGenerativeConstructor) {
- if (cls.isAbstract) {
- reporter.reportWarningMessage(
- diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
- registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
- return new ConstructorResult(
- ConstructorResultKind.ABSTRACT, prefix, constructor, type);
- } else {
- return new ConstructorResult(
- ConstructorResultKind.GENERATIVE, prefix, constructor, type);
- }
- } else {
- assert(constructor.isFactoryConstructor,
- failedAt(diagnosticNode, "Unexpected constructor $constructor."));
- return new ConstructorResult(
- ConstructorResultKind.FACTORY, prefix, constructor, type);
- }
- }
- }
-
- ConstructorResult visitNewExpression(NewExpression node) {
- Node selector = node.send.selector;
- ConstructorResult result = visit(selector);
- assert(result != null,
- failedAt(selector, 'No result returned for $selector.'));
- return finishConstructorReference(result, node.send.selector, node);
- }
-
- /// Finishes resolution of a constructor reference and records the
- /// type of the constructed instance on [expression].
- ConstructorResult finishConstructorReference(
- ConstructorResult result, Node diagnosticNode, Node expression) {
- assert(result != null,
- failedAt(diagnosticNode, 'No result returned for $diagnosticNode.'));
-
- if (result.kind != null) {
- resolver.registry.setType(expression, result.type);
- return result;
- }
-
- // Find the unnamed constructor if the reference resolved to a
- // class.
- if (result.type != null) {
- // The unnamed constructor may not exist, so [e] may become unresolved.
- result =
- resolveConstructor(result.prefix, result.type, diagnosticNode, '');
- } else {
- Element element = result.element;
- if (element.isMalformed) {
- result = constructorResultForErroneous(diagnosticNode, element);
- } else {
- result = reportAndCreateErroneousConstructorElement(
- diagnosticNode,
- ConstructorResultKind.INVALID_TYPE,
- null,
- element.name,
- MessageKind.NOT_A_TYPE,
- {'node': diagnosticNode});
- }
- }
- resolver.registry.setType(expression, result.type);
- return result;
- }
-
- ConstructorResult visitNominalTypeAnnotation(NominalTypeAnnotation node) {
- // This is not really resolving a type-annotation, but the name of the
- // constructor. Therefore we allow deferred types.
- ResolutionDartType type = resolver.resolveTypeAnnotation(node,
- malformedIsError: inConstContext,
- deferredIsMalformed: false,
- registerCheckedModeCheck: false);
- Send send = node.typeName.asSend();
- PrefixElement prefix;
- if (send != null) {
- // The type name is of the form [: prefix . identifier :].
- String name = send.receiver.asIdentifier().source;
- Element element = lookupInScope(reporter, send, resolver.scope, name);
- if (element != null && element.isPrefix) {
- prefix = element;
- }
- }
- return constructorResultForType(node, type, prefix: prefix);
- }
-
- ConstructorResult visitSend(Send node) {
- ConstructorResult receiver = visit(node.receiver);
- assert(receiver != null,
- failedAt(node.receiver, 'No result returned for $node.receiver.'));
- if (receiver.kind != null) {
- assert(receiver.element.isMalformed,
- failedAt(node, "Unexpected prefix result: $receiver."));
- // We have already found an error.
- return receiver;
- }
-
- Identifier name = node.selector.asIdentifier();
- if (name == null) {
- reporter.internalError(node.selector, 'unexpected node');
- }
-
- if (receiver.type != null) {
- if (receiver.type.isInterfaceType) {
- return resolveConstructor(
- receiver.prefix, receiver.type, name, name.source);
- } else {
- // TODO(johnniwinther): Update the message for the different types.
- return reportAndCreateErroneousConstructorElement(
- name,
- ConstructorResultKind.INVALID_TYPE,
- null,
- name.source,
- MessageKind.NOT_A_TYPE,
- {'node': name});
- }
- } else if (receiver.element.isPrefix) {
- PrefixElement prefix = receiver.element;
- Element member = prefix.lookupLocalMember(name.source);
- return constructorResultForElement(node, name.source, member,
- prefix: prefix);
- } else {
- return reporter.internalError(
- node.receiver, 'unexpected receiver $receiver');
- }
- }
-
- ConstructorResult visitIdentifier(Identifier node) {
- String name = node.source;
- Element element = lookupInScope(reporter, node, resolver.scope, name);
- registry.useElement(node, element);
- return constructorResultForElement(node, name, element);
- }
-
- /// Assumed to be called by [resolveRedirectingFactory].
- ConstructorResult visitRedirectingFactoryBody(RedirectingFactoryBody node) {
- Node constructorReference = node.constructorReference;
- return finishConstructorReference(
- visit(constructorReference), constructorReference, node);
- }
-
- ConstructorResult constructorResultForElement(
- Node node, String name, Element element,
- {PrefixElement prefix}) {
- element = Elements.unwrap(element, reporter, node);
- if (element == null) {
- return reportAndCreateErroneousConstructorElement(
- node,
- ConstructorResultKind.INVALID_TYPE,
- null,
- name,
- MessageKind.CANNOT_RESOLVE,
- {'name': name});
- } else if (element.isAmbiguous) {
- AmbiguousElement ambiguous = element;
- return reportAndCreateErroneousConstructorElement(
- node,
- ConstructorResultKind.INVALID_TYPE,
- null,
- name,
- ambiguous.messageKind,
- ambiguous.messageArguments,
- infos: ambiguous.computeInfos(context, reporter));
- } else if (element.isMalformed) {
- return constructorResultForErroneous(node, element);
- } else if (element.isClass) {
- ClassElement cls = element;
- cls.computeType(resolution);
- return constructorResultForType(node, cls.rawType, prefix: prefix);
- } else if (element.isPrefix) {
- return new ConstructorResult.forPrefix(element);
- } else if (element.isTypedef) {
- TypedefElement typdef = element;
- typdef.ensureResolved(resolution);
- return constructorResultForType(node, typdef.rawType);
- } else if (element.isTypeVariable) {
- TypeVariableElement typeVariableElement = element;
- return constructorResultForType(node, typeVariableElement.type);
- } else {
- return reportAndCreateErroneousConstructorElement(
- node,
- ConstructorResultKind.INVALID_TYPE,
- null,
- name,
- MessageKind.NOT_A_TYPE,
- {'node': name});
- }
- }
-
- ConstructorResult constructorResultForErroneous(Node node, Element error) {
- if (error is! ErroneousElementX) {
- // Parser error. The error has already been reported.
- error = new ErroneousConstructorElementX(
- MessageKind.NOT_A_TYPE, {'node': node}, error.name, error);
- registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
- }
- return new ConstructorResult.forError(ConstructorResultKind.INVALID_TYPE,
- error, new MalformedType(error, null));
- }
-
- ConstructorResult constructorResultForType(Node node, ResolutionDartType type,
- {PrefixElement prefix}) {
- String name = type.name;
- if (type.isTypeVariable) {
- return reportAndCreateErroneousConstructorElement(
- node,
- ConstructorResultKind.INVALID_TYPE,
- type,
- name,
- MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
- {'typeVariableName': name});
- } else if (type.isMalformed) {
- // `type is MalformedType`: `MethodTypeVariableType` is handled above.
- return new ConstructorResult.forError(
- ConstructorResultKind.INVALID_TYPE, type.element, type);
- } else if (type.isInterfaceType) {
- return new ConstructorResult.forType(prefix, type);
- } else if (type.isTypedef) {
- return reportAndCreateErroneousConstructorElement(
- node,
- ConstructorResultKind.INVALID_TYPE,
- type,
- name,
- MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
- {'typedefName': name});
- }
- return reporter.internalError(node, "Unexpected constructor type $type");
- }
-}
-
-/// The kind of constructor found by the [ConstructorResolver].
-enum ConstructorResultKind {
- /// A generative or redirecting generative constructor.
- GENERATIVE,
-
- /// A factory or redirecting factory constructor.
- FACTORY,
-
- /// A generative or redirecting generative constructor on an abstract class.
- ABSTRACT,
-
- /// No constructor was found because the type was invalid, for instance
- /// unresolved, an enum class, a type variable, a typedef or a non-type.
- INVALID_TYPE,
-
- /// No constructor of the sought name was found on the class.
- UNRESOLVED_CONSTRUCTOR,
-
- /// A non-constant constructor was found for a const constructor invocation.
- NON_CONSTANT,
-}
-
-/// The (partial) result of the resolution of a new expression used in
-/// [ConstructorResolver].
-class ConstructorResult {
- /// The prefix used to access the constructor. For instance `prefix` in `new
- /// prefix.Class.constructorName()`.
- final PrefixElement prefix;
-
- /// The kind of the found constructor.
- final ConstructorResultKind kind;
-
- /// The currently found element. Since [ConstructorResult] is used for partial
- /// results, this might be a [PrefixElement], a [ClassElement], a
- /// [ConstructorElement] or in the negative cases an [ErroneousElement].
- final Element element;
-
- /// The type of the new expression. For instance `Foo<String>` in
- /// `new prefix.Foo<String>.constructorName()`.
- final ResolutionDartType type;
-
- /// Creates a fully resolved constructor access where [element] is resolved
- /// to a constructor and [type] to an interface type.
- ConstructorResult(this.kind, this.prefix, ConstructorElement this.element,
- ResolutionInterfaceType this.type);
-
- /// Creates a fully resolved constructor access where [element] is an
- /// [ErroneousElement].
- // TODO(johnniwinther): Do we still need the prefix for cases like
- // `new deferred.Class.unresolvedConstructor()` ?
- ConstructorResult.forError(
- this.kind, ErroneousElement this.element, this.type)
- : prefix = null;
-
- /// Creates a constructor access that is partially resolved to a prefix. For
- /// instance `prefix` of `new prefix.Class()`.
- ConstructorResult.forPrefix(this.element)
- : prefix = null,
- kind = null,
- type = null;
-
- /// Creates a constructor access that is partially resolved to a type. For
- /// instance `Foo<String>` of `new Foo<String>.constructorName()`.
- ConstructorResult.forType(this.prefix, this.type)
- : kind = null,
- element = null;
-
- bool get isDeferred => prefix != null && prefix.isDeferred;
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.write('ConstructorResult(');
- if (kind != null) {
- sb.write('kind=$kind,');
- if (prefix != null) {
- sb.write('prefix=$prefix,');
- }
- sb.write('element=$element,');
- sb.write('type=$type');
- } else if (element != null) {
- sb.write('element=$element');
- } else {
- if (prefix != null) {
- sb.write('prefix=$prefix,');
- }
- sb.write('type=$type');
- }
- sb.write(')');
- return sb.toString();
- }
-}
-
-/// Lookup the [constructorName] constructor in [cls] and normalize the result
-/// with respect to privacy and patching.
-ConstructorElement findConstructor(
- LibraryElement currentLibrary, ClassElement cls, String constructorName) {
- if (Name.isPrivateName(constructorName) &&
- currentLibrary.library != cls.library) {
- // TODO(johnniwinther): Report a special error on unaccessible private
- // constructors.
- return null;
- }
- // TODO(johnniwinther): Use [Name] for lookup.
- ConstructorElement constructor = cls.lookupConstructor(constructorName);
- if (constructor != null) {
- constructor = constructor.declaration;
- }
- return constructor;
-}
diff --git a/pkg/compiler/lib/src/resolution/deferred_load.dart b/pkg/compiler/lib/src/resolution/deferred_load.dart
deleted file mode 100644
index e826a25..0000000
--- a/pkg/compiler/lib/src/resolution/deferred_load.dart
+++ /dev/null
@@ -1,376 +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 resolution.deferred_load;
-
-import '../common.dart';
-import '../compiler.dart' show Compiler;
-import '../constants/expressions.dart' show ConstantExpression;
-import '../constants/values.dart'
- show ConstantValue, ConstructedConstantValue, StringConstantValue;
-import '../deferred_load.dart';
-import '../elements/elements.dart'
- show
- AstElement,
- AccessorElement,
- ClassElement,
- ConstructorElement,
- Element,
- ExportElement,
- ImportElement,
- LibraryElement,
- MemberElement,
- MetadataAnnotation,
- PrefixElement,
- ResolvedAstKind,
- TypedefElement;
-import '../elements/resolution_types.dart';
-import '../js_backend/js_backend.dart' show JavaScriptBackend;
-import '../resolution/resolution.dart' show AnalyzableElementX;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart' as ast;
-import '../util/util.dart' show Setlet;
-import 'tree_elements.dart' show TreeElements;
-
-class AstDeferredLoadTask extends DeferredLoadTask {
- /// DeferredLibrary from dart:async
- ClassElement get deferredLibraryClass =>
- compiler.resolution.commonElements.deferredLibraryClass;
-
- JavaScriptBackend get backend => compiler.backend;
-
- AstDeferredLoadTask(Compiler compiler) : super(compiler);
-
- Iterable<ImportElement> importsTo(
- covariant Element element, covariant LibraryElement library) {
- if (element.isClassMember) {
- element = element.enclosingClass;
- }
- if (element.isAccessor) {
- element = (element as AccessorElement).abstractField;
- }
- return library.getImportsFor(element);
- }
-
- void checkForDeferredErrorCases(covariant LibraryElement library) {
- var usedPrefixes = new Setlet<String>();
- // The last deferred import we saw with a given prefix (if any).
- var prefixDeferredImport = new Map<String, ImportElement>();
- for (ImportElement import in library.imports) {
- _detectOldSyntax(import);
- _detectDuplicateErrorCases(import, usedPrefixes, prefixDeferredImport);
- }
- }
-
- /// Give an error if the old annotation-based syntax has been used.
- void _detectOldSyntax(ImportElement import) {
- List<MetadataAnnotation> metadataList = import.metadata;
- if (metadataList != null) {
- for (MetadataAnnotation metadata in metadataList) {
- metadata.ensureResolved(compiler.resolution);
- ConstantValue value =
- compiler.constants.getConstantValue(metadata.constant);
- ResolutionDartType type =
- value.getType(compiler.resolution.commonElements);
- Element element = type.element;
- if (element == deferredLibraryClass) {
- reporter.reportErrorMessage(import, MessageKind.DEFERRED_OLD_SYNTAX);
- }
- }
- }
- }
-
- /// Detect duplicate prefixes of deferred libraries.
- ///
- /// There are 4 cases of duplicate prefixes:
- /// 1.
- /// import "lib.dart" deferred as a;
- /// import "lib2.dart" deferred as a;
- ///
- /// 2.
- /// import "lib.dart" deferred as a;
- /// import "lib2.dart" as a;
- ///
- /// 3.
- /// import "lib.dart" as a;
- /// import "lib2.dart" deferred as a;
- ///
- /// 4.
- /// import "lib.dart" as a;
- /// import "lib2.dart" as a;
- ///
- /// We must be able to signal error for case 1, 2, 3, but accept case 4.
- void _detectDuplicateErrorCases(
- ImportElement import,
- Set<String> usedPrefixes,
- Map<String, ImportElement> prefixDeferredImport) {
- String prefix = import.name;
- // The last import we saw with the same prefix.
- ImportElement previousDeferredImport = prefixDeferredImport[prefix];
- if (import.isDeferred) {
- if (prefix == null) {
- reporter.reportErrorMessage(
- import, MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX);
- } else {
- prefixDeferredImport[prefix] = import;
- }
- }
- if (prefix != null) {
- if (previousDeferredImport != null ||
- (import.isDeferred && usedPrefixes.contains(prefix))) {
- ImportElement failingImport =
- (previousDeferredImport != null) ? previousDeferredImport : import;
- reporter.reportErrorMessage(failingImport.prefix,
- MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX);
- }
- usedPrefixes.add(prefix);
- }
- }
-
- @override
- void collectConstantsFromMetadata(
- covariant AstElement element, Set<ConstantValue> constants) {
- for (MetadataAnnotation metadata in element.metadata) {
- ConstantValue constant =
- backend.constants.getConstantValueForMetadata(metadata);
- if (constant != null) constants.add(constant);
- }
- }
-
- @override
- void collectConstantsInBody(
- covariant AstElement element, Set<ConstantValue> constants) {
- if (element.resolvedAst.kind != ResolvedAstKind.PARSED) return;
-
- TreeElements treeElements = element.resolvedAst.elements;
- assert(treeElements != null);
-
- Set<ast.Node> metadataNodes = element.implementation.metadata
- .map((m) => m.node)
- .toSet()
- ..addAll(element.declaration.metadata.map((m) => m.node));
-
- // TODO(johnniwinther): Add only expressions that are actually needed.
- // Currently we have some noise here: Some potential expressions are
- // seen that should never be added (for instance field initializers
- // in constant constructors, like `this.field = parameter`). And some
- // implicit constant expression are seen that we should be able to add
- // (like primitive constant literals like `true`, `"foo"` and `0`).
- // See dartbug.com/26406 for context.
- treeElements
- .forEachConstantNode((ast.Node node, ConstantExpression expression) {
- if (metadataNodes.contains(node)) return;
-
- // Explicitly depend on the backend constants.
- if (backend.constants.hasConstantValue(expression)) {
- ConstantValue value = backend.constants.getConstantValue(expression);
- assert(
- value != null,
- failedAt(
- node,
- "Constant expression without value: "
- "${expression.toStructuredText()}."));
- constants.add(value);
- } else {
- assert(
- expression.isImplicit || expression.isPotential,
- failedAt(
- node,
- "Unexpected unevaluated constant expression: "
- "${expression.toStructuredText()}."));
- }
- });
- }
-
- void addDeferredMirrorElements(WorkQueue queue) {
- for (ImportElement deferredImport in allDeferredImports) {
- addMirrorElementsForLibrary(queue, deferredImport.importedLibrary,
- importSets.singleton(deferredImport));
- }
- }
-
- void addMirrorElementsForLibrary(
- WorkQueue queue, covariant LibraryElement root, ImportSet newSet) {
- void handleElementIfResolved(Element element) {
- // If an element is the target of a MirrorsUsed annotation but never used
- // It will not be resolved, and we should not call isNeededForReflection.
- // TODO(sigurdm): Unresolved elements should just answer false when
- // asked isNeededForReflection. Instead an internal error is triggered.
- // So we have to filter them out here.
- if (element is AnalyzableElementX && !element.hasTreeElements) return;
-
- bool isAccessibleByReflection(Element element) {
- if (element.isLibrary) {
- return false;
- } else if (element.isClass) {
- ClassElement cls = element;
- return compiler.backend.mirrorsData
- .isClassAccessibleByReflection(cls);
- } else if (element.isTypedef) {
- TypedefElement typedef = element;
- return compiler.backend.mirrorsData
- .isTypedefAccessibleByReflection(typedef);
- } else {
- MemberElement member = element;
- return compiler.backend.mirrorsData
- .isMemberAccessibleByReflection(member);
- }
- }
-
- if (isAccessibleByReflection(element)) {
- queue.addElement(element, newSet, isMirrorUsage: true);
- }
- }
-
- // For each deferred import we analyze all elements reachable from the
- // imported library through non-deferred imports.
- void handleLibrary(LibraryElement library) {
- library.implementation.forEachLocalMember((Element element) {
- handleElementIfResolved(element);
- });
-
- void processMetadata(Element element) {
- for (MetadataAnnotation metadata in element.metadata) {
- ConstantValue constant =
- backend.constants.getConstantValueForMetadata(metadata);
- if (constant != null) {
- queue.addConstant(constant, newSet);
- }
- }
- }
-
- processMetadata(library);
- library.imports.forEach(processMetadata);
- library.exports.forEach(processMetadata);
- }
-
- _nonDeferredReachableLibraries(root).forEach(handleLibrary);
- }
-
- /// Returns the transitive closure of all libraries that are imported
- /// from root without DeferredLibrary annotations.
- Set<LibraryElement> _nonDeferredReachableLibraries(LibraryElement root) {
- Set<LibraryElement> result = new Set<LibraryElement>();
-
- void traverseLibrary(LibraryElement library) {
- if (result.contains(library)) return;
- result.add(library);
-
- iterateDependencies(LibraryElement library) {
- for (ImportElement import in library.imports) {
- if (!import.isDeferred) {
- LibraryElement importedLibrary = import.importedLibrary;
- traverseLibrary(importedLibrary);
- }
- }
- for (ExportElement export in library.exports) {
- LibraryElement exportedLibrary = export.exportedLibrary;
- traverseLibrary(exportedLibrary);
- }
- }
-
- iterateDependencies(library);
- if (library.isPatched) {
- iterateDependencies(library.implementation);
- }
- }
-
- traverseLibrary(root);
- result.add(compiler.resolution.commonElements.coreLibrary);
- return result;
- }
-
- /// If [send] is a static send with a deferred element, returns the
- /// [PrefixElement] that the first prefix of the send resolves to.
- /// Otherwise returns null.
- ///
- /// Precondition: send must be static.
- ///
- /// Example:
- ///
- /// import "a.dart" deferred as a;
- ///
- /// main() {
- /// print(a.loadLibrary.toString());
- /// a.loadLibrary().then((_) {
- /// a.run();
- /// a.foo.method();
- /// });
- /// }
- ///
- /// Returns null for a.loadLibrary() (the special
- /// function loadLibrary is not deferred). And returns the PrefixElement for
- /// a.run() and a.foo.
- /// a.loadLibrary.toString() and a.foo.method() are dynamic sends - and
- /// this functions should not be called on them.
- ImportElement deferredImportElement(ast.Send send, TreeElements elements) {
- Element element = elements[send];
- // The DeferredLoaderGetter is not deferred, therefore we do not return the
- // prefix.
- if (element != null && element.isDeferredLoaderGetter) return null;
-
- ast.Node firstNode(ast.Node node) {
- if (node is! ast.Send) {
- return node;
- } else {
- ast.Send send = node;
- ast.Node receiver = send.receiver;
- ast.Node receiverFirst = firstNode(receiver);
- if (receiverFirst != null) {
- return receiverFirst;
- } else {
- return firstNode(send.selector);
- }
- }
- }
-
- ast.Node first = firstNode(send);
- ast.Node identifier = first.asIdentifier();
- if (identifier == null) return null;
- Element maybePrefix = elements[identifier];
- if (maybePrefix != null && maybePrefix.isPrefix) {
- PrefixElement prefixElement = maybePrefix;
- if (prefixElement.isDeferred) {
- return prefixElement.deferredImport;
- }
- }
- return null;
- }
-
- /// Returns a name for a deferred import.
- // TODO(sigmund): delete support for the old annotation-style syntax.
- String computeImportDeferName(
- covariant ImportElement declaration, Compiler compiler) {
- if (declaration.isDeferred) {
- return super.computeImportDeferName(declaration, compiler);
- }
-
- String result;
- // Finds the first argument to the [DeferredLibrary] annotation
- List<MetadataAnnotation> metadatas = declaration.metadata;
- assert(metadatas != null);
- for (MetadataAnnotation metadata in metadatas) {
- metadata.ensureResolved(compiler.resolution);
- ConstantValue value =
- compiler.constants.getConstantValue(metadata.constant);
- ResolutionDartType type =
- value.getType(compiler.resolution.commonElements);
- Element element = type.element;
- if (element == compiler.resolution.commonElements.deferredLibraryClass) {
- ConstructedConstantValue constant = value;
- StringConstantValue s = constant.fields.values.single;
- result = s.stringValue;
- break;
- }
- }
- assert(result != null);
- return result;
- }
-
- bool ignoreEntityInDump(covariant Element element) =>
- // origin element will already be dumped.
- element.isPatch ||
- // redirecting factories are not visible to the kernel ir
- element is ConstructorElement && element.isRedirectingFactory;
-}
diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart
deleted file mode 100644
index 72781d4..0000000
--- a/pkg/compiler/lib/src/resolution/enum_creator.dart
+++ /dev/null
@@ -1,359 +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 dart2js.resolution.enum_creator;
-
-import '../common.dart';
-import '../common_elements.dart' show CommonElements;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart';
-import 'package:front_end/src/fasta/scanner.dart';
-import 'package:front_end/src/scanner/token.dart' show KeywordToken, TokenType;
-import '../tree/tree.dart';
-import '../util/util.dart';
-
-// TODO(johnniwinther): Merge functionality with the `TreePrinter`.
-class AstBuilder {
- final int charOffset;
-
- AstBuilder(this.charOffset);
-
- Modifiers modifiers(
- {bool isConst: false, bool isFinal: false, bool isStatic: false}) {
- List identifiers = [];
- int flags = 0;
- if (isConst) {
- identifiers.add(identifier('const'));
- flags |= Modifiers.FLAG_CONST;
- }
- if (isFinal) {
- identifiers.add(identifier('final'));
- flags |= Modifiers.FLAG_FINAL;
- }
- if (isStatic) {
- identifiers.add(identifier('static'));
- flags |= Modifiers.FLAG_STATIC;
- }
- return new Modifiers.withFlags(
- new NodeList(null, linkedList(identifiers), null, ''), flags);
- }
-
- Token keywordToken(String text) {
- return new KeywordToken(Keyword.keywords[text], charOffset);
- }
-
- Token stringToken(String text) {
- return new StringToken.fromString(TokenType.IDENTIFIER, text, charOffset);
- }
-
- Token symbolToken(TokenType type) {
- return new Token(type, charOffset);
- }
-
- Identifier identifier(String text) {
- Keyword keyword = Keyword.keywords[text];
- Token token;
- if (keyword != null) {
- token = new KeywordToken(keyword, charOffset);
- } else {
- token = stringToken(text);
- }
- return new Identifier(token);
- }
-
- Link linkedList(List elements) {
- LinkBuilder builder = new LinkBuilder();
- elements.forEach((e) => builder.addLast(e));
- return builder.toLink();
- }
-
- NodeList argumentList(List<Node> nodes) {
- return new NodeList(symbolToken(TokenType.OPEN_PAREN), linkedList(nodes),
- symbolToken(TokenType.CLOSE_PAREN), ',');
- }
-
- Return returnStatement(Expression expression) {
- return new Return(
- keywordToken('return'), symbolToken(TokenType.SEMICOLON), expression);
- }
-
- FunctionExpression functionExpression(Modifiers modifiers, String name,
- NodeList typeVariables, NodeList argumentList, Statement body,
- [TypeAnnotation returnType]) {
- return new FunctionExpression(
- identifier(name),
- typeVariables,
- argumentList,
- body,
- returnType,
- modifiers,
- null, // Initializer.
- null, // get/set.
- null // Async modifier.
- );
- }
-
- EmptyStatement emptyStatement() {
- return new EmptyStatement(symbolToken(TokenType.COMMA));
- }
-
- LiteralInt literalInt(int value) {
- return new LiteralInt(stringToken('$value'), null);
- }
-
- LiteralString literalString(String text,
- {String prefix: '"', String suffix: '"'}) {
- return new LiteralString(
- stringToken('$prefix$text$suffix'), new DartString.literal(text));
- }
-
- LiteralList listLiteral(List<Node> elements, {bool isConst: false}) {
- return new LiteralList(
- null,
- new NodeList(
- symbolToken(TokenType.OPEN_SQUARE_BRACKET),
- linkedList(elements),
- symbolToken(TokenType.CLOSE_SQUARE_BRACKET),
- ','),
- isConst ? keywordToken('const') : null);
- }
-
- Node createDefinition(Identifier name, Expression initializer) {
- if (initializer == null) return name;
- return new SendSet(null, name, new Operator(symbolToken(TokenType.EQ)),
- new NodeList.singleton(initializer));
- }
-
- VariableDefinitions initializingFormal(String fieldName) {
- return new VariableDefinitions.forParameter(
- new NodeList.empty(),
- null,
- Modifiers.EMPTY,
- new NodeList.singleton(
- new Send(identifier('this'), identifier(fieldName))));
- }
-
- NewExpression newExpression(String typeName, NodeList arguments,
- {bool isConst: false}) {
- return new NewExpression(keywordToken(isConst ? 'const' : 'new'),
- new Send(null, identifier(typeName), arguments));
- }
-
- Send reference(Identifier identifier) {
- return new Send(null, identifier);
- }
-
- Send indexGet(Expression receiver, Expression index) {
- return new Send(receiver, new Operator(symbolToken(TokenType.INDEX)),
- new NodeList.singleton(index));
- }
-
- LiteralMapEntry mapLiteralEntry(Expression key, Expression value) {
- return new LiteralMapEntry(key, symbolToken(TokenType.COLON), value);
- }
-
- LiteralMap mapLiteral(List<LiteralMapEntry> entries, {bool isConst: false}) {
- return new LiteralMap(
- null, // Type arguments.
- new NodeList(
- symbolToken(TokenType.OPEN_CURLY_BRACKET),
- linkedList(entries),
- symbolToken(TokenType.CLOSE_CURLY_BRACKET),
- ','),
- isConst ? keywordToken('const') : null);
- }
-}
-
-/// This class generates the model for an enum class.
-///
-/// For instance
-///
-/// enum A { b, c, }
-///
-/// is modelled as
-///
-/// class A {
-/// final int index;
-/// final String _name;
-///
-/// const A(this.index);
-///
-/// String toString() {
-/// return _name;
-/// }
-///
-/// static const A b = const A(0, "A.b");
-/// static const A c = const A(1, "A.v");
-///
-/// static const List<A> values = const <A>[b, c];
-/// }
-///
-// TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is
-// removed.
-class EnumCreator {
- final DiagnosticReporter reporter;
- final CommonElements commonElements;
- final EnumClassElementX enumClass;
-
- EnumCreator(this.reporter, this.commonElements, this.enumClass);
-
- /// Whether to use a constant-map to encode the result of toString on an enum
- /// value.
- ///
- /// Dart2js by default uses a compact representation of enum values that
- /// include their name. The spec and the kernel-based implementation use a
- /// const-map to encode the result of toString. This flag is used to disable
- /// the default representation, and instead match the kernel representation to
- /// make it easier to test the equivalence of resolution-based and
- /// kernel-based world builders.
- static bool matchKernelRepresentationForTesting = false;
-
- void createMembers() {
- Enum node = enumClass.node;
- ResolutionInterfaceType enumType = enumClass.thisType;
- AstBuilder builder = new AstBuilder(enumClass.position.charOffset);
-
- ResolutionInterfaceType intType = commonElements.intType;
- ResolutionInterfaceType stringType = commonElements.stringType;
-
- EnumFieldElementX addInstanceMember(
- String name, ResolutionInterfaceType type) {
- Identifier identifier = builder.identifier(name);
- VariableList variableList =
- new VariableList(builder.modifiers(isFinal: true));
- variableList.type = type;
- EnumFieldElementX variable = new EnumFieldElementX(
- identifier, enumClass, variableList, identifier);
- enumClass.addMember(variable, reporter);
- return variable;
- }
-
- EnumFieldElementX indexVariable = addInstanceMember('index', intType);
- EnumFieldElementX nameVariable;
-
- VariableDefinitions indexDefinition = builder.initializingFormal('index');
- VariableDefinitions nameDefinition;
-
- List<Node> constructorInitializers = <Node>[indexDefinition];
- if (!matchKernelRepresentationForTesting) {
- nameVariable = addInstanceMember('_name', stringType);
- nameDefinition = builder.initializingFormal('_name');
- constructorInitializers.add(nameDefinition);
- }
- FunctionExpression constructorNode = builder.functionExpression(
- builder.modifiers(isConst: true),
- enumClass.name,
- null, // typeVariables
- builder.argumentList(constructorInitializers),
- builder.emptyStatement());
-
- EnumConstructorElementX constructor = new EnumConstructorElementX(
- enumClass, builder.modifiers(isConst: true), constructorNode);
-
- EnumFormalElementX indexFormal = new EnumFormalElementX(constructor,
- indexDefinition, builder.identifier('index'), indexVariable);
-
- EnumFormalElementX nameFormal;
-
- List<FormalElement> parameters = <FormalElement>[indexFormal];
- List<ResolutionDartType> parameterTypes = <ResolutionDartType>[intType];
- if (!matchKernelRepresentationForTesting) {
- nameFormal = new EnumFormalElementX(constructor, nameDefinition,
- builder.identifier('_name'), nameVariable);
- parameters.add(nameFormal);
- parameterTypes.add(stringType);
- }
- FunctionSignatureX constructorSignature = new FunctionSignatureX(
- requiredParameters: parameters,
- requiredParameterCount: parameters.length,
- type: new ResolutionFunctionType(
- constructor, const ResolutionDynamicType(), parameterTypes));
- constructor.functionSignature = constructorSignature;
- enumClass.addMember(constructor, reporter);
-
- List<EnumConstantElement> enumValues = <EnumConstantElement>[];
- int index = 0;
- List<Node> valueReferences = <Node>[];
- List<LiteralMapEntry> mapEntries;
- if (matchKernelRepresentationForTesting) {
- mapEntries = <LiteralMapEntry>[];
- }
- for (Link<Node> link = node.names.nodes; !link.isEmpty; link = link.tail) {
- Identifier name = link.head;
- AstBuilder valueBuilder = new AstBuilder(name.token.charOffset);
- VariableList variableList = new VariableList(
- valueBuilder.modifiers(isStatic: true, isConst: true));
- variableList.type = enumType;
-
- // Add reference for the `values` field.
- valueReferences.add(valueBuilder.reference(name));
-
- Node indexValue = valueBuilder.literalInt(index);
- Node nameValue =
- valueBuilder.literalString('${enumClass.name}.${name.source}');
- Expression initializer;
- if (matchKernelRepresentationForTesting) {
- // Add map entry for `toString` implementation.
- mapEntries.add(valueBuilder.mapLiteralEntry(indexValue, nameValue));
-
- initializer = valueBuilder.newExpression(
- enumClass.name, valueBuilder.argumentList([indexValue]),
- isConst: true);
- } else {
- initializer = valueBuilder.newExpression(
- enumClass.name, valueBuilder.argumentList([indexValue, nameValue]),
- isConst: true);
- }
- SendSet definition = valueBuilder.createDefinition(name, initializer);
-
- EnumConstantElementX field = new EnumConstantElementX(
- name, enumClass, variableList, definition, initializer, index);
- enumValues.add(field);
- enumClass.addMember(field, reporter);
- index++;
- }
-
- VariableList valuesVariableList =
- new VariableList(builder.modifiers(isStatic: true, isConst: true));
- ResolutionInterfaceType valuesType = commonElements.listType(enumType);
- valuesVariableList.type = valuesType;
-
- Identifier valuesIdentifier = builder.identifier('values');
- // TODO(28340): Add type argument.
- Expression initializer =
- builder.listLiteral(valueReferences, isConst: true);
-
- Node definition = builder.createDefinition(valuesIdentifier, initializer);
-
- EnumFieldElementX valuesVariable = new EnumFieldElementX(valuesIdentifier,
- enumClass, valuesVariableList, definition, initializer);
-
- enumClass.addMember(valuesVariable, reporter);
-
- Node toStringValue;
- if (matchKernelRepresentationForTesting) {
- toStringValue = builder.indexGet(
- builder.mapLiteral(mapEntries, isConst: true),
- builder.reference(builder.identifier('index')));
- } else {
- toStringValue = builder.reference(builder.identifier('_name'));
- }
- FunctionExpression toStringNode = builder.functionExpression(
- Modifiers.EMPTY,
- 'toString',
- null, // typeVariables
- builder.argumentList([]),
- builder.returnStatement(toStringValue));
-
- EnumMethodElementX toString = new EnumMethodElementX(
- 'toString', enumClass, Modifiers.EMPTY, toStringNode);
- FunctionSignatureX toStringSignature = new FunctionSignatureX(
- type: new ResolutionFunctionType(toString, stringType));
- toString.functionSignature = toStringSignature;
- enumClass.addMember(toString, reporter);
-
- enumClass.enumValues = enumValues;
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/label_scope.dart b/pkg/compiler/lib/src/resolution/label_scope.dart
deleted file mode 100644
index beb888c..0000000
--- a/pkg/compiler/lib/src/resolution/label_scope.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.label_scope;
-
-import '../elements/jumps.dart';
-import '../util/util.dart' show Link;
-
-abstract class LabelScope {
- LabelScope get outer;
- LabelDefinition lookup(String label);
-}
-
-class LabeledStatementLabelScope implements LabelScope {
- final LabelScope outer;
- final Map<String, LabelDefinition> labels;
- LabeledStatementLabelScope(this.outer, this.labels);
- LabelDefinition lookup(String labelName) {
- LabelDefinition label = labels[labelName];
- if (label != null) return label;
- return outer.lookup(labelName);
- }
-}
-
-class SwitchLabelScope implements LabelScope {
- final LabelScope outer;
- final Map<String, LabelDefinition> caseLabels;
-
- SwitchLabelScope(this.outer, this.caseLabels);
-
- LabelDefinition lookup(String labelName) {
- LabelDefinition result = caseLabels[labelName];
- if (result != null) return result;
- return outer.lookup(labelName);
- }
-}
-
-class EmptyLabelScope implements LabelScope {
- const EmptyLabelScope();
- LabelDefinition lookup(String label) => null;
- LabelScope get outer {
- throw 'internal error: empty label scope has no outer';
- }
-}
-
-class StatementScope {
- LabelScope labels;
- Link<JumpTarget> breakTargetStack;
- Link<JumpTarget> continueTargetStack;
- // Used to provide different numbers to statements if one is inside the other.
- // Can be used to make otherwise duplicate labels unique.
- int nestingLevel = 0;
-
- StatementScope()
- : labels = const EmptyLabelScope(),
- breakTargetStack = const Link<JumpTarget>(),
- continueTargetStack = const Link<JumpTarget>();
-
- LabelDefinition lookupLabel(String label) {
- return labels.lookup(label);
- }
-
- JumpTarget currentBreakTarget() =>
- breakTargetStack.isEmpty ? null : breakTargetStack.head;
-
- JumpTarget currentContinueTarget() =>
- continueTargetStack.isEmpty ? null : continueTargetStack.head;
-
- void enterLabelScope(Map<String, LabelDefinition> elements) {
- labels = new LabeledStatementLabelScope(labels, elements);
- nestingLevel++;
- }
-
- void exitLabelScope() {
- nestingLevel--;
- labels = labels.outer;
- }
-
- void enterLoop(JumpTarget element) {
- breakTargetStack = breakTargetStack.prepend(element);
- continueTargetStack = continueTargetStack.prepend(element);
- nestingLevel++;
- }
-
- void exitLoop() {
- nestingLevel--;
- breakTargetStack = breakTargetStack.tail;
- continueTargetStack = continueTargetStack.tail;
- }
-
- void enterSwitch(
- JumpTarget breakElement, Map<String, LabelDefinition> continueElements) {
- breakTargetStack = breakTargetStack.prepend(breakElement);
- labels = new SwitchLabelScope(labels, continueElements);
- nestingLevel++;
- }
-
- void exitSwitch() {
- nestingLevel--;
- breakTargetStack = breakTargetStack.tail;
- labels = labels.outer;
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/member_impl.dart b/pkg/compiler/lib/src/resolution/member_impl.dart
deleted file mode 100644
index e454c83..0000000
--- a/pkg/compiler/lib/src/resolution/member_impl.dart
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart2js.resolution.compute_members;
-
-class DeclaredMember implements Member {
- final Name name;
- final MemberElement element;
- final ResolutionInterfaceType declarer;
- final ResolutionDartType type;
- final ResolutionFunctionType functionType;
-
- DeclaredMember(
- this.name, this.element, this.declarer, this.type, this.functionType);
-
- bool get isStatic => !element.isInstanceMember;
-
- bool get isGetter => element.isGetter || (!isSetter && element.isField);
-
- bool get isSetter => name.isSetter;
-
- bool get isMethod => element.isFunction;
-
- bool get isDeclaredByField => element.isField;
-
- bool get isAbstract => false;
-
- Member get implementation => this;
-
- /// Returns this member as inherited from [instance].
- ///
- /// For instance:
- /// class A<T> { T m() {} }
- /// class B<S> extends A<S> {}
- /// class C<U> extends B<U> {}
- /// The member `T m()` is declared in `A<T>` and inherited from `A<S>` into
- /// `B` as `S m()`, and further from `B<U>` into `C` as `U m()`.
- DeclaredMember inheritFrom(ResolutionInterfaceType instance) {
- // If the member is declared in a non-generic class its type cannot change
- // as a result of inheritance.
- if (!declarer.isGeneric) return this;
- assert(declarer.element == instance.element);
- return _newInheritedMember(instance);
- }
-
- InheritedMember _newInheritedMember(ResolutionInterfaceType instance) {
- return new InheritedMember(this, instance);
- }
-
- Iterable<Member> get declarations => <Member>[this];
-
- int get hashCode => element.hashCode + 13 * isSetter.hashCode;
-
- bool operator ==(other) {
- if (other is! Member) return false;
- return element == other.element && isSetter == other.isSetter;
- }
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- printOn(sb, type);
- return sb.toString();
- }
-
- void printOn(StringBuffer sb, ResolutionDartType type) {
- if (isStatic) {
- sb.write('static ');
- }
- if (isAbstract) {
- sb.write('abstract ');
- }
- if (isGetter) {
- sb.write(type);
- sb.write(' get ');
- sb.write(name);
- } else if (isSetter) {
- sb.write('void set ');
- sb.write(name.getter);
- sb.write('(');
- sb.write(type);
- sb.write(' _)');
- } else {
- sb.write(type.getStringAsDeclared('$name'));
- }
- }
-}
-
-class DeclaredAbstractMember extends DeclaredMember {
- final DeclaredMember implementation;
-
- DeclaredAbstractMember(
- Name name,
- Element element,
- ResolutionInterfaceType declarer,
- ResolutionDartType type,
- ResolutionFunctionType functionType,
- this.implementation)
- : super(name, element, declarer, type, functionType);
-
- bool get isAbstract => true;
-
- InheritedMember _newInheritedMember(ResolutionInterfaceType instance) {
- return new InheritedAbstractMember(this, instance,
- implementation != null ? implementation.inheritFrom(instance) : null);
- }
-}
-
-class InheritedMember implements DeclaredMember {
- final DeclaredMember declaration;
- final ResolutionInterfaceType instance;
-
- InheritedMember(
- DeclaredMember this.declaration, ResolutionInterfaceType this.instance) {
- assert(instance.isGeneric);
- assert(!declaration.isStatic);
- }
-
- MemberElement get element => declaration.element;
-
- Name get name => declaration.name;
-
- ResolutionInterfaceType get declarer => instance;
-
- bool get isStatic => false;
-
- bool get isSetter => declaration.isSetter;
-
- bool get isGetter => declaration.isGetter;
-
- bool get isMethod => declaration.isMethod;
-
- bool get isDeclaredByField => declaration.isDeclaredByField;
-
- bool get isAbstract => false;
-
- Member get implementation => this;
-
- ResolutionDartType get type => declaration.type.substByContext(instance);
-
- ResolutionFunctionType get functionType {
- return declaration.functionType.substByContext(instance);
- }
-
- DeclaredMember inheritFrom(ResolutionInterfaceType newInstance) {
- assert(() {
- // Assert that if [instance] contains type variables, then these are
- // defined in the declaration of [newInstance] and will therefore be
- // substituted into the context of [newInstance] in the created member.
- ClassElement contextClass = DartTypes.getClassContext(instance);
- return contextClass == null || contextClass == newInstance.element;
- }(),
- failedAt(
- declaration.element,
- "Context mismatch: Context class "
- "${DartTypes.getClassContext(instance)} from $instance does match "
- "the new instance $newInstance."));
- return _newInheritedMember(newInstance);
- }
-
- InheritedMember _newInheritedMember(ResolutionInterfaceType newInstance) {
- return new InheritedMember(
- declaration, instance.substByContext(newInstance));
- }
-
- Iterable<Member> get declarations => <Member>[this];
-
- int get hashCode => declaration.hashCode + 17 * instance.hashCode;
-
- bool operator ==(other) {
- if (other is! InheritedMember) return false;
- return declaration == other.declaration && instance == other.instance;
- }
-
- void printOn(StringBuffer sb, ResolutionDartType type) {
- declaration.printOn(sb, type);
- sb.write(' inherited from $instance');
- }
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- printOn(sb, type);
- return sb.toString();
- }
-}
-
-class InheritedAbstractMember extends InheritedMember {
- final DeclaredMember implementation;
-
- InheritedAbstractMember(DeclaredMember declaration,
- ResolutionInterfaceType instance, this.implementation)
- : super(declaration, instance);
-
- bool get isAbstract => true;
-
- InheritedMember _newInheritedMember(ResolutionInterfaceType newInstance) {
- return new InheritedAbstractMember(
- declaration,
- instance.substByContext(newInstance),
- implementation != null
- ? implementation.inheritFrom(newInstance)
- : null);
- }
-}
-
-abstract class AbstractSyntheticMember implements MemberSignature {
- final Setlet<Member> inheritedMembers;
-
- AbstractSyntheticMember(this.inheritedMembers);
-
- Member get member => inheritedMembers.first;
-
- Iterable<Member> get declarations => inheritedMembers;
-
- Name get name => member.name;
-}
-
-class SyntheticMember extends AbstractSyntheticMember {
- final ResolutionDartType type;
- final ResolutionFunctionType functionType;
-
- SyntheticMember(Setlet<Member> inheritedMembers, this.type, this.functionType)
- : super(inheritedMembers);
-
- bool get isSetter => member.isSetter;
-
- bool get isGetter => member.isGetter;
-
- bool get isMethod => member.isMethod;
-
- bool get isMalformed => false;
-
- String toString() => '${type.getStringAsDeclared('$name')} synthesized '
- 'from ${inheritedMembers}';
-}
-
-class ErroneousMember extends AbstractSyntheticMember {
- ErroneousMember(Setlet<Member> inheritedMembers) : super(inheritedMembers);
-
- ResolutionDartType get type => functionType;
-
- ResolutionFunctionType get functionType {
- throw new UnsupportedError('Erroneous members have no type.');
- }
-
- bool get isSetter => false;
-
- bool get isGetter => false;
-
- bool get isMethod => false;
-
- bool get isMalformed => true;
-
- String toString() => "erroneous member '$name' synthesized "
- "from ${inheritedMembers}";
-}
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
deleted file mode 100644
index abda55c..0000000
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ /dev/null
@@ -1,4836 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.members;
-
-import 'package:front_end/src/fasta/scanner.dart' show isUserDefinableOperator;
-
-import '../common.dart';
-import '../common/names.dart' show Selectors;
-import '../common/resolution.dart' show Resolution;
-import '../compile_time_constants.dart';
-import '../constants/constructors.dart'
- show RedirectingFactoryConstantConstructor;
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../common_elements.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../elements/modelx.dart'
- show
- ConstructorElementX,
- ErroneousElementX,
- FunctionElementX,
- JumpTargetX,
- LabelDefinitionX,
- LocalFunctionElementX,
- LocalParameterElementX,
- ParameterElementX,
- VariableElementX,
- VariableList;
-import '../elements/jumps.dart';
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../options.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../universe/selector.dart' show Selector;
-import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
-import '../util/util.dart' show Link;
-import 'access_semantics.dart';
-import 'class_members.dart' show MembersCreator;
-import 'constructors.dart'
- show ConstructorResolver, ConstructorResult, ConstructorResultKind;
-import 'label_scope.dart' show StatementScope;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution.dart' show ResolverTask;
-import 'resolution_common.dart' show MappingVisitor;
-import 'resolution_result.dart';
-import 'scope.dart' show BlockScope, MethodScope, Scope;
-import 'send_structure.dart';
-import 'signatures.dart' show SignatureResolver;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-import 'variables.dart' show VariableDefinitionsVisitor;
-
-/// The state of constants in resolutions.
-enum ConstantState {
- /// Expressions are not required to be constants.
- NON_CONSTANT,
-
- /// Expressions are required to be constants.
- ///
- /// For instance the values of a constant list literal.
- CONSTANT,
-
- /// Expressions are required to be constants and parameter references are
- /// also considered constant.
- ///
- /// This is used for resolving constructor initializers of constant
- /// constructors.
- CONSTANT_INITIALIZER,
-}
-
-/**
- * Core implementation of resolution.
- *
- * Do not subclass or instantiate this class outside this library
- * except for testing.
- */
-class ResolverVisitor extends MappingVisitor<ResolutionResult> {
- /**
- * The current enclosing element for the visited AST nodes.
- *
- * This field is updated when nested closures are visited.
- */
- Element enclosingElement;
-
- /// Whether we are in a context where `this` is accessible (this will be false
- /// in static contexts, factory methods, and field initializers).
- bool inInstanceContext;
- bool inCheckContext;
- bool inCatchParameters = false;
- bool inCatchBlock;
- ConstantState constantState;
-
- Scope scope;
- ClassElement currentClass;
- ExpressionStatement currentExpressionStatement;
-
- /// `true` if a [Send] or [SendSet] is visited as the prefix of member access.
- /// For instance `Class` in `Class.staticField` or `prefix.Class` in
- /// `prefix.Class.staticMethod()`.
- bool sendIsMemberAccess = false;
-
- StatementScope statementScope;
- int allowedCategory = ElementCategory.VARIABLE |
- ElementCategory.FUNCTION |
- ElementCategory.IMPLIES_TYPE;
-
- /// 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 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.
- Link<Node> promotionScope = const Link<Node>();
-
- bool isPotentiallyMutableTarget(Element target) {
- if (target == null) return false;
- return (target.isVariable || target.isRegularParameter) &&
- !(target.isFinal || target.isConst);
- }
-
- // TODO(ahe): Find a way to share this with runtime implementation.
- static final RegExp symbolValidationPattern =
- new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
- r'-|'
- r'unary-|'
- r'\[\]=|'
- r'~|'
- r'==|'
- r'\[\]|'
- r'\*|'
- r'/|'
- r'%|'
- r'~/|'
- r'\+|'
- r'<<|'
- r'>>|'
- r'>=|'
- r'>|'
- r'<=|'
- r'<|'
- r'&|'
- r'\^|'
- r'\|'
- r')$');
-
- ResolverVisitor(
- Resolution resolution, Element element, ResolutionRegistry registry,
- {Scope scope, bool useEnclosingScope: false})
- : this.enclosingElement = element,
- // When the element is a field, we are actually resolving its
- // initial value, which should not have access to instance
- // fields.
- inInstanceContext = (element.isInstanceMember && !element.isField) ||
- element.isGenerativeConstructor,
- this.currentClass =
- element.isClassMember ? element.enclosingClass : null,
- this.statementScope = new StatementScope(),
- this.scope = scope ??
- (useEnclosingScope
- ? Scope.buildEnclosingScope(element)
- : element.buildScope()),
- // The type annotations on a typedef do not imply type checks.
- // TODO(karlklose): clean this up (dartbug.com/8870).
- inCheckContext = resolution.options.enableTypeAssertions &&
- !element.isLibrary &&
- !element.isTypedef &&
- !element.enclosingElement.isTypedef,
- inCatchBlock = false,
- constantState = element.isConst
- ? ConstantState.CONSTANT
- : ConstantState.NON_CONSTANT,
- super(resolution, registry);
-
- CommonElements get commonElements => resolution.commonElements;
- ConstantEnvironment get constants => resolution.constants;
- ResolverTask get resolver => resolution.resolver;
- CompilerOptions get options => resolution.options;
-
- AsyncMarker get currentAsyncMarker {
- if (enclosingElement is FunctionElement) {
- FunctionElement function = enclosingElement;
- return function.asyncMarker;
- }
- return AsyncMarker.SYNC;
- }
-
- Element reportLookupErrorIfAny(Element result, Node node, String name) {
- if (!Elements.isUnresolved(result)) {
- if (!inInstanceContext && result.isInstanceMember) {
- reporter.reportErrorMessage(
- node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
- return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE,
- {'name': name}, name, enclosingElement);
- } else if (result.isAmbiguous) {
- AmbiguousElement ambiguous = result;
- return reportAndCreateErroneousElement(
- node, name, ambiguous.messageKind, ambiguous.messageArguments,
- infos: ambiguous.computeInfos(enclosingElement, reporter),
- isError: true);
- }
- }
- return result;
- }
-
- // Create, or reuse an already created, target element for a statement.
- JumpTarget getOrDefineTarget(Node statement) {
- JumpTarget element = registry.getTargetDefinition(statement);
- if (element == null) {
- element = new JumpTargetX(
- statement, statementScope.nestingLevel, enclosingElement);
- registry.defineTarget(statement, element);
- }
- return element;
- }
-
- doInPromotionScope(Node node, action()) {
- promotionScope = promotionScope.prepend(node);
- var result = action();
- promotionScope = promotionScope.tail;
- return result;
- }
-
- inStaticContext(action(), {bool inConstantInitializer: false}) {
- bool wasInstanceContext = inInstanceContext;
- ConstantState oldConstantState = constantState;
- constantState = inConstantInitializer
- ? ConstantState.CONSTANT_INITIALIZER
- : constantState;
- inInstanceContext = false;
- var result = action();
- inInstanceContext = wasInstanceContext;
- constantState = oldConstantState;
- return result;
- }
-
- ResolutionResult visitInStaticContext(Node node,
- {bool inConstantInitializer: false}) {
- return inStaticContext(() => visit(node),
- inConstantInitializer: inConstantInitializer);
- }
-
- /// Execute [action] where the constant state is `ConstantState.CONSTANT` if
- /// not already `ConstantState.CONSTANT_INITIALIZER`.
- inConstantContext(action()) {
- ConstantState oldConstantState = constantState;
- if (constantState != ConstantState.CONSTANT_INITIALIZER) {
- constantState = ConstantState.CONSTANT;
- }
- var result = action();
- constantState = oldConstantState;
- return result;
- }
-
- /// Visit [node] where the constant state is `ConstantState.CONSTANT` if
- /// not already `ConstantState.CONSTANT_INITIALIZER`.
- ResolutionResult visitInConstantContext(Node node) {
- ResolutionResult result = inConstantContext(() => visit(node));
- assert(result != null, failedAt(node, "No resolution result for $node."));
-
- return result;
- }
-
- ErroneousElement reportAndCreateErroneousElement(
- Node node, String name, MessageKind kind, Map arguments,
- {List<DiagnosticMessage> infos: const <DiagnosticMessage>[],
- bool isError: false}) {
- if (isError) {
- reporter.reportError(
- reporter.createMessage(node, kind, arguments), infos);
- } else {
- reporter.reportWarning(
- reporter.createMessage(node, kind, arguments), infos);
- }
- // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass
- // of [ErroneousElementX]. For example, [ErroneousFieldElementX],
- // [ErroneousConstructorElementX], etc.
- return new ErroneousElementX(kind, arguments, name, enclosingElement);
- }
-
- /// Report a warning or error on an unresolved access in non-instance context.
- ///
- /// The [ErroneousElement] corresponding to the message is returned.
- ErroneousElement reportCannotResolve(Node node, String name) {
- assert(
- !inInstanceContext,
- failedAt(
- node,
- "ResolverVisitor.reportCannotResolve must not be called in "
- "instance context."));
-
- // We report an error within initializers because `this` is implicitly
- // accessed when unqualified identifiers are not resolved. For
- // details, see section 16.14.3 of the spec (2nd edition):
- // An unqualified invocation `i` of the form `id(a1, ...)`
- // ...
- // If `i` does not occur inside a top level or static function, `i`
- // is equivalent to `this.id(a1 , ...)`.
- bool inInitializer = enclosingElement.isGenerativeConstructor ||
- (enclosingElement.isInstanceMember && enclosingElement.isField);
- MessageKind kind;
- Map arguments = {'name': name};
- if (inInitializer) {
- kind = MessageKind.CANNOT_RESOLVE_IN_INITIALIZER;
- } else if (name == 'await') {
- var functionName = enclosingElement.name;
- if (functionName == '') {
- kind = MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE;
- } else {
- kind = MessageKind.CANNOT_RESOLVE_AWAIT;
- arguments['functionName'] = functionName;
- }
- } else {
- kind = MessageKind.CANNOT_RESOLVE;
- }
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- return reportAndCreateErroneousElement(node, name, kind, arguments,
- isError: inInitializer);
- }
-
- ResolutionResult visitIdentifier(Identifier node) {
- if (node.isThis()) {
- if (!inInstanceContext) {
- reporter.reportErrorMessage(
- node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node});
- }
- return const NoneResult();
- } else if (node.isSuper()) {
- if (!inInstanceContext) {
- reporter.reportErrorMessage(node, MessageKind.NO_SUPER_IN_STATIC);
- }
- if ((ElementCategory.SUPER & allowedCategory) == 0) {
- reporter.reportErrorMessage(node, MessageKind.INVALID_USE_OF_SUPER);
- }
- return const NoneResult();
- } else {
- String name = node.source;
- Element element = lookupInScope(reporter, node, scope, name);
- if (Elements.isUnresolved(element) && name == 'dynamic') {
- // TODO(johnniwinther): Remove this hack when we can return more complex
- // objects than [Element] from this method.
- ClassElement typeClass = commonElements.typeClass;
- element = typeClass;
- // Set the type to be `dynamic` to mark that this is a type literal.
- registry.setType(node, const ResolutionDynamicType());
- }
- element = reportLookupErrorIfAny(element, node, name);
- if (element == null) {
- if (!inInstanceContext) {
- element = reportCannotResolve(node, name);
- }
- } else if (element.isMalformed) {
- // Use the malformed element.
- } else {
- if ((element.kind.category & allowedCategory) == 0) {
- element =
- reportAndCreateErroneousElement(node, name, MessageKind.GENERIC,
- // TODO(ahe): Improve error message. Need UX input.
- {'text': "is not an expression $element"});
- }
- }
- if (!Elements.isUnresolved(element) && element.isClass) {
- ClassElement classElement = element;
- classElement.ensureResolved(resolution);
- }
- if (element != null) {
- registry.useElement(node, element);
- if (element.isPrefix) {
- return new PrefixResult(element, null);
- } else if (element.isClass && sendIsMemberAccess) {
- return new PrefixResult(null, element);
- }
- return new ElementResult(element);
- }
- return const NoneResult();
- }
- }
-
- TypeResult visitTypeAnnotation(TypeAnnotation node) {
- return new TypeResult(resolveTypeAnnotation(node));
- }
-
- bool isNamedConstructor(Send node) => node.receiver != null;
-
- Name getRedirectingThisOrSuperConstructorName(Send node) {
- if (isNamedConstructor(node)) {
- String constructorName = node.selector.asIdentifier().source;
- return new Name(constructorName, enclosingElement.library);
- } else {
- return const PublicName('');
- }
- }
-
- FunctionElement resolveConstructorRedirection(FunctionElementX constructor) {
- FunctionExpression node = constructor.parseNode(resolution.parsingContext);
-
- // A synthetic constructor does not have a node.
- if (node == null) return null;
- if (node.initializers == null) return null;
- Link<Node> initializers = node.initializers.nodes;
- if (!initializers.isEmpty &&
- Initializers.isConstructorRedirect(initializers.head)) {
- Name name = getRedirectingThisOrSuperConstructorName(initializers.head);
- final ClassElement classElement = constructor.enclosingClass;
- return classElement.lookupConstructor(name.text);
- }
- return null;
- }
-
- void setupFunction(FunctionExpression node, FunctionElement function) {
- Element enclosingElement = function.enclosingElement;
- if (node.modifiers.isStatic && enclosingElement.kind != ElementKind.CLASS) {
- reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC);
- }
- FunctionSignature functionSignature = function.functionSignature;
-
- // Create the scope where the type variables are introduced, if any.
- scope = new MethodScope(scope, function);
- functionSignature.typeVariables
- .forEach((ResolutionDartType type) => addToScope(type.element));
-
- // Create the scope for the function body, and put the parameters in scope.
- scope = new BlockScope(scope);
- Link<Node> parameterNodes =
- (node.parameters == null) ? const Link<Node>() : node.parameters.nodes;
- functionSignature.forEachParameter((_element) {
- ParameterElementX element = _element;
- // TODO(karlklose): should be a list of [FormalElement]s, but the actual
- // implementation uses [Element].
- List<Element> optionals = functionSignature.optionalParameters;
- if (!optionals.isEmpty && element == optionals.first) {
- NodeList nodes = parameterNodes.head;
- parameterNodes = nodes.nodes;
- }
- if (element.isOptional) {
- if (element.initializer != null) {
- ResolutionResult result = visitInConstantContext(element.initializer);
- if (result.isConstant) {
- element.constant = result.constant;
- }
- } else {
- registry.registerConstantLiteral(
- element.constant = new NullConstantExpression());
- }
- }
- VariableDefinitions variableDefinitions = parameterNodes.head;
- Node parameterNode = variableDefinitions.definitions.nodes.head;
- // Field parameters (this.x) are not visible inside the constructor. The
- // fields they reference are visible, but must be resolved independently.
- if (element.isInitializingFormal) {
- registry.useElement(parameterNode, element);
- } else {
- LocalParameterElementX parameterElement = element;
- defineLocalVariable(parameterNode, parameterElement);
- addToScope(parameterElement);
- }
- parameterNodes = parameterNodes.tail;
- });
- addDeferredAction(enclosingElement, () {
- functionSignature.forEachOptionalParameter((_parameter) {
- ParameterElementX parameter = _parameter;
- parameter.constant =
- resolver.constantCompiler.compileConstant(parameter);
- });
- });
- registry.registerCheckedModeCheck(functionSignature.returnType);
- functionSignature.forEachParameter((_element) {
- ParameterElement element = _element;
- registry.registerCheckedModeCheck(element.type);
- });
- }
-
- ResolutionResult visitAssert(Assert node) {
- // TODO(sra): We could completely ignore the assert in production mode if we
- // didn't need it to be resolved for type checking.
- registry.registerFeature(
- node.hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
- visit(node.condition);
- visit(node.message);
- return const NoneResult();
- }
-
- ResolutionResult visitCascade(Cascade node) {
- visit(node.expression);
- return const NoneResult();
- }
-
- ResolutionResult visitCascadeReceiver(CascadeReceiver node) {
- visit(node.expression);
- return const NoneResult();
- }
-
- ResolutionResult visitIn(Node node, Scope nestedScope) {
- Scope oldScope = scope;
- scope = nestedScope;
- ResolutionResult result = visit(node);
- scope = oldScope;
- return result;
- }
-
- /**
- * Introduces new default targets for break and continue
- * before visiting the body of the loop
- */
- void visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) {
- JumpTarget element = getOrDefineTarget(loop);
- statementScope.enterLoop(element);
- visitIn(body, bodyScope);
- statementScope.exitLoop();
- if (!element.isTarget) {
- registry.undefineTarget(loop);
- }
- }
-
- ResolutionResult visitBlock(Block node) {
- visitIn(node.statements, new BlockScope(scope));
- return const NoneResult();
- }
-
- ResolutionResult visitDoWhile(DoWhile node) {
- visitLoopBodyIn(node, node.body, new BlockScope(scope));
- visit(node.condition);
- return const NoneResult();
- }
-
- ResolutionResult visitEmptyStatement(EmptyStatement node) {
- return const NoneResult();
- }
-
- ResolutionResult visitExpressionStatement(ExpressionStatement node) {
- ExpressionStatement oldExpressionStatement = currentExpressionStatement;
- currentExpressionStatement = node;
- visit(node.expression);
- currentExpressionStatement = oldExpressionStatement;
- return const NoneResult();
- }
-
- ResolutionResult visitFor(For node) {
- Scope blockScope = new BlockScope(scope);
- visitIn(node.initializer, blockScope);
- visitIn(node.condition, blockScope);
- visitIn(node.update, blockScope);
- visitLoopBodyIn(node, node.body, blockScope);
- return const NoneResult();
- }
-
- ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) {
- assert(node.function.name != null);
- visitFunctionExpression(node.function, inFunctionDeclaration: true);
- return const NoneResult();
- }
-
- /// Process a local function declaration or an anonymous function expression.
- ///
- /// [inFunctionDeclaration] is `true` when the current node is the immediate
- /// child of a function declaration.
- ///
- /// This is used to distinguish local function declarations from anonymous
- /// function expressions.
- ResolutionResult visitFunctionExpression(FunctionExpression node,
- {bool inFunctionDeclaration: false}) {
- bool doAddToScope = inFunctionDeclaration;
- if (!inFunctionDeclaration && node.name != null) {
- reporter.reportErrorMessage(node.name,
- MessageKind.NAMED_FUNCTION_EXPRESSION, {'name': node.name});
- }
- String name;
- if (node.name == null) {
- name = "";
- } else {
- name = node.name.asIdentifier().source;
- }
- LocalFunctionElementX function = new LocalFunctionElementX(
- name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement);
- ResolverTask.processAsyncMarker(resolution, function, registry);
- function.functionSignature = SignatureResolver.analyze(
- resolution,
- scope,
- const FunctionTypeParameterScope(),
- node.typeVariables,
- node.parameters,
- node.returnType,
- function,
- registry,
- createRealParameters: true,
- isFunctionExpression: !inFunctionDeclaration);
- checkLocalDefinitionName(node, function);
- registry.defineFunction(node, function);
- if (doAddToScope) {
- addToScope(function);
- }
- Scope oldScope = scope; // The scope is modified by [setupFunction].
- setupFunction(node, function);
-
- Element previousEnclosingElement = enclosingElement;
- enclosingElement = function;
- // Run the body in a fresh statement scope.
- StatementScope oldStatementScope = statementScope;
- statementScope = new StatementScope();
- visit(node.body);
- statementScope = oldStatementScope;
-
- scope = oldScope;
- enclosingElement = previousEnclosingElement;
-
- registry.registerStaticUse(new StaticUse.closure(function));
- return const NoneResult();
- }
-
- ResolutionResult visitIf(If node) {
- doInPromotionScope(node.condition.expression, () => visit(node.condition));
- doInPromotionScope(
- node.thenPart, () => visitIn(node.thenPart, new BlockScope(scope)));
- visitIn(node.elsePart, new BlockScope(scope));
- return const NoneResult();
- }
-
- static Selector computeSendSelector(
- Send node, LibraryElement library, Element element) {
- // First determine if this is part of an assignment.
- bool isSet = node.asSendSet() != null;
-
- if (node.isIndex) {
- return isSet ? new Selector.indexSet() : new Selector.index();
- }
-
- if (node.isOperator) {
- String source = node.selector.asOperator().source;
- String string = source;
- if (identical(string, '!') ||
- identical(string, '&&') ||
- identical(string, '||') ||
- identical(string, 'is') ||
- identical(string, 'as') ||
- identical(string, '?') ||
- identical(string, '??')) {
- return null;
- }
- String op = source;
- if (!isUserDefinableOperator(source)) {
- op = Elements.mapToUserOperatorOrNull(source);
- }
- if (op == null) {
- // Unsupported operator. An error has been reported during parsing.
- return new Selector.call(new Name(source, library),
- new CallStructure.unnamed(node.argumentsNode.slowLength()));
- }
- return node.arguments.isEmpty
- ? new Selector.unaryOperator(op)
- : new Selector.binaryOperator(op);
- }
-
- Identifier identifier = node.selector.asIdentifier();
- if (node.isPropertyAccess) {
- assert(!isSet);
- return new Selector.getter(new Name(identifier.source, library));
- } else if (isSet) {
- return new Selector.setter(
- new Name(identifier.source, library, isSetter: true));
- }
-
- // Compute the arity and the list of named arguments.
- int arity = 0;
- List<String> named = <String>[];
- for (Link<Node> link = node.argumentsNode.nodes;
- !link.isEmpty;
- link = link.tail) {
- Expression argument = link.head;
- NamedArgument namedArgument = argument.asNamedArgument();
- if (namedArgument != null) {
- named.add(namedArgument.name.source);
- }
- arity++;
- }
-
- if (element != null && element.isConstructor) {
- return new Selector.callConstructor(
- new Name(element.name, library), arity, named);
- }
-
- // If we're invoking a closure, we do not have an identifier.
- return (identifier == null)
- ? new Selector.callClosure(arity, named)
- : new Selector.call(new Name(identifier.source, library),
- new CallStructure(arity, named));
- }
-
- Selector resolveSelector(Send node, Element element) {
- LibraryElement library = enclosingElement.library;
- Selector selector = computeSendSelector(node, library, element);
- if (selector != null) registry.setSelector(node, selector);
- return selector;
- }
-
- ArgumentsResult resolveArguments(NodeList list) {
- if (list == null) return null;
- bool isValidAsConstant = true;
- List<ResolutionResult> argumentResults = <ResolutionResult>[];
- bool oldSendIsMemberAccess = sendIsMemberAccess;
- sendIsMemberAccess = false;
- Map<String, Node> seenNamedArguments = new Map<String, Node>();
- int argumentCount = 0;
- List<String> namedArguments = <String>[];
- for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) {
- Expression argument = link.head;
- ResolutionResult result = visit(argument);
- if (!result.isConstant) {
- isValidAsConstant = false;
- }
- argumentResults.add(result);
-
- NamedArgument namedArgument = argument.asNamedArgument();
- if (namedArgument != null) {
- String source = namedArgument.name.source;
- namedArguments.add(source);
- if (seenNamedArguments.containsKey(source)) {
- reportDuplicateDefinition(
- source, argument, seenNamedArguments[source]);
- isValidAsConstant = false;
- } else {
- seenNamedArguments[source] = namedArgument;
- }
- } else if (!seenNamedArguments.isEmpty) {
- reporter.reportErrorMessage(
- argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED);
- isValidAsConstant = false;
- }
- argumentCount++;
- }
- sendIsMemberAccess = oldSendIsMemberAccess;
- return new ArgumentsResult(
- new CallStructure(argumentCount, namedArguments), argumentResults,
- isValidAsConstant: isValidAsConstant);
- }
-
- /// Check that access to `super` is currently allowed. Returns an
- /// [AccessSemantics] in case of an error, `null` otherwise.
- AccessSemantics checkSuperAccess(Send node) {
- if (!inInstanceContext) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node, 'super', MessageKind.NO_SUPER_IN_STATIC, {},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- return new StaticAccess.invalid(error);
- }
- if (node.isConditional) {
- // `super?.foo` is not allowed.
- ErroneousElement error = reportAndCreateErroneousElement(
- node, 'super', MessageKind.INVALID_USE_OF_SUPER, {},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- return new StaticAccess.invalid(error);
- }
- if (currentClass.supertype == null) {
- // This is just to guard against internal errors, so no need
- // for a real error message.
- ErroneousElement error = reportAndCreateErroneousElement(node, 'super',
- MessageKind.GENERIC, {'text': "Object has no superclass"},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- return new StaticAccess.invalid(error);
- }
- registry.registerSuperUse(reporter.spanFromSpannable(node));
- return null;
- }
-
- /// Check that access to `this` is currently allowed. Returns an
- /// [AccessSemantics] in case of an error, `null` otherwise.
- AccessSemantics checkThisAccess(Send node) {
- if (!inInstanceContext) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node, 'this', MessageKind.NO_THIS_AVAILABLE, const {},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- return new StaticAccess.invalid(error);
- }
- return null;
- }
-
- /// Compute the [AccessSemantics] corresponding to a super access of [target].
- AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) {
- if (target.isMalformed) {
- return new StaticAccess.unresolvedSuper(target);
- } else if (target.isGetter) {
- return new StaticAccess.superGetter(target);
- } else if (target.isSetter) {
- return new StaticAccess.superSetter(target);
- } else if (target.isField) {
- if (target.isFinal) {
- return new StaticAccess.superFinalField(target);
- } else {
- return new StaticAccess.superField(target);
- }
- } else {
- assert(target.isFunction,
- failedAt(node, "Unexpected super target '$target'."));
- return new StaticAccess.superMethod(target);
- }
- }
-
- /// Compute the [AccessSemantics] corresponding to a compound super access
- /// reading from [getter] and writing to [setter].
- AccessSemantics computeCompoundSuperAccessSemantics(
- Spannable node, Element getter, Element setter,
- {bool isIndex: false}) {
- if (getter.isMalformed) {
- if (setter.isMalformed) {
- return new StaticAccess.unresolvedSuper(getter);
- } else if (setter.isFunction) {
- assert(setter.name == '[]=',
- failedAt(node, "Unexpected super setter '$setter'."));
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
- } else {
- assert(setter.isSetter,
- failedAt(node, "Unexpected super setter '$setter'."));
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
- }
- } else if (getter.isField) {
- if (setter.isMalformed) {
- assert(
- getter.isFinal,
- failedAt(node,
- "Unexpected super setter '$setter' for getter '$getter."));
- return new StaticAccess.superFinalField(getter);
- } else if (setter.isField) {
- if (getter == setter) {
- return new StaticAccess.superField(getter);
- } else {
- return new CompoundAccessSemantics(
- CompoundAccessKind.SUPER_FIELD_FIELD, getter, setter);
- }
- } else {
- // Either the field is accessible directly, or a setter shadows the
- // setter access. If there was another instance member it would shadow
- // the field.
- assert(setter.isSetter,
- failedAt(node, "Unexpected super setter '$setter'."));
- return new CompoundAccessSemantics(
- CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter);
- }
- } else if (getter.isGetter) {
- if (setter.isMalformed) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
- } else if (setter.isField) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter);
- } else {
- assert(setter.isSetter,
- failedAt(node, "Unexpected super setter '$setter'."));
- return new CompoundAccessSemantics(
- CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
- }
- } else {
- assert(getter.isFunction,
- failedAt(node, "Unexpected super getter '$getter'."));
- if (setter.isMalformed) {
- if (isIndex) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
- } else {
- return new StaticAccess.superMethod(getter);
- }
- } else if (setter.isFunction) {
- assert(setter.name == '[]=',
- failedAt(node, "Unexpected super setter '$setter'."));
- assert(getter.name == '[]',
- failedAt(node, "Unexpected super getter '$getter'."));
- return new CompoundAccessSemantics(
- CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
- } else {
- assert(setter.isSetter,
- failedAt(node, "Unexpected super setter '$setter'."));
- return new CompoundAccessSemantics(
- CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter);
- }
- }
- }
-
- /// Compute the [AccessSemantics] corresponding to a local access of [target].
- AccessSemantics computeLocalAccessSemantics(
- Spannable node, LocalElement target) {
- if (target.isRegularParameter) {
- if (target.isFinal || target.isConst) {
- return new StaticAccess.finalParameter(target);
- } else {
- return new StaticAccess.parameter(target);
- }
- } else if (target.isInitializingFormal) {
- return new StaticAccess.finalParameter(target);
- } else if (target.isVariable) {
- if (target.isFinal || target.isConst) {
- return new StaticAccess.finalLocalVariable(target);
- } else {
- return new StaticAccess.localVariable(target);
- }
- } else {
- assert(target.isFunction,
- failedAt(node, "Unexpected local target '$target'."));
- return new StaticAccess.localFunction(target);
- }
- }
-
- /// Compute the [AccessSemantics] corresponding to a static or toplevel access
- /// of [target].
- AccessSemantics computeStaticOrTopLevelAccessSemantics(
- Spannable node, Element target) {
- target = target.declaration;
- if (target.isMalformed) {
- // This handles elements with parser errors.
- return new StaticAccess.unresolved(target);
- }
- if (target.isStatic) {
- if (target.isGetter) {
- return new StaticAccess.staticGetter(target);
- } else if (target.isSetter) {
- return new StaticAccess.staticSetter(target);
- } else if (target.isField) {
- if (target.isFinal || target.isConst) {
- return new StaticAccess.finalStaticField(target);
- } else {
- return new StaticAccess.staticField(target);
- }
- } else {
- assert(target.isFunction,
- failedAt(node, "Unexpected static target '$target'."));
- return new StaticAccess.staticMethod(target);
- }
- } else {
- assert(target.isTopLevel,
- failedAt(node, "Unexpected statically resolved target '$target'."));
- if (target.isGetter) {
- return new StaticAccess.topLevelGetter(target);
- } else if (target.isSetter) {
- return new StaticAccess.topLevelSetter(target);
- } else if (target.isField) {
- if (target.isFinal) {
- return new StaticAccess.finalTopLevelField(target);
- } else {
- return new StaticAccess.topLevelField(target);
- }
- } else {
- assert(target.isFunction,
- failedAt(node, "Unexpected top level target '$target'."));
- return new StaticAccess.topLevelMethod(target);
- }
- }
- }
-
- /// Compute the [AccessSemantics] for accessing the name of [selector] on the
- /// super class.
- ///
- /// If no matching super member is found and error is reported and
- /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
- /// is provided, the [AccessSemantics] corresponding to the alternate name is
- /// returned. For instance, the access of a super setter for an unresolved
- /// getter:
- ///
- /// class Super {
- /// set name(_) {}
- /// }
- /// class Sub extends Super {
- /// foo => super.name; // Access to the setter.
- /// }
- ///
- AccessSemantics computeSuperAccessSemanticsForSelector(
- Spannable node, Selector selector,
- {Name alternateName}) {
- Name name = selector.memberName;
- // TODO(johnniwinther): Ensure correct behavior if currentClass is a
- // patch.
- Element target = currentClass.lookupSuperByName(name);
- // [target] may be null which means invoking noSuchMethod on super.
- if (target == null) {
- if (alternateName != null) {
- target = currentClass.lookupSuperByName(alternateName);
- }
- Element error;
- if (selector.isSetter) {
- error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.UNDEFINED_SUPER_SETTER,
- {'className': currentClass.name, 'memberName': name});
- } else {
- error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.NO_SUCH_SUPER_MEMBER,
- {'className': currentClass.name, 'memberName': name});
- }
- if (target == null) {
- // If a setter wasn't resolved, use the [ErroneousElement].
- target = error;
- }
- // We still need to register the invocation, because we might
- // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
- registry.registerDynamicUse(new DynamicUse(selector));
- registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
- }
- return computeSuperAccessSemantics(node, target);
- }
-
- /// Compute the [AccessSemantics] for accessing the name of [selector] on the
- /// super class.
- ///
- /// If no matching super member is found and error is reported and
- /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
- /// is provided, the [AccessSemantics] corresponding to the alternate name is
- /// returned. For instance, the access of a super setter for an unresolved
- /// getter:
- ///
- /// class Super {
- /// set name(_) {}
- /// }
- /// class Sub extends Super {
- /// foo => super.name; // Access to the setter.
- /// }
- ///
- AccessSemantics computeSuperAccessSemanticsForSelectors(
- Spannable node, Selector getterSelector, Selector setterSelector,
- {bool isIndex: false}) {
- bool getterError = false;
- bool setterError = false;
-
- // TODO(johnniwinther): Ensure correct behavior if currentClass is a
- // patch.
- Element getter = currentClass.lookupSuperByName(getterSelector.memberName);
- // [target] may be null which means invoking noSuchMethod on super.
- if (getter == null) {
- getter = reportAndCreateErroneousElement(
- node,
- getterSelector.name,
- MessageKind.NO_SUCH_SUPER_MEMBER,
- {'className': currentClass.name, 'memberName': getterSelector.name});
- getterError = true;
- }
- Element setter = currentClass.lookupSuperByName(setterSelector.memberName);
- // [target] may be null which means invoking noSuchMethod on super.
- if (setter == null) {
- setter = reportAndCreateErroneousElement(
- node,
- setterSelector.name,
- MessageKind.NO_SUCH_SUPER_MEMBER,
- {'className': currentClass.name, 'memberName': setterSelector.name});
- setterError = true;
- } else if (getter == setter) {
- if (setter.isFunction) {
- setter = reportAndCreateErroneousElement(
- node, setterSelector.name, MessageKind.ASSIGNING_METHOD_IN_SUPER, {
- 'superclassName': setter.enclosingClass.name,
- 'name': setterSelector.name
- });
- setterError = true;
- } else if (setter.isField && setter.isFinal) {
- setter = reportAndCreateErroneousElement(node, setterSelector.name,
- MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, {
- 'superclassName': setter.enclosingClass.name,
- 'name': setterSelector.name
- });
- setterError = true;
- }
- }
- if (getterError) {
- // We still need to register the invocation, because we might
- // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
- registry.registerDynamicUse(new DynamicUse(getterSelector));
- }
- if (setterError) {
- // We still need to register the invocation, because we might
- // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
- registry.registerDynamicUse(new DynamicUse(setterSelector));
- }
- if (getterError || setterError) {
- registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
- }
- return computeCompoundSuperAccessSemantics(node, getter, setter,
- isIndex: isIndex);
- }
-
- /// Resolve [node] as a subexpression that is _not_ the prefix of a member
- /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
- ResolutionResult visitExpression(Node node) {
- bool oldSendIsMemberAccess = sendIsMemberAccess;
- sendIsMemberAccess = false;
- ResolutionResult result = visit(node);
- sendIsMemberAccess = oldSendIsMemberAccess;
- return result;
- }
-
- /// Resolve [node] as a subexpression that _is_ the prefix of a member access.
- /// For instance `a` in `a.b`, as opposed to `a` in `a + b`.
- ResolutionResult visitExpressionPrefix(Node node) {
- int oldAllowedCategory = allowedCategory;
- bool oldSendIsMemberAccess = sendIsMemberAccess;
- allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
- sendIsMemberAccess = true;
- ResolutionResult result = visit(node);
- sendIsMemberAccess = oldSendIsMemberAccess;
- allowedCategory = oldAllowedCategory;
- return result;
- }
-
- /// Handle a type test expression, like `a is T` and `a is! T`.
- ResolutionResult handleIs(Send node) {
- Node expression = node.receiver;
- visitExpression(expression);
-
- // TODO(johnniwinther): Use seen type tests to avoid registration of
- // mutation/access to unpromoted variables.
-
- Send notTypeNode = node.arguments.head.asSend();
- ResolutionDartType type;
- SendStructure sendStructure;
- if (notTypeNode != null) {
- // `e is! T`.
- Node typeNode = notTypeNode.receiver;
- type = resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
- sendStructure = new IsNotStructure(type);
- } else {
- // `e is T`.
- Node typeNode = node.arguments.head;
- type = resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
- sendStructure = new IsStructure(type);
- }
-
- // GENERIC_METHODS: Method type variables are not reified so we must warn
- // about the error which will occur at runtime.
- if (type is MethodTypeVariableType) {
- reporter.reportWarningMessage(
- node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
- }
-
- registry.registerTypeUse(new TypeUse.isCheck(type));
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- }
-
- /// Handle a type cast expression, like `a as T`.
- ResolutionResult handleAs(Send node) {
- Node expression = node.receiver;
- visitExpression(expression);
-
- Node typeNode = node.arguments.head;
- ResolutionDartType type =
- resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
-
- // GENERIC_METHODS: Method type variables are not reified, so we must inform
- // the developer about the potentially bug-inducing semantics.
- if (type is MethodTypeVariableType) {
- reporter.reportHintMessage(
- node, MessageKind.TYPE_VARIABLE_FROM_METHOD_CONSIDERED_DYNAMIC);
- }
-
- registry.registerTypeUse(new TypeUse.asCast(type));
- registry.registerSendStructure(node, new AsStructure(type));
- return const NoneResult();
- }
-
- /// Handle the unary expression of an unresolved unary operator [text], like
- /// the no longer supported `+a`.
- ResolutionResult handleUnresolvedUnary(Send node, String text) {
- Node expression = node.receiver;
- if (node.isSuperCall) {
- checkSuperAccess(node);
- } else {
- visitExpression(expression);
- }
-
- registry.registerSendStructure(node, const InvalidUnaryStructure());
- return const NoneResult();
- }
-
- /// Handle the unary expression of a user definable unary [operator], like
- /// `-a`, and `-super`.
- ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) {
- ResolutionResult result = const NoneResult();
- Node expression = node.receiver;
- Selector selector = operator.selector;
- // TODO(23998): Remove this when all information goes through the
- // [SendStructure].
- registry.setSelector(node, selector);
-
- AccessSemantics semantics;
- if (node.isSuperCall) {
- semantics = checkSuperAccess(node);
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelector(node, selector);
- // TODO(johnniwinther): Add information to [AccessSemantics] about
- // whether it is erroneous.
- if (semantics.kind == AccessKind.SUPER_METHOD) {
- MethodElement superMethod = semantics.element.declaration;
- registry.registerStaticUse(
- new StaticUse.superInvoke(superMethod, selector.callStructure));
- }
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.useElement(node, semantics.element);
- }
- } else {
- ResolutionResult expressionResult = visitExpression(expression);
- semantics = const DynamicAccess.expression();
- registry.registerDynamicUse(new DynamicUse(selector));
-
- if (expressionResult.isConstant) {
- bool isValidConstant;
- ConstantExpression expressionConstant = expressionResult.constant;
- ResolutionDartType knownExpressionType =
- expressionConstant.getKnownType(commonElements);
- switch (operator.kind) {
- case UnaryOperatorKind.COMPLEMENT:
- isValidConstant = knownExpressionType == commonElements.intType;
- break;
- case UnaryOperatorKind.NEGATE:
- isValidConstant = knownExpressionType == commonElements.intType ||
- knownExpressionType == commonElements.doubleType;
- break;
- case UnaryOperatorKind.NOT:
- reporter.internalError(
- node, "Unexpected user definable unary operator: $operator");
- }
- if (isValidConstant) {
- // TODO(johnniwinther): Handle potentially invalid constant
- // expressions.
- ConstantExpression constant =
- new UnaryConstantExpression(operator, expressionConstant);
- registry.setConstant(node, constant);
- result = new ConstantResult(node, constant);
- }
- }
- }
- if (semantics != null) {
- registry.registerSendStructure(
- node, new UnaryStructure(semantics, operator));
- }
- return result;
- }
-
- /// Handle a not expression, like `!a`.
- ResolutionResult handleNot(Send node, UnaryOperator operator) {
- assert(operator.kind == UnaryOperatorKind.NOT, failedAt(node));
-
- Node expression = node.receiver;
- ResolutionResult result = visitExpression(expression);
- registry.registerSendStructure(node, const NotStructure());
-
- if (result.isConstant) {
- ConstantExpression expressionConstant = result.constant;
- if (expressionConstant.getKnownType(commonElements) ==
- commonElements.boolType) {
- // TODO(johnniwinther): Handle potentially invalid constant expressions.
- ConstantExpression constant =
- new UnaryConstantExpression(operator, expressionConstant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- }
-
- return const NoneResult();
- }
-
- /// Handle a logical and expression, like `a && b`.
- ResolutionResult handleLogicalAnd(Send node) {
- Node left = node.receiver;
- Node right = node.arguments.head;
- ResolutionResult leftResult =
- doInPromotionScope(left, () => visitExpression(left));
- ResolutionResult rightResult =
- doInPromotionScope(right, () => visitExpression(right));
- registry.registerSendStructure(node, const LogicalAndStructure());
-
- if (leftResult.isConstant && rightResult.isConstant) {
- ConstantExpression leftConstant = leftResult.constant;
- ConstantExpression rightConstant = rightResult.constant;
- if (leftConstant.getKnownType(commonElements) ==
- commonElements.boolType &&
- rightConstant.getKnownType(commonElements) ==
- commonElements.boolType) {
- // TODO(johnniwinther): Handle potentially invalid constant expressions.
- ConstantExpression constant = new BinaryConstantExpression(
- leftConstant, BinaryOperator.LOGICAL_AND, rightConstant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- }
-
- return const NoneResult();
- }
-
- /// Handle a logical or expression, like `a || b`.
- ResolutionResult handleLogicalOr(Send node) {
- Node left = node.receiver;
- Node right = node.arguments.head;
- ResolutionResult leftResult = visitExpression(left);
- ResolutionResult rightResult = visitExpression(right);
- registry.registerSendStructure(node, const LogicalOrStructure());
-
- if (leftResult.isConstant && rightResult.isConstant) {
- ConstantExpression leftConstant = leftResult.constant;
- ConstantExpression rightConstant = rightResult.constant;
- if (leftConstant.getKnownType(commonElements) ==
- commonElements.boolType &&
- rightConstant.getKnownType(commonElements) ==
- commonElements.boolType) {
- // TODO(johnniwinther): Handle potentially invalid constant expressions.
- ConstantExpression constant = new BinaryConstantExpression(
- leftConstant, BinaryOperator.LOGICAL_OR, rightConstant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- }
- return const NoneResult();
- }
-
- /// Handle an if-null expression, like `a ?? b`.
- ResolutionResult handleIfNull(Send node) {
- Node left = node.receiver;
- Node right = node.arguments.head;
- visitExpression(left);
- visitExpression(right);
- registry.registerConstantLiteral(new NullConstantExpression());
- registry.registerDynamicUse(new DynamicUse(Selectors.equals));
- registry.registerSendStructure(node, const IfNullStructure());
- return const NoneResult();
- }
-
- /// Handle the binary expression of an unresolved binary operator [text], like
- /// the no longer supported `a === b`.
- ResolutionResult handleUnresolvedBinary(Send node, String text) {
- Node left = node.receiver;
- Node right = node.arguments.head;
- if (node.isSuperCall) {
- checkSuperAccess(node);
- } else {
- visitExpression(left);
- }
- visitExpression(right);
- registry.registerSendStructure(node, const InvalidBinaryStructure());
- return const NoneResult();
- }
-
- /// Handle the binary expression of a user definable binary [operator], like
- /// `a + b`, `super + b`, `a == b` and `a != b`.
- ResolutionResult handleUserDefinableBinary(
- Send node, BinaryOperator operator) {
- ResolutionResult result = const NoneResult();
- Node left = node.receiver;
- Node right = node.arguments.head;
- AccessSemantics semantics;
- Selector selector;
- if (operator.kind == BinaryOperatorKind.INDEX) {
- selector = new Selector.index();
- } else {
- selector = new Selector.binaryOperator(operator.selectorName);
- }
- // TODO(23998): Remove this when all information goes through the
- // [SendStructure].
- registry.setSelector(node, selector);
-
- if (node.isSuperCall) {
- semantics = checkSuperAccess(node);
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelector(node, selector);
- // TODO(johnniwinther): Add information to [AccessSemantics] about
- // whether it is erroneous.
- if (semantics.kind == AccessKind.SUPER_METHOD) {
- MethodElement superMethod = semantics.element.declaration;
- registry.registerStaticUse(
- new StaticUse.superInvoke(superMethod, selector.callStructure));
- }
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.useElement(node, semantics.element);
- }
- visitExpression(right);
- } else {
- ResolutionResult leftResult = visitExpression(left);
- ResolutionResult rightResult = visitExpression(right);
- registry.registerDynamicUse(new DynamicUse(selector));
- semantics = const DynamicAccess.expression();
-
- if (leftResult.isConstant && rightResult.isConstant) {
- bool isValidConstant;
- ConstantExpression leftConstant = leftResult.constant;
- ConstantExpression rightConstant = rightResult.constant;
- ResolutionDartType knownLeftType =
- leftConstant.getKnownType(commonElements);
- ResolutionDartType knownRightType =
- rightConstant.getKnownType(commonElements);
- switch (operator.kind) {
- case BinaryOperatorKind.EQ:
- case BinaryOperatorKind.NOT_EQ:
- isValidConstant = (knownLeftType == commonElements.intType ||
- knownLeftType == commonElements.doubleType ||
- knownLeftType == commonElements.stringType ||
- knownLeftType == commonElements.boolType ||
- knownLeftType == commonElements.nullType) &&
- (knownRightType == commonElements.intType ||
- knownRightType == commonElements.doubleType ||
- knownRightType == commonElements.stringType ||
- knownRightType == commonElements.boolType ||
- knownRightType == commonElements.nullType);
- break;
- case BinaryOperatorKind.ADD:
- isValidConstant = (knownLeftType == commonElements.intType ||
- knownLeftType == commonElements.doubleType ||
- knownLeftType == commonElements.stringType) &&
- (knownRightType == commonElements.intType ||
- knownRightType == commonElements.doubleType ||
- knownRightType == commonElements.stringType);
- break;
- case BinaryOperatorKind.SUB:
- case BinaryOperatorKind.MUL:
- case BinaryOperatorKind.DIV:
- case BinaryOperatorKind.IDIV:
- case BinaryOperatorKind.MOD:
- case BinaryOperatorKind.GTEQ:
- case BinaryOperatorKind.GT:
- case BinaryOperatorKind.LTEQ:
- case BinaryOperatorKind.LT:
- isValidConstant = (knownLeftType == commonElements.intType ||
- knownLeftType == commonElements.doubleType) &&
- (knownRightType == commonElements.intType ||
- knownRightType == commonElements.doubleType);
- break;
- case BinaryOperatorKind.SHL:
- case BinaryOperatorKind.SHR:
- case BinaryOperatorKind.AND:
- case BinaryOperatorKind.OR:
- case BinaryOperatorKind.XOR:
- isValidConstant = knownLeftType == commonElements.intType &&
- knownRightType == commonElements.intType;
- break;
- case BinaryOperatorKind.INDEX:
- isValidConstant = false;
- break;
- case BinaryOperatorKind.LOGICAL_AND:
- case BinaryOperatorKind.LOGICAL_OR:
- case BinaryOperatorKind.IF_NULL:
- reporter.internalError(
- node, "Unexpected binary operator '${operator}'.");
- break;
- }
- if (isValidConstant) {
- // TODO(johnniwinther): Handle potentially invalid constant
- // expressions.
- ConstantExpression constant = new BinaryConstantExpression(
- leftResult.constant, operator, rightResult.constant);
- registry.setConstant(node, constant);
- result = new ConstantResult(node, constant);
- }
- }
- }
-
- if (semantics != null) {
- // TODO(johnniwinther): Support invalid super access as an
- // [AccessSemantics].
- SendStructure sendStructure;
- switch (operator.kind) {
- case BinaryOperatorKind.EQ:
- sendStructure = new EqualsStructure(semantics);
- break;
- case BinaryOperatorKind.NOT_EQ:
- sendStructure = new NotEqualsStructure(semantics);
- break;
- case BinaryOperatorKind.INDEX:
- sendStructure = new IndexStructure(semantics);
- break;
- case BinaryOperatorKind.ADD:
- case BinaryOperatorKind.SUB:
- case BinaryOperatorKind.MUL:
- case BinaryOperatorKind.DIV:
- case BinaryOperatorKind.IDIV:
- case BinaryOperatorKind.MOD:
- case BinaryOperatorKind.SHL:
- case BinaryOperatorKind.SHR:
- case BinaryOperatorKind.GTEQ:
- case BinaryOperatorKind.GT:
- case BinaryOperatorKind.LTEQ:
- case BinaryOperatorKind.LT:
- case BinaryOperatorKind.AND:
- case BinaryOperatorKind.OR:
- case BinaryOperatorKind.XOR:
- sendStructure = new BinaryStructure(semantics, operator);
- break;
- case BinaryOperatorKind.LOGICAL_AND:
- case BinaryOperatorKind.LOGICAL_OR:
- case BinaryOperatorKind.IF_NULL:
- reporter.internalError(
- node, "Unexpected binary operator '${operator}'.");
- break;
- }
- registry.registerSendStructure(node, sendStructure);
- }
- return result;
- }
-
- /// Handle an invocation of an expression, like `(){}()` or `(foo)()`.
- ResolutionResult handleExpressionInvoke(Send node) {
- assert(node.isCall, failedAt(node, "Unexpected expression: $node"));
- Node expression = node.selector;
- visitExpression(expression);
- CallStructure callStructure =
- resolveArguments(node.argumentsNode).callStructure;
- Selector selector = callStructure.callSelector;
- // TODO(23998): Remove this when all information goes through the
- // [SendStructure].
- registry.setSelector(node, selector);
- registry.registerDynamicUse(new DynamicUse(selector));
- registry.registerSendStructure(
- node, new InvokeStructure(const DynamicAccess.expression(), selector));
- return const NoneResult();
- }
-
- /// Handle access of a property of [name] on `this`, like `this.name` and
- /// `this.name()`, or `name` and `name()` in instance context.
- ResolutionResult handleThisPropertyAccess(Send node, Name name) {
- AccessSemantics semantics = new DynamicAccess.thisProperty(name);
- return handleDynamicAccessSemantics(node, name, semantics);
- }
-
- /// Handle update of a property of [name] on `this`, like `this.name = b` and
- /// `this.name++`, or `name = b` and `name++` in instance context.
- ResolutionResult handleThisPropertyUpdate(
- SendSet node, Name name, Element element) {
- AccessSemantics semantics = new DynamicAccess.thisProperty(name);
- return handleDynamicUpdateSemantics(node, name, element, semantics);
- }
-
- /// Handle access on `this`, like `this()` and `this` when it is parsed as a
- /// [Send] node.
- ResolutionResult handleThisAccess(Send node) {
- if (node.isCall) {
- CallStructure callStructure =
- resolveArguments(node.argumentsNode).callStructure;
- Selector selector = callStructure.callSelector;
- // TODO(johnniwinther): Handle invalid this access as an
- // [AccessSemantics].
- AccessSemantics accessSemantics = checkThisAccess(node);
- if (accessSemantics == null) {
- accessSemantics = const DynamicAccess.thisAccess();
- registry.registerDynamicUse(new DynamicUse(selector));
- }
- registry.registerSendStructure(
- node, new InvokeStructure(accessSemantics, selector));
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.setSelector(node, selector);
- return const NoneResult();
- } else {
- // TODO(johnniwinther): Handle get of `this` when it is a [Send] node.
- reporter.internalError(node, "Unexpected node '$node'.");
- }
- return const NoneResult();
- }
-
- /// Handle access of a super property, like `super.foo` and `super.foo()`.
- ResolutionResult handleSuperPropertyAccess(Send node, Name name) {
- Element target;
- Selector selector;
- CallStructure callStructure;
- if (node.isCall) {
- callStructure = resolveArguments(node.argumentsNode).callStructure;
- selector = new Selector.call(name, callStructure);
- } else {
- selector = new Selector.getter(name);
- }
- AccessSemantics semantics = checkSuperAccess(node);
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelector(node, selector,
- alternateName: name.setter);
- }
- if (node.isCall) {
- bool isIncompatibleInvoke = false;
- switch (semantics.kind) {
- case AccessKind.SUPER_METHOD:
- MethodElement superMethod = semantics.element;
- superMethod.computeType(resolution);
- if (!callStructure.signatureApplies(superMethod.parameterStructure)) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- registry.registerDynamicUse(new DynamicUse(selector));
- registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
- isIncompatibleInvoke = true;
- } else {
- registry.registerStaticUse(
- new StaticUse.superInvoke(superMethod, callStructure));
- }
- break;
- case AccessKind.SUPER_FIELD:
- case AccessKind.SUPER_FINAL_FIELD:
- case AccessKind.SUPER_GETTER:
- MemberElement superMember = semantics.element;
- registry.registerStaticUse(new StaticUse.superGet(superMember));
- selector = callStructure.callSelector;
- registry.registerDynamicUse(new DynamicUse(selector));
- break;
- case AccessKind.SUPER_SETTER:
- case AccessKind.UNRESOLVED_SUPER:
- // NoSuchMethod registered in [computeSuperSemantics].
- break;
- case AccessKind.INVALID:
- // 'super' is not allowed.
- break;
- default:
- reporter.internalError(
- node, "Unexpected super property access $semantics.");
- break;
- }
- registry.registerSendStructure(
- node,
- isIncompatibleInvoke
- ? new IncompatibleInvokeStructure(semantics, selector)
- : new InvokeStructure(semantics, selector));
- } else {
- switch (semantics.kind) {
- case AccessKind.SUPER_METHOD:
- // TODO(johnniwinther): Method this should be registered as a
- // closurization.
- MethodElement superMethod = semantics.element;
- registry.registerStaticUse(new StaticUse.superTearOff(superMethod));
- break;
- case AccessKind.SUPER_FIELD:
- case AccessKind.SUPER_FINAL_FIELD:
- case AccessKind.SUPER_GETTER:
- MemberElement superMember = semantics.element;
- registry.registerStaticUse(new StaticUse.superGet(superMember));
- break;
- case AccessKind.SUPER_SETTER:
- case AccessKind.UNRESOLVED_SUPER:
- // NoSuchMethod registered in [computeSuperSemantics].
- break;
- case AccessKind.INVALID:
- // 'super' is not allowed.
- break;
- default:
- reporter.internalError(
- node, "Unexpected super property access $semantics.");
- break;
- }
- registry.registerSendStructure(node, new GetStructure(semantics));
- }
- target = semantics.element;
-
- // TODO(23998): Remove these when all information goes through
- // the [SendStructure].
- registry.useElement(node, target);
- registry.setSelector(node, selector);
- return const NoneResult();
- }
-
- /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`,
- /// `a + b`, and `~a`.
- // ignore: MISSING_RETURN
- ResolutionResult handleOperatorSend(Send node) {
- String operatorText = node.selector.asOperator().source;
- if (operatorText == 'is') {
- return handleIs(node);
- } else if (operatorText == 'as') {
- return handleAs(node);
- } else if (node.arguments.isEmpty) {
- UnaryOperator operator = UnaryOperator.parse(operatorText);
- if (operator == null) {
- return handleUnresolvedUnary(node, operatorText);
- } else {
- switch (operator.kind) {
- case UnaryOperatorKind.NOT:
- return handleNot(node, operator);
- case UnaryOperatorKind.COMPLEMENT:
- case UnaryOperatorKind.NEGATE:
- assert(operator.isUserDefinable,
- failedAt(node, "Unexpected unary operator '${operator}'."));
- return handleUserDefinableUnary(node, operator);
- }
- }
- } else {
- BinaryOperator operator = BinaryOperator.parse(operatorText);
- if (operator == null) {
- return handleUnresolvedBinary(node, operatorText);
- } else {
- switch (operator.kind) {
- case BinaryOperatorKind.LOGICAL_AND:
- return handleLogicalAnd(node);
- case BinaryOperatorKind.LOGICAL_OR:
- return handleLogicalOr(node);
- case BinaryOperatorKind.IF_NULL:
- return handleIfNull(node);
- case BinaryOperatorKind.EQ:
- case BinaryOperatorKind.NOT_EQ:
- case BinaryOperatorKind.INDEX:
- case BinaryOperatorKind.ADD:
- case BinaryOperatorKind.SUB:
- case BinaryOperatorKind.MUL:
- case BinaryOperatorKind.DIV:
- case BinaryOperatorKind.IDIV:
- case BinaryOperatorKind.MOD:
- case BinaryOperatorKind.SHL:
- case BinaryOperatorKind.SHR:
- case BinaryOperatorKind.GTEQ:
- case BinaryOperatorKind.GT:
- case BinaryOperatorKind.LTEQ:
- case BinaryOperatorKind.LT:
- case BinaryOperatorKind.AND:
- case BinaryOperatorKind.OR:
- case BinaryOperatorKind.XOR:
- return handleUserDefinableBinary(node, operator);
- }
- }
- }
- }
-
- /// Handle qualified access to an unresolved static class member, like `a.b`
- /// or `a.b()` where `a` is a class and `b` is unresolved.
- ResolutionResult handleUnresolvedStaticMemberAccess(
- Send node, Name name, ClassElement receiverClass) {
- // TODO(johnniwinther): Share code with [handleStaticInstanceMemberAccess]
- // and [handlePrivateStaticMemberAccess].
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- // TODO(johnniwinther): Produce a different error if [name] is resolves to
- // a constructor.
-
- // TODO(johnniwinther): With the simplified [TreeElements] invariant,
- // try to resolve injected elements if [currentClass] is in the patch
- // library of [receiverClass].
-
- // TODO(karlklose): this should be reported by the caller of
- // [resolveSend] to select better warning messages for getters and
- // setters.
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.UNDEFINED_GETTER,
- {'className': receiverClass.name, 'memberName': name.text});
- // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
- // member access.
- return handleErroneousAccess(
- node, name, new StaticAccess.unresolved(error));
- }
-
- /// Handle qualified update to an unresolved static class member, like
- /// `a.b = c` or `a.b++` where `a` is a class and `b` is unresolved.
- ResolutionResult handleUnresolvedStaticMemberUpdate(
- SendSet node, Name name, ClassElement receiverClass) {
- // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate]
- // and [handlePrivateStaticMemberUpdate].
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- // TODO(johnniwinther): Produce a different error if [name] is resolves to
- // a constructor.
-
- // TODO(johnniwinther): With the simplified [TreeElements] invariant,
- // try to resolve injected elements if [currentClass] is in the patch
- // library of [receiverClass].
-
- // TODO(johnniwinther): Produce a different error for complex update.
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.UNDEFINED_GETTER,
- {'className': receiverClass.name, 'memberName': name.text});
- // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
- // member access.
- return handleUpdate(node, name, new StaticAccess.unresolved(error));
- }
-
- /// Handle qualified access of an instance member, like `a.b` or `a.b()` where
- /// `a` is a class and `b` is a non-static member.
- ResolutionResult handleStaticInstanceMemberAccess(
- Send node, Name name, ClassElement receiverClass, Element member) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- // TODO(johnniwinther): With the simplified [TreeElements] invariant,
- // try to resolve injected elements if [currentClass] is in the patch
- // library of [receiverClass].
-
- // TODO(karlklose): this should be reported by the caller of
- // [resolveSend] to select better warning messages for getters and
- // setters.
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.MEMBER_NOT_STATIC,
- {'className': receiverClass.name, 'memberName': name});
-
- // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed
- // instance members.
- return handleErroneousAccess(
- node, name, new StaticAccess.unresolved(error));
- }
-
- /// Handle qualified update of an instance member, like `a.b = c` or `a.b++`
- /// where `a` is a class and `b` is a non-static member.
- ResolutionResult handleStaticInstanceMemberUpdate(
- SendSet node, Name name, ClassElement receiverClass, Element member) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- // TODO(johnniwinther): With the simplified [TreeElements] invariant,
- // try to resolve injected elements if [currentClass] is in the patch
- // library of [receiverClass].
-
- // TODO(johnniwinther): Produce a different error for complex update.
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.MEMBER_NOT_STATIC,
- {'className': receiverClass.name, 'memberName': name});
-
- // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed
- // instance members.
- return handleUpdate(node, name, new StaticAccess.unresolved(error));
- }
-
- /// Handle qualified access of an inaccessible private static class member,
- /// like `a._b` or `a._b()` where `a` is class, `_b` is static member of `a`
- /// but `a` is not defined in the current library.
- ResolutionResult handlePrivateStaticMemberAccess(
- Send node, Name name, ClassElement receiverClass, Element member) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.PRIVATE_ACCESS,
- {'libraryName': member.library.name, 'name': name});
- // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
- // member access.
- return handleErroneousAccess(
- node, name, new StaticAccess.unresolved(error));
- }
-
- /// Handle qualified update of an inaccessible private static class member,
- /// like `a._b = c` or `a._b++` where `a` is class, `_b` is static member of
- /// `a` but `a` is not defined in the current library.
- ResolutionResult handlePrivateStaticMemberUpdate(
- SendSet node, Name name, ClassElement receiverClass, Element member) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.PRIVATE_ACCESS,
- {'libraryName': member.library.name, 'name': name});
- // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
- // member access.
- return handleUpdate(node, name, new StaticAccess.unresolved(error));
- }
-
- /// Handle qualified access to a static member, like `a.b` or `a.b()` where
- /// `a` is a class and `b` is a static member of `a`.
- ResolutionResult handleStaticMemberAccess(
- Send node, Name memberName, ClassElement receiverClass) {
- String name = memberName.text;
- receiverClass.ensureResolved(resolution);
- if (node.isOperator) {
- // When the resolved receiver is a class, we can have two cases:
- // 1) a static send: C.foo, or
- // 2) an operator send, where the receiver is a class literal: 'C + 1'.
- // The following code that looks up the selector on the resolved
- // receiver will treat the second as the invocation of a static operator
- // if the resolved receiver is not null.
- return const NoneResult();
- }
- MembersCreator.computeClassMembersByName(
- resolution, receiverClass.declaration, name);
- Element member = receiverClass.lookupLocalMember(name);
- if (member == null) {
- return handleUnresolvedStaticMemberAccess(
- node, memberName, receiverClass);
- } else if (member.isAmbiguous) {
- return handleAmbiguousSend(node, memberName, member);
- } else if (member.isInstanceMember) {
- return handleStaticInstanceMemberAccess(
- node, memberName, receiverClass, member);
- } else if (memberName.isPrivate && memberName.library != member.library) {
- return handlePrivateStaticMemberAccess(
- node, memberName, receiverClass, member);
- } else {
- return handleStaticOrTopLevelAccess(node, memberName, member);
- }
- }
-
- /// Handle qualified update to a static member, like `a.b = c` or `a.b++`
- /// where `a` is a class and `b` is a static member of `a`.
- ResolutionResult handleStaticMemberUpdate(
- Send node, Name memberName, ClassElement receiverClass) {
- String name = memberName.text;
- receiverClass.ensureResolved(resolution);
- MembersCreator.computeClassMembersByName(
- resolution, receiverClass.declaration, name);
- Element member = receiverClass.lookupLocalMember(name);
- if (member == null) {
- return handleUnresolvedStaticMemberUpdate(
- node, memberName, receiverClass);
- } else if (member.isAmbiguous) {
- return handleAmbiguousUpdate(node, memberName, member);
- } else if (member.isInstanceMember) {
- return handleStaticInstanceMemberUpdate(
- node, memberName, receiverClass, member);
- } else if (memberName.isPrivate && memberName.library != member.library) {
- return handlePrivateStaticMemberUpdate(
- node, memberName, receiverClass, member);
- } else {
- return handleStaticOrTopLevelUpdate(node, memberName, member);
- }
- }
-
- /// Handle access to a type literal of type variable [element]. Like `T` or
- /// `T()` where 'T' is type variable.
- // TODO(johnniwinther): Remove [name] when [Selector] is not required for the
- // the [GetStructure].
- // TODO(johnniwinther): Remove [element] when it is no longer needed for
- // evaluating constants.
- ResolutionResult handleTypeVariableTypeLiteralAccess(
- Send node, Name name, TypeVariableElement element) {
- AccessSemantics semantics;
- if (!Elements.hasAccessToTypeVariable(enclosingElement, element)) {
- // TODO(johnniwinther): Add another access semantics for this.
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
- {'typeVariableName': name},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- semantics = new StaticAccess.invalid(error);
- // TODO(johnniwinther): Clean up registration of elements and selectors
- // for this case.
- } else {
- // GENERIC_METHODS: Method type variables are not reified so we must warn
- // about the error which will occur at runtime.
- if (element.type is MethodTypeVariableType) {
- reporter.reportWarningMessage(
- node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
- }
- semantics = new StaticAccess.typeParameterTypeLiteral(element);
- }
-
- registry.useElement(node, element);
- registry.registerTypeLiteral(node, element.type);
-
- if (node.isCall) {
- CallStructure callStructure =
- resolveArguments(node.argumentsNode).callStructure;
- Selector selector = callStructure.callSelector;
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.setSelector(node, selector);
-
- registry.registerSendStructure(
- node, new InvokeStructure(semantics, selector));
- } else {
- // TODO(johnniwinther): Avoid the need for a [Selector] here.
- registry.registerSendStructure(node, new GetStructure(semantics));
- }
- return const NoneResult();
- }
-
- /// Handle access to a type literal of type variable [element]. Like `T = b`,
- /// `T++` or `T += b` where 'T' is type variable.
- ResolutionResult handleTypeVariableTypeLiteralUpdate(
- SendSet node, Name name, TypeVariableElement element) {
- AccessSemantics semantics;
- if (!Elements.hasAccessToTypeVariable(enclosingElement, element)) {
- // TODO(johnniwinther): Add another access semantics for this.
- ErroneousElement error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
- {'typeVariableName': name},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- semantics = new StaticAccess.invalid(error);
- } else {
- ErroneousElement error;
- if (node.isIfNullAssignment) {
- error = reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.IF_NULL_ASSIGNING_TYPE, const {});
- // TODO(23998): Remove these when all information goes through
- // the [SendStructure].
- registry.useElement(node.selector, element);
- } else {
- error = reportAndCreateErroneousElement(
- node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {});
- }
-
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.useElement(node, error);
- // TODO(johnniwinther): Register only on read?
- registry.registerTypeLiteral(node, element.type);
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- semantics = new StaticAccess.typeParameterTypeLiteral(element);
- }
- return handleUpdate(node, name, semantics);
- }
-
- /// Handle access to a constant type literal of [type].
- // TODO(johnniwinther): Remove [name] when [Selector] is not required for the
- // the [GetStructure].
- // TODO(johnniwinther): Remove [element] when it is no longer needed for
- // evaluating constants.
- ResolutionResult handleConstantTypeLiteralAccess(
- Send node,
- Name name,
- TypeDeclarationElement element,
- ResolutionDartType type,
- ConstantAccess semantics) {
- registry.useElement(node, element);
- registry.registerTypeLiteral(node, type);
-
- if (node.isCall) {
- CallStructure callStructure =
- resolveArguments(node.argumentsNode).callStructure;
- Selector selector = callStructure.callSelector;
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.setSelector(node, selector);
-
- // The node itself is not a constant but we register the selector (the
- // identifier that refers to the class/typedef) as a constant.
- registry.useElement(node.selector, element);
- analyzeConstantDeferred(node.selector, enforceConst: false);
-
- registry.registerSendStructure(
- node, new InvokeStructure(semantics, selector));
- return const NoneResult();
- } else {
- analyzeConstantDeferred(node, enforceConst: false);
-
- registry.setConstant(node, semantics.constant);
- registry.registerSendStructure(node, new GetStructure(semantics));
- return new ConstantResult(node, semantics.constant);
- }
- }
-
- /// Handle access to a constant type literal of [type].
- // TODO(johnniwinther): Remove [name] when [Selector] is not required for the
- // the [GetStructure].
- // TODO(johnniwinther): Remove [element] when it is no longer needed for
- // evaluating constants.
- ResolutionResult handleConstantTypeLiteralUpdate(
- SendSet node,
- Name name,
- TypeDeclarationElement element,
- ResolutionDartType type,
- ConstantAccess semantics) {
- // TODO(johnniwinther): Remove this when all constants are evaluated.
- resolver.constantCompiler.evaluate(semantics.constant);
-
- ErroneousElement error;
- if (node.isIfNullAssignment) {
- error = reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.IF_NULL_ASSIGNING_TYPE, const {});
- // TODO(23998): Remove these when all information goes through
- // the [SendStructure].
- registry.setConstant(node.selector, semantics.constant);
- registry.useElement(node.selector, element);
- } else {
- error = reportAndCreateErroneousElement(
- node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {});
- }
-
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.useElement(node, error);
- registry.registerTypeLiteral(node, type);
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
- return handleUpdate(node, name, semantics);
- }
-
- /// Handle access to a type literal of a typedef. Like `F` or
- /// `F()` where 'F' is typedef.
- ResolutionResult handleTypedefTypeLiteralAccess(
- Send node, Name name, TypedefElement typdef) {
- typdef.ensureResolved(resolution);
- ResolutionDartType type = typdef.rawType;
- ConstantExpression constant = new TypeConstantExpression(type, name.text);
- AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant);
- return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics);
- }
-
- /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or
- /// `F += b` where 'F' is typedef.
- ResolutionResult handleTypedefTypeLiteralUpdate(
- SendSet node, Name name, TypedefElement typdef) {
- typdef.ensureResolved(resolution);
- ResolutionDartType type = typdef.rawType;
- ConstantExpression constant = new TypeConstantExpression(type, name.text);
- AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant);
- return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics);
- }
-
- /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or
- /// `dynamic()`.
- ResolutionResult handleDynamicTypeLiteralAccess(Send node) {
- ResolutionDartType type = const ResolutionDynamicType();
- ConstantExpression constant = new TypeConstantExpression(
- // TODO(johnniwinther): Use [type] when evaluation of constants is done
- // directly on the constant expressions.
- node.isCall ? commonElements.typeType : type,
- 'dynamic');
- AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
- ClassElement typeClass = commonElements.typeClass;
- return handleConstantTypeLiteralAccess(
- node, const PublicName('dynamic'), typeClass, type, semantics);
- }
-
- /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or
- /// `dynamic = 0`.
- ResolutionResult handleDynamicTypeLiteralUpdate(SendSet node) {
- ResolutionDartType type = const ResolutionDynamicType();
- ConstantExpression constant =
- new TypeConstantExpression(const ResolutionDynamicType(), 'dynamic');
- AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
- ClassElement typeClass = commonElements.typeClass;
- return handleConstantTypeLiteralUpdate(
- node, const PublicName('dynamic'), typeClass, type, semantics);
- }
-
- /// Handle access to a type literal of a class. Like `C` or
- /// `C()` where 'C' is class.
- ResolutionResult handleClassTypeLiteralAccess(
- Send node, Name name, ClassElement cls) {
- cls.ensureResolved(resolution);
- ResolutionDartType type = cls.rawType;
- ConstantExpression constant = new TypeConstantExpression(type, name.text);
- AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant);
- return handleConstantTypeLiteralAccess(node, name, cls, type, semantics);
- }
-
- /// Handle access to a type literal of a class. Like `C = b`, `C++` or
- /// `C += b` where 'C' is class.
- ResolutionResult handleClassTypeLiteralUpdate(
- SendSet node, Name name, ClassElement cls) {
- cls.ensureResolved(resolution);
- ResolutionDartType type = cls.rawType;
- ConstantExpression constant = new TypeConstantExpression(type, name.text);
- AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant);
- return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics);
- }
-
- /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in
- /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time
- /// error.
- ResolutionResult handleClassSend(Send node, Name name, ClassElement cls) {
- cls.ensureResolved(resolution);
- if (sendIsMemberAccess) {
- registry.useElement(node, cls);
- return new PrefixResult(null, cls);
- } else {
- // `C` or `C()` where 'C' is a class.
- return handleClassTypeLiteralAccess(node, name, cls);
- }
- }
-
- /// Compute a [DeferredPrefixStructure] for [node].
- ResolutionResult handleDeferredAccess(
- Send node, PrefixElement prefix, ResolutionResult result) {
- assert(
- prefix.isDeferred, failedAt(node, "Prefix $prefix is not deferred."));
- SendStructure sendStructure = registry.getSendStructure(node);
- assert(
- sendStructure != null, failedAt(node, "No SendStructure for $node."));
- registry.registerSendStructure(
- node, new DeferredPrefixStructure(prefix, sendStructure));
- if (result.isConstant) {
- ConstantExpression constant = new DeferredConstantExpression(
- result.constant, prefix.deferredImport);
- registry.setConstant(node, constant);
- result = new ConstantResult(node, constant);
- }
- return result;
- }
-
- /// Handle qualified [Send] where the receiver resolves to a [prefix],
- /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where
- /// `prefix` is a library prefix.
- ResolutionResult handleLibraryPrefixSend(
- Send node, Name name, PrefixElement prefix) {
- ResolutionResult result;
- Element member = prefix.lookupLocalMember(name.text);
- if (member == null) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- Element error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.NO_SUCH_LIBRARY_MEMBER,
- {'libraryName': prefix.name, 'memberName': name});
- result = handleUnresolvedAccess(node, name, error);
- } else {
- result = handleResolvedSend(node, name, member);
- }
- if (result.kind == ResultKind.PREFIX) {
- // [member] is a class prefix of a static access like `prefix.Class` of
- // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will
- // called on the parent `prefix.Class.foo` node.
- result = new PrefixResult(prefix, result.element);
- } else if (prefix.isDeferred &&
- (member == null || !member.isDeferredLoaderGetter)) {
- result = handleDeferredAccess(node, prefix, result);
- }
- return result;
- }
-
- /// Handle qualified [SendSet] where the receiver resolves to a [prefix],
- /// like `prefix.toplevelField = b` or `prefix.Class.staticField++` where
- /// `prefix` is a library prefix.
- ResolutionResult handleLibraryPrefixSendSet(
- SendSet node, Name name, PrefixElement prefix) {
- ResolutionResult result;
- Element member = prefix.lookupLocalMember(name.text);
- if (member == null) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- Element error = reportAndCreateErroneousElement(
- node,
- name.text,
- MessageKind.NO_SUCH_LIBRARY_MEMBER,
- {'libraryName': prefix.name, 'memberName': name});
- return handleUpdate(node, name, new StaticAccess.unresolved(error));
- } else {
- result = handleResolvedSendSet(node, name, member);
- }
- if (result.kind == ResultKind.PREFIX) {
- // [member] is a class prefix of a static access like `prefix.Class` of
- // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will
- // called on the parent `prefix.Class.foo` node.
- result = new PrefixResult(prefix, result.element);
- } else if (prefix.isDeferred &&
- (member == null || !member.isDeferredLoaderGetter)) {
- result = handleDeferredAccess(node, prefix, result);
- }
- return result;
- }
-
- /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in
- /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time
- /// error.
- ResolutionResult handleLibraryPrefix(
- Send node, Name name, PrefixElement prefix) {
- if ((ElementCategory.PREFIX & allowedCategory) == 0) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- return handleErroneousAccess(node, name, new StaticAccess.invalid(error));
- }
- if (prefix.isDeferred) {
- // TODO(23998): Remove this when deferred access is detected
- // through a [SendStructure].
- registry.useElement(node.selector, prefix);
- }
- registry.useElement(node, prefix);
- return new PrefixResult(prefix, null);
- }
-
- /// Handle qualified [Send] where the receiver resolves to an [Element], like
- /// `a.b` where `a` is a prefix or a class.
- ResolutionResult handlePrefixSend(
- Send node, Name name, PrefixResult prefixResult) {
- Element element = prefixResult.element;
- if (element.isPrefix) {
- if (node.isConditional) {
- return handleLibraryPrefix(node, name, element);
- } else {
- return handleLibraryPrefixSend(node, name, element);
- }
- } else {
- assert(element.isClass);
- ResolutionResult result = handleStaticMemberAccess(node, name, element);
- if (prefixResult.isDeferred) {
- result = handleDeferredAccess(node, prefixResult.prefix, result);
- }
- return result;
- }
- }
-
- /// Handle qualified [SendSet] where the receiver resolves to an [Element],
- /// like `a.b = c` where `a` is a prefix or a class.
- ResolutionResult handlePrefixSendSet(
- SendSet node, Name name, PrefixResult prefixResult) {
- Element element = prefixResult.element;
- if (element.isPrefix) {
- if (node.isConditional) {
- return handleLibraryPrefix(node, name, element);
- } else {
- return handleLibraryPrefixSendSet(node, name, element);
- }
- } else {
- assert(element.isClass);
- ResolutionResult result = handleStaticMemberUpdate(node, name, element);
- if (prefixResult.isDeferred) {
- result = handleDeferredAccess(node, prefixResult.prefix, result);
- }
- return result;
- }
- }
-
- /// Handle dynamic access of [semantics].
- ResolutionResult handleDynamicAccessSemantics(
- Send node, Name name, AccessSemantics semantics) {
- SendStructure sendStructure;
- Selector selector;
- if (node.isCall) {
- CallStructure callStructure =
- resolveArguments(node.argumentsNode).callStructure;
- selector = new Selector.call(name, callStructure);
- registry.registerDynamicUse(new DynamicUse(selector));
- sendStructure = new InvokeStructure(semantics, selector);
- } else {
- assert(node.isPropertyAccess, failedAt(node));
- selector = new Selector.getter(name);
- registry.registerDynamicUse(new DynamicUse(selector));
- sendStructure = new GetStructure(semantics);
- }
- registry.registerSendStructure(node, sendStructure);
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.setSelector(node, selector);
- return const NoneResult();
- }
-
- /// Handle dynamic update of [semantics].
- ResolutionResult handleDynamicUpdateSemantics(
- SendSet node, Name name, Element element, AccessSemantics semantics) {
- Selector getterSelector = new Selector.getter(name);
- Selector setterSelector = new Selector.setter(name.setter);
- registry.registerDynamicUse(new DynamicUse(setterSelector));
- if (node.isComplex) {
- registry.registerDynamicUse(new DynamicUse(getterSelector));
- }
-
- // TODO(23998): Remove these when elements are only accessed through the
- // send structure.
- Element getter = element;
- Element setter = element;
- if (element != null && element.isAbstractField) {
- AbstractFieldElement abstractField = element;
- getter = abstractField.getter;
- setter = abstractField.setter;
- }
- if (setter != null) {
- registry.useElement(node, setter);
- if (getter != null && node.isComplex) {
- registry.useElement(node.selector, getter);
- }
- }
-
- return handleUpdate(node, name, semantics);
- }
-
- /// Handle `this` as a qualified property, like `a.this`.
- ResolutionResult handleQualifiedThisAccess(Send node, Name name) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node.selector, name.text, MessageKind.THIS_PROPERTY, {},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- AccessSemantics accessSemantics = new StaticAccess.invalid(error);
- return handleErroneousAccess(node, name, accessSemantics);
- }
-
- /// Handle a qualified [Send], that is where the receiver is non-null, like
- /// `a.b`, `a.b()`, `this.a()` and `super.a()`.
- ResolutionResult handleQualifiedSend(Send node) {
- Identifier selector = node.selector.asIdentifier();
- String text = selector.source;
- Name name = new Name(text, enclosingElement.library);
- if (text == 'this') {
- return handleQualifiedThisAccess(node, name);
- } else if (node.isSuperCall) {
- return handleSuperPropertyAccess(node, name);
- } else if (node.receiver.isThis()) {
- AccessSemantics semantics = checkThisAccess(node);
- if (semantics == null) {
- return handleThisPropertyAccess(node, name);
- } else {
- // TODO(johnniwinther): Handle invalid this access as an
- // [AccessSemantics].
- return handleErroneousAccess(node, name, semantics);
- }
- }
- ResolutionResult result = visitExpressionPrefix(node.receiver);
- if (result.kind == ResultKind.PREFIX) {
- return handlePrefixSend(node, name, result);
- } else if (node.isConditional) {
- registry.registerConstantLiteral(new NullConstantExpression());
- registry.registerDynamicUse(new DynamicUse(Selectors.equals));
- return handleDynamicAccessSemantics(
- node, name, new DynamicAccess.ifNotNullProperty(name));
- } else {
- // Handle dynamic property access, like `a.b` or `a.b()` where `a` is not
- // a prefix or class.
- // TODO(johnniwinther): Use the `element` of [result].
- return handleDynamicAccessSemantics(
- node, name, new DynamicAccess.dynamicProperty(name));
- }
- }
-
- /// Handle a qualified [SendSet], that is where the receiver is non-null, like
- /// `a.b = c`, `a.b++`, and `a.b += c`.
- ResolutionResult handleQualifiedSendSet(SendSet node) {
- Identifier selector = node.selector.asIdentifier();
- String text = selector.source;
- Name name = new Name(text, enclosingElement.library);
- if (text == 'this') {
- return handleQualifiedThisAccess(node, name);
- } else if (node.receiver.isThis()) {
- AccessSemantics semantics = checkThisAccess(node);
- if (semantics == null) {
- return handleThisPropertyUpdate(node, name, null);
- } else {
- // TODO(johnniwinther): Handle invalid this access as an
- // [AccessSemantics].
- return handleUpdate(node, name, semantics);
- }
- }
- ResolutionResult result = visitExpressionPrefix(node.receiver);
- if (result.kind == ResultKind.PREFIX) {
- return handlePrefixSendSet(node, name, result);
- } else if (node.isConditional) {
- registry.registerConstantLiteral(new NullConstantExpression());
- registry.registerDynamicUse(new DynamicUse(Selectors.equals));
- return handleDynamicUpdateSemantics(
- node, name, null, new DynamicAccess.ifNotNullProperty(name));
- } else {
- // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c`
- // where `a` is not a prefix or class.
- // TODO(johnniwinther): Use the `element` of [result].
- return handleDynamicUpdateSemantics(
- node, name, null, new DynamicAccess.dynamicProperty(name));
- }
- }
-
- /// Handle access unresolved access to [name] in a non-instance context.
- ResolutionResult handleUnresolvedAccess(
- Send node, Name name, Element element) {
- // TODO(johnniwinther): Support unresolved top level access as an
- // [AccessSemantics].
- AccessSemantics semantics = new StaticAccess.unresolved(element);
- return handleErroneousAccess(node, name, semantics);
- }
-
- /// Handle erroneous access of [element] of the given [semantics].
- ResolutionResult handleErroneousAccess(
- Send node, Name name, AccessSemantics semantics) {
- SendStructure sendStructure;
- Selector selector;
- if (node.isCall) {
- CallStructure callStructure =
- resolveArguments(node.argumentsNode).callStructure;
- selector = new Selector.call(name, callStructure);
- registry.registerDynamicUse(new DynamicUse(selector));
- sendStructure = new InvokeStructure(semantics, selector);
- } else {
- assert(node.isPropertyAccess, failedAt(node));
- selector = new Selector.getter(name);
- registry.registerDynamicUse(new DynamicUse(selector));
- sendStructure = new GetStructure(semantics);
- }
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.setSelector(node, selector);
- registry.useElement(node, semantics.element);
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- }
-
- /// Handle access to an ambiguous element, that is, a name imported twice.
- ResolutionResult handleAmbiguousSend(
- Send node, Name name, AmbiguousElement element) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node, name.text, element.messageKind, element.messageArguments,
- infos: element.computeInfos(enclosingElement, reporter));
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
- // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
- AccessSemantics semantics = new StaticAccess.unresolved(error);
- return handleErroneousAccess(node, name, semantics);
- }
-
- /// Handle update to an ambiguous element, that is, a name imported twice.
- ResolutionResult handleAmbiguousUpdate(
- SendSet node, Name name, AmbiguousElement element) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node, name.text, element.messageKind, element.messageArguments,
- infos: element.computeInfos(enclosingElement, reporter));
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
- // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
- AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
- return handleUpdate(node, name, accessSemantics);
- }
-
- /// Report access of an instance [member] from a non-instance context.
- AccessSemantics reportStaticInstanceAccess(Send node, Name name) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node, name.text, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name},
- isError: true);
- // TODO(johnniwinther): Support static instance access as an
- // [AccessSemantics].
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- return new StaticAccess.invalid(error);
- }
-
- /// Handle access of a parameter, local variable or local function.
- ResolutionResult handleLocalAccess(Send node, Name name, Element element) {
- ResolutionResult result = const NoneResult();
- AccessSemantics semantics = computeLocalAccessSemantics(node, element);
- Selector selector;
- if (node.isCall) {
- CallStructure callStructure =
- resolveArguments(node.argumentsNode).callStructure;
- selector = new Selector.call(name, callStructure);
- bool isIncompatibleInvoke = false;
- switch (semantics.kind) {
- case AccessKind.LOCAL_FUNCTION:
- LocalFunctionElementX function = semantics.element;
- function.computeType(resolution);
- if (!callStructure.signatureApplies(function.parameterStructure)) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- registry.registerDynamicUse(new DynamicUse(selector));
- isIncompatibleInvoke = true;
- }
- break;
- case AccessKind.PARAMETER:
- case AccessKind.FINAL_PARAMETER:
- case AccessKind.LOCAL_VARIABLE:
- case AccessKind.FINAL_LOCAL_VARIABLE:
- selector = callStructure.callSelector;
- registry.registerDynamicUse(new DynamicUse(selector));
- break;
- default:
- reporter.internalError(node, "Unexpected local access $semantics.");
- break;
- }
- registry.registerSendStructure(
- node,
- isIncompatibleInvoke
- ? new IncompatibleInvokeStructure(semantics, selector)
- : new InvokeStructure(semantics, selector));
- } else {
- switch (semantics.kind) {
- case AccessKind.LOCAL_VARIABLE:
- case AccessKind.LOCAL_FUNCTION:
- result = new ElementResult(element);
- break;
- case AccessKind.PARAMETER:
- case AccessKind.FINAL_PARAMETER:
- if (constantState == ConstantState.CONSTANT_INITIALIZER) {
- ParameterElement parameter = element;
- if (parameter.isNamed) {
- result = new ConstantResult(
- node, new NamedArgumentReference(parameter.name),
- element: element);
- } else {
- result = new ConstantResult(
- node,
- new PositionalArgumentReference(parameter
- .functionDeclaration.parameters
- .indexOf(parameter)),
- element: element);
- }
- } else {
- result = new ElementResult(element);
- }
- break;
- case AccessKind.FINAL_LOCAL_VARIABLE:
- if (element.isConst) {
- LocalVariableElement local = element;
- result = new ConstantResult(
- node, new LocalVariableConstantExpression(local),
- element: element);
- } else {
- result = new ElementResult(element);
- }
- break;
- default:
- reporter.internalError(node, "Unexpected local access $semantics.");
- break;
- }
- selector = new Selector.getter(name);
- registry.registerSendStructure(node, new GetStructure(semantics));
- }
-
- // TODO(23998): Remove these when all information goes through
- // the [SendStructure].
- registry.useElement(node, element);
- registry.setSelector(node, selector);
-
- registerPotentialAccessInClosure(node, element);
-
- return result;
- }
-
- /// Handle update of a parameter, local variable or local function.
- ResolutionResult handleLocalUpdate(Send node, Name name, Element element) {
- AccessSemantics semantics;
- ErroneousElement error;
- if (element.isRegularParameter) {
- if (element.isFinal) {
- error = reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
- semantics = new StaticAccess.finalParameter(element);
- } else {
- semantics = new StaticAccess.parameter(element);
- }
- } else if (element.isInitializingFormal) {
- error = reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
- semantics = new StaticAccess.finalParameter(element);
- } else if (element.isVariable) {
- if (element.isFinal || element.isConst) {
- error = reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
- semantics = new StaticAccess.finalLocalVariable(element);
- } else {
- semantics = new StaticAccess.localVariable(element);
- }
- } else {
- assert(element.isFunction, failedAt(node, "Unexpected local $element."));
- error = reportAndCreateErroneousElement(
- node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {});
- semantics = new StaticAccess.localFunction(element);
- }
- if (isPotentiallyMutableTarget(element)) {
- registry.registerPotentialMutation(element, node);
- if (enclosingElement != element.enclosingElement) {
- registry.registerPotentialMutationInClosure(element, node);
- }
- for (Node scope in promotionScope) {
- registry.registerPotentialMutationIn(scope, element, node);
- }
- }
-
- ResolutionResult result = handleUpdate(node, name, semantics);
- if (error != null) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- // TODO(23998): Remove this when all information goes through
- // the [SendStructure].
- registry.useElement(node, error);
- }
- return result;
- }
-
- /// Handle access of a static or top level [element].
- ResolutionResult handleStaticOrTopLevelAccess(
- Send node, Name name, Element element) {
- ResolutionResult result = const NoneResult();
- MemberElement member;
- if (element.isAbstractField) {
- AbstractFieldElement abstractField = element;
- if (abstractField.getter != null) {
- member = abstractField.getter;
- } else {
- member = abstractField.setter;
- }
- } else {
- member = element;
- }
- // TODO(johnniwinther): Needed to provoke a parsing and with it discovery
- // of parse errors to make [element] erroneous. Fix this!
- member.computeType(resolution);
-
- if (resolution.commonElements.isMirrorSystemGetNameFunction(member) &&
- !resolution.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
- reporter.reportHintMessage(
- node.selector, MessageKind.STATIC_FUNCTION_BLOAT, {
- 'class': resolution.commonElements.mirrorSystemClass.name,
- 'name': member.name
- });
- }
-
- Selector selector;
- AccessSemantics semantics =
- computeStaticOrTopLevelAccessSemantics(node, member);
- if (node.isCall) {
- ArgumentsResult argumentsResult = resolveArguments(node.argumentsNode);
- CallStructure callStructure = argumentsResult.callStructure;
- selector = new Selector.call(name, callStructure);
-
- bool isIncompatibleInvoke = false;
- switch (semantics.kind) {
- case AccessKind.STATIC_METHOD:
- case AccessKind.TOPLEVEL_METHOD:
- MethodElement method = semantics.element;
- method.computeType(resolution);
- if (!callStructure.signatureApplies(method.parameterStructure)) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- registry.registerDynamicUse(new DynamicUse(selector));
- isIncompatibleInvoke = true;
- } else {
- registry.registerStaticUse(
- new StaticUse.staticInvoke(method, callStructure));
- handleForeignCall(node, semantics.element, callStructure);
- if (method == resolution.commonElements.identicalFunction &&
- argumentsResult.isValidAsConstant) {
- result = new ConstantResult(
- node,
- new IdenticalConstantExpression(
- argumentsResult.argumentResults[0].constant,
- argumentsResult.argumentResults[1].constant));
- }
- }
- break;
- case AccessKind.STATIC_FIELD:
- case AccessKind.FINAL_STATIC_FIELD:
- case AccessKind.STATIC_GETTER:
- case AccessKind.TOPLEVEL_FIELD:
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- case AccessKind.TOPLEVEL_GETTER:
- MemberElement member = semantics.element;
- registry.registerStaticUse(new StaticUse.staticGet(member));
- selector = callStructure.callSelector;
- registry.registerDynamicUse(new DynamicUse(selector));
- break;
- case AccessKind.STATIC_SETTER:
- case AccessKind.TOPLEVEL_SETTER:
- case AccessKind.UNRESOLVED:
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- member = reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name});
- break;
- default:
- reporter.internalError(
- node, "Unexpected statically resolved access $semantics.");
- break;
- }
- registry.registerSendStructure(
- node,
- isIncompatibleInvoke
- ? new IncompatibleInvokeStructure(semantics, selector)
- : new InvokeStructure(semantics, selector));
- } else {
- selector = new Selector.getter(name);
- switch (semantics.kind) {
- case AccessKind.STATIC_METHOD:
- case AccessKind.TOPLEVEL_METHOD:
- MethodElement method = semantics.element;
- registry.registerStaticUse(new StaticUse.staticTearOff(method));
- break;
- case AccessKind.STATIC_FIELD:
- case AccessKind.FINAL_STATIC_FIELD:
- case AccessKind.STATIC_GETTER:
- case AccessKind.TOPLEVEL_FIELD:
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- case AccessKind.TOPLEVEL_GETTER:
- MemberElement member = semantics.element;
- registry.registerStaticUse(new StaticUse.staticGet(member));
- break;
- case AccessKind.STATIC_SETTER:
- case AccessKind.TOPLEVEL_SETTER:
- case AccessKind.UNRESOLVED:
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- member = reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name});
- break;
- default:
- reporter.internalError(
- node, "Unexpected statically resolved access $semantics.");
- break;
- }
- registry.registerSendStructure(node, new GetStructure(semantics));
- if (member.isConst) {
- FieldElement field = member;
- result = new ConstantResult(node, new FieldConstantExpression(field),
- element: field);
- } else {
- result = new ElementResult(member);
- }
- }
-
- // TODO(23998): Remove these when all information goes through
- // the [SendStructure].
- registry.useElement(node, member);
- registry.setSelector(node, selector);
-
- return result;
- }
-
- /// Handle update of a static or top level [element].
- ResolutionResult handleStaticOrTopLevelUpdate(
- SendSet node, Name name, Element element) {
- AccessSemantics semantics;
- if (element.isAbstractField) {
- AbstractFieldElement abstractField = element;
- if (abstractField.setter == null) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node.selector,
- name.text,
- MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER,
- {'name': name});
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
- if (node.isComplex) {
- // `a++` or `a += b` where `a` has no setter.
- semantics = new CompoundAccessSemantics(
- element.isTopLevel
- ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER
- : CompoundAccessKind.UNRESOLVED_STATIC_SETTER,
- abstractField.getter,
- error);
- } else {
- // `a = b` where `a` has no setter.
- semantics = element.isTopLevel
- ? new StaticAccess.topLevelGetter(abstractField.getter)
- : new StaticAccess.staticGetter(abstractField.getter);
- }
- registry
- .registerStaticUse(new StaticUse.staticGet(abstractField.getter));
- } else if (node.isComplex) {
- if (abstractField.getter == null) {
- ErroneousElement error = reportAndCreateErroneousElement(
- node.selector,
- name.text,
- MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER,
- {'name': name});
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- // `a++` or `a += b` where `a` has no getter.
- semantics = new CompoundAccessSemantics(
- element.isTopLevel
- ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER
- : CompoundAccessKind.UNRESOLVED_STATIC_GETTER,
- error,
- abstractField.setter);
- registry
- .registerStaticUse(new StaticUse.staticSet(abstractField.setter));
- } else {
- // `a++` or `a += b` where `a` has both a getter and a setter.
- semantics = new CompoundAccessSemantics(
- element.isTopLevel
- ? CompoundAccessKind.TOPLEVEL_GETTER_SETTER
- : CompoundAccessKind.STATIC_GETTER_SETTER,
- abstractField.getter,
- abstractField.setter);
- registry
- .registerStaticUse(new StaticUse.staticGet(abstractField.getter));
- registry
- .registerStaticUse(new StaticUse.staticSet(abstractField.setter));
- }
- } else {
- // `a = b` where `a` has a setter.
- semantics = element.isTopLevel
- ? new StaticAccess.topLevelSetter(abstractField.setter)
- : new StaticAccess.staticSetter(abstractField.setter);
- registry
- .registerStaticUse(new StaticUse.staticSet(abstractField.setter));
- }
- } else {
- MemberElement member = element;
- // TODO(johnniwinther): Needed to provoke a parsing and with it discovery
- // of parse errors to make [element] erroneous. Fix this!
- member.computeType(resolution);
- if (member.isMalformed) {
- // [member] has parse errors.
- semantics = new StaticAccess.unresolved(member);
- } else if (member.isFunction) {
- // `a = b`, `a++` or `a += b` where `a` is a function.
- MethodElement method = member;
- reportAndCreateErroneousElement(
- node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {});
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- if (node.isComplex) {
- // `a++` or `a += b` where `a` is a function.
- registry.registerStaticUse(new StaticUse.staticTearOff(method));
- }
- semantics = member.isTopLevel
- ? new StaticAccess.topLevelMethod(method)
- : new StaticAccess.staticMethod(method);
- } else {
- // `a = b`, `a++` or `a += b` where `a` is a field.
- assert(member.isField, failedAt(node, "Unexpected element: $member."));
- if (node.isComplex) {
- // `a++` or `a += b` where `a` is a field.
- registry.registerStaticUse(new StaticUse.staticGet(member));
- }
- if (member.isFinal || member.isConst) {
- reportAndCreateErroneousElement(node.selector, name.text,
- MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- semantics = member.isTopLevel
- ? new StaticAccess.finalTopLevelField(member)
- : new StaticAccess.finalStaticField(member);
- } else {
- registry.registerStaticUse(new StaticUse.staticSet(member));
- semantics = member.isTopLevel
- ? new StaticAccess.topLevelField(member)
- : new StaticAccess.staticField(member);
- }
- }
- }
- return handleUpdate(node, name, semantics);
- }
-
- /// Handle access to resolved [element].
- ResolutionResult handleResolvedSend(Send node, Name name, Element element) {
- if (element.isAmbiguous) {
- return handleAmbiguousSend(node, name, element);
- }
- if (element.isMalformed) {
- // This handles elements with parser errors.
- assert(element is! ErroneousElement,
- failedAt(node, "Unexpected erroneous element $element."));
- return handleErroneousAccess(
- node, name, new StaticAccess.unresolved(element));
- }
- if (element.isInstanceMember) {
- if (inInstanceContext) {
- // TODO(johnniwinther): Maybe use the found [element].
- return handleThisPropertyAccess(node, name);
- } else {
- return handleErroneousAccess(
- node, name, reportStaticInstanceAccess(node, name));
- }
- }
- if (element.isClass) {
- // `C`, `C()`, or 'C.b` where 'C' is a class.
- return handleClassSend(node, name, element);
- } else if (element.isTypedef) {
- // `F` or `F()` where 'F' is a typedef.
- return handleTypedefTypeLiteralAccess(node, name, element);
- } else if (element.isTypeVariable) {
- return handleTypeVariableTypeLiteralAccess(node, name, element);
- } else if (element.isPrefix) {
- return handleLibraryPrefix(node, name, element);
- } else if (element.isLocal) {
- return handleLocalAccess(node, name, element);
- } else if (element.isStatic || element.isTopLevel) {
- return handleStaticOrTopLevelAccess(node, name, element);
- }
- return reporter.internalError(node, "Unexpected resolved send: $element");
- }
-
- /// Handle update to resolved [element].
- ResolutionResult handleResolvedSendSet(
- SendSet node, Name name, Element element) {
- if (element.isAmbiguous) {
- return handleAmbiguousUpdate(node, name, element);
- }
- if (element.isMalformed) {
- // This handles elements with parser errors..
- assert(element is! ErroneousElement,
- failedAt(node, "Unexpected erroneous element $element."));
- return handleUpdate(node, name, new StaticAccess.unresolved(element));
- }
- if (element.isInstanceMember) {
- if (inInstanceContext) {
- return handleThisPropertyUpdate(node, name, element);
- } else {
- return handleUpdate(node, name, reportStaticInstanceAccess(node, name));
- }
- }
- if (element.isClass) {
- // `C = b`, `C++`, or 'C += b` where 'C' is a class.
- return handleClassTypeLiteralUpdate(node, name, element);
- } else if (element.isTypedef) {
- // `C = b`, `C++`, or 'C += b` where 'F' is a typedef.
- return handleTypedefTypeLiteralUpdate(node, name, element);
- } else if (element.isTypeVariable) {
- // `T = b`, `T++`, or 'T += b` where 'T' is a type variable.
- return handleTypeVariableTypeLiteralUpdate(node, name, element);
- } else if (element.isPrefix) {
- // `p = b` where `p` is a prefix.
- ErroneousElement error = reportAndCreateErroneousElement(
- node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name},
- isError: true);
- registry.registerFeature(Feature.COMPILE_TIME_ERROR);
- return handleUpdate(node, name, new StaticAccess.invalid(error));
- } else if (element.isLocal) {
- return handleLocalUpdate(node, name, element);
- } else if (element.isStatic || element.isTopLevel) {
- return handleStaticOrTopLevelUpdate(node, name, element);
- }
- return reporter.internalError(node, "Unexpected resolved send: $element");
- }
-
- /// Handle an unqualified [Send], that is where the `node.receiver` is null,
- /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`.
- ResolutionResult handleUnqualifiedSend(Send node) {
- Identifier selector = node.selector.asIdentifier();
- if (selector == null) {
- // `(){}()` and `(foo)()`.
- return handleExpressionInvoke(node);
- }
- String text = selector.source;
- if (text == 'this') {
- // `this()`.
- return handleThisAccess(node);
- }
- // `name` or `name()`
- Name name = new Name(text, enclosingElement.library);
- Element element = lookupInScope(reporter, node, scope, text);
- if (element == null) {
- if (text == 'dynamic') {
- // `dynamic` or `dynamic()` where 'dynamic' is not declared in the
- // current scope.
- return handleDynamicTypeLiteralAccess(node);
- } else if (inInstanceContext) {
- // Implicitly `this.name`.
- return handleThisPropertyAccess(node, name);
- } else {
- // Create [ErroneousElement] for unresolved access.
- ErroneousElement error = reportCannotResolve(node, text);
- return handleUnresolvedAccess(node, name, error);
- }
- } else {
- return handleResolvedSend(node, name, element);
- }
- }
-
- /// Handle an unqualified [SendSet], that is where the `node.receiver` is
- /// null, like `a = b`, `a++`, and `a += b`.
- ResolutionResult handleUnqualifiedSendSet(SendSet node) {
- Identifier selector = node.selector.asIdentifier();
- String text = selector.source;
- Name name = new Name(text, enclosingElement.library);
- Element element = lookupInScope(reporter, node, scope, text);
- if (element == null) {
- if (text == 'dynamic') {
- // `dynamic = b`, `dynamic++`, or `dynamic += b` where 'dynamic' is not
- // declared in the current scope.
- return handleDynamicTypeLiteralUpdate(node);
- } else if (inInstanceContext) {
- // Left-hand side is implicitly `this.name`.
- return handleThisPropertyUpdate(node, name, null);
- } else {
- // Create [ErroneousElement] for unresolved access.
- ErroneousElement error = reportCannotResolve(node, text);
- return handleUpdate(node, name, new StaticAccess.unresolved(error));
- }
- } else {
- return handleResolvedSendSet(node, name, element);
- }
- }
-
- ResolutionResult visitSend(Send node) {
- // Resolve type arguments to ensure that these are well-formed types.
- if (node.typeArgumentsNode != null) {
- for (TypeAnnotation type in node.typeArgumentsNode.nodes) {
- resolveTypeAnnotation(type, registerCheckedModeCheck: false);
- }
- }
- if (node.isOperator) {
- // `a && b`, `a + b`, `-a`, or `a is T`.
- return handleOperatorSend(node);
- } else if (node.receiver != null) {
- // `a.b`.
- return handleQualifiedSend(node);
- } else {
- // `a`.
- return handleUnqualifiedSend(node);
- }
- }
-
- /// Register read access of [target] inside a closure.
- void registerPotentialAccessInClosure(Send node, Element target) {
- if (isPotentiallyMutableTarget(target)) {
- if (enclosingElement != target.enclosingElement) {
- for (Node scope in promotionScope) {
- registry.setAccessedByClosureIn(scope, target, node);
- }
- }
- }
- }
-
- // TODO(johnniwinther): Move this to the backend resolution callbacks.
- void handleForeignCall(
- Send node, Element target, CallStructure callStructure) {
- if (target != null && resolution.target.isForeign(target)) {
- registry.registerForeignCall(node, target, callStructure, this);
- }
- }
-
- /// Callback for native enqueuer to parse a type. Returns [:null:] on error.
- ResolutionDartType resolveTypeFromString(Node node, String typeName) {
- Element element = lookupInScope(reporter, node, scope, typeName);
- if (element == null) return null;
- if (element is! ClassElement) return null;
- ClassElement cls = element;
- cls.ensureResolved(resolution);
- cls.computeType(resolution);
- return cls.rawType;
- }
-
- /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`.
- ResolutionResult handleIndexSendSet(SendSet node) {
- String operatorText = node.assignmentOperator.source;
- Node receiver = node.receiver;
- Node index = node.arguments.head;
- visitExpression(receiver);
- visitExpression(index);
- AccessSemantics semantics = const DynamicAccess.expression();
- if (node.isPrefix || node.isPostfix) {
- // `a[b]++` or `++a[b]`.
- IncDecOperator operator = IncDecOperator.parse(operatorText);
- Selector getterSelector = new Selector.index();
- Selector setterSelector = new Selector.indexSet();
- Selector operatorSelector =
- new Selector.binaryOperator(operator.selectorName);
-
- // TODO(23998): Remove these when selectors are only accessed
- // through the send structure.
- registry.setGetterSelectorInComplexSendSet(node, getterSelector);
- registry.setSelector(node, setterSelector);
- registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
- registry.registerDynamicUse(new DynamicUse(getterSelector));
- registry.registerDynamicUse(new DynamicUse(setterSelector));
- registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
- SendStructure sendStructure = node.isPrefix
- ? new IndexPrefixStructure(semantics, operator)
- : new IndexPostfixStructure(semantics, operator);
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- } else {
- Node rhs = node.arguments.tail.head;
- visitExpression(rhs);
-
- AssignmentOperator operator = AssignmentOperator.parse(operatorText);
- if (operator.kind == AssignmentOperatorKind.ASSIGN) {
- // `a[b] = c`.
- Selector setterSelector = new Selector.indexSet();
-
- // TODO(23998): Remove this when selectors are only accessed
- // through the send structure.
- registry.setSelector(node, setterSelector);
- registry.registerDynamicUse(new DynamicUse(setterSelector));
-
- SendStructure sendStructure = new IndexSetStructure(semantics);
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- } else {
- // `a[b] += c`.
- Selector getterSelector = new Selector.index();
- Selector setterSelector = new Selector.indexSet();
- Selector operatorSelector =
- new Selector.binaryOperator(operator.selectorName);
-
- // TODO(23998): Remove these when selectors are only accessed
- // through the send structure.
- registry.setGetterSelectorInComplexSendSet(node, getterSelector);
- registry.setSelector(node, setterSelector);
- registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
- registry.registerDynamicUse(new DynamicUse(getterSelector));
- registry.registerDynamicUse(new DynamicUse(setterSelector));
- registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
- SendStructure sendStructure;
- if (operator.kind == AssignmentOperatorKind.IF_NULL) {
- sendStructure = new IndexSetIfNullStructure(semantics);
- } else {
- sendStructure = new CompoundIndexSetStructure(semantics, operator);
- }
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- }
- }
- }
-
- /// Handle super index operations like `super[a] = b`, `super[a] += b`, and
- /// `super[a]++`.
- // TODO(johnniwinther): Share code with [handleIndexSendSet].
- ResolutionResult handleSuperIndexSendSet(SendSet node) {
- String operatorText = node.assignmentOperator.source;
- Node index = node.arguments.head;
- visitExpression(index);
-
- AccessSemantics semantics = checkSuperAccess(node);
- if (node.isPrefix || node.isPostfix) {
- // `super[a]++` or `++super[a]`.
- IncDecOperator operator = IncDecOperator.parse(operatorText);
- Selector getterSelector = new Selector.index();
- Selector setterSelector = new Selector.indexSet();
- Selector operatorSelector =
- new Selector.binaryOperator(operator.selectorName);
-
- // TODO(23998): Remove these when selectors are only accessed
- // through the send structure.
- registry.setGetterSelectorInComplexSendSet(node, getterSelector);
- registry.setSelector(node, setterSelector);
- registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelectors(
- node, getterSelector, setterSelector,
- isIndex: true);
-
- if (!semantics.getter.isError) {
- MethodElement getter = semantics.getter;
- registry.registerStaticUse(
- new StaticUse.superInvoke(getter, getterSelector.callStructure));
- }
- if (!semantics.setter.isError) {
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(
- new StaticUse.superInvoke(setter, setterSelector.callStructure));
- }
-
- // TODO(23998): Remove these when elements are only accessed
- // through the send structure.
- registry.useElement(node, semantics.setter);
- registry.useElement(node.selector, semantics.getter);
- }
- registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
- SendStructure sendStructure = node.isPrefix
- ? new IndexPrefixStructure(semantics, operator)
- : new IndexPostfixStructure(semantics, operator);
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- } else {
- Node rhs = node.arguments.tail.head;
- visitExpression(rhs);
-
- AssignmentOperator operator = AssignmentOperator.parse(operatorText);
- if (operator.kind == AssignmentOperatorKind.ASSIGN) {
- // `super[a] = b`.
- Selector setterSelector = new Selector.indexSet();
- if (semantics == null) {
- semantics =
- computeSuperAccessSemanticsForSelector(node, setterSelector);
-
- // TODO(23998): Remove these when elements are only accessed
- // through the send structure.
- registry.useElement(node, semantics.setter);
- }
-
- // TODO(23998): Remove this when selectors are only accessed
- // through the send structure.
- registry.setSelector(node, setterSelector);
- if (!semantics.setter.isError) {
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(
- new StaticUse.superInvoke(setter, setterSelector.callStructure));
- }
-
- SendStructure sendStructure = new IndexSetStructure(semantics);
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- } else {
- // `super[a] += b`.
- Selector getterSelector = new Selector.index();
- Selector setterSelector = new Selector.indexSet();
- Selector operatorSelector =
- new Selector.binaryOperator(operator.selectorName);
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelectors(
- node, getterSelector, setterSelector,
- isIndex: true);
-
- if (!semantics.getter.isError) {
- MethodElement getter = semantics.getter;
- registry.registerStaticUse(new StaticUse.superInvoke(
- getter, getterSelector.callStructure));
- }
- if (!semantics.setter.isError) {
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(new StaticUse.superInvoke(
- setter, setterSelector.callStructure));
- }
-
- // TODO(23998): Remove these when elements are only accessed
- // through the send structure.
- registry.useElement(node, semantics.setter);
- registry.useElement(node.selector, semantics.getter);
- }
-
- // TODO(23998): Remove these when selectors are only accessed
- // through the send structure.
- registry.setGetterSelectorInComplexSendSet(node, getterSelector);
- registry.setSelector(node, setterSelector);
- registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
- registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
- SendStructure sendStructure;
- if (operator.kind == AssignmentOperatorKind.IF_NULL) {
- sendStructure = new IndexSetIfNullStructure(semantics);
- } else {
- sendStructure = new CompoundIndexSetStructure(semantics, operator);
- }
- registry.registerSendStructure(node, sendStructure);
- return const NoneResult();
- }
- }
- }
-
- /// Handle super index operations like `super.a = b`, `super.a += b`, and
- /// `super.a++`.
- // TODO(johnniwinther): Share code with [handleSuperIndexSendSet].
- ResolutionResult handleSuperSendSet(SendSet node) {
- Identifier selector = node.selector.asIdentifier();
- String text = selector.source;
- Name name = new Name(text, enclosingElement.library);
- String operatorText = node.assignmentOperator.source;
- Selector getterSelector = new Selector.getter(name);
- Selector setterSelector = new Selector.setter(name);
-
- void registerStaticUses(AccessSemantics semantics) {
- switch (semantics.kind) {
- case AccessKind.SUPER_METHOD:
- MethodElement method = semantics.element;
- registry.registerStaticUse(new StaticUse.superTearOff(method));
- break;
- case AccessKind.SUPER_GETTER:
- MethodElement getter = semantics.getter;
- registry.registerStaticUse(new StaticUse.superGet(getter));
- break;
- case AccessKind.SUPER_SETTER:
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(new StaticUse.superSetterSet(setter));
- break;
- case AccessKind.SUPER_FIELD:
- FieldElement field = semantics.element;
- registry.registerStaticUse(new StaticUse.superGet(field));
- registry.registerStaticUse(new StaticUse.superFieldSet(field));
- break;
- case AccessKind.SUPER_FINAL_FIELD:
- FieldElement field = semantics.element;
- registry.registerStaticUse(new StaticUse.superGet(field));
- break;
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.SUPER_GETTER_FIELD:
- case CompoundAccessKind.SUPER_FIELD_FIELD:
- MemberElement getter = semantics.getter;
- FieldElement setter = semantics.setter;
- registry.registerStaticUse(new StaticUse.superGet(getter));
- registry.registerStaticUse(new StaticUse.superFieldSet(setter));
- break;
- case CompoundAccessKind.SUPER_FIELD_SETTER:
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- MemberElement getter = semantics.getter;
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(new StaticUse.superGet(getter));
- registry.registerStaticUse(new StaticUse.superSetterSet(setter));
- break;
- case CompoundAccessKind.SUPER_METHOD_SETTER:
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(new StaticUse.superSetterSet(setter));
- break;
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(new StaticUse.superSetterSet(setter));
- break;
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- MethodElement getter = semantics.getter;
- registry.registerStaticUse(new StaticUse.superGet(getter));
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
-
- AccessSemantics semantics = checkSuperAccess(node);
- if (node.isPrefix || node.isPostfix) {
- // `super.a++` or `++super.a`.
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelectors(
- node, getterSelector, setterSelector);
- registerStaticUses(semantics);
- }
- return handleUpdate(node, name, semantics);
- } else {
- AssignmentOperator operator = AssignmentOperator.parse(operatorText);
- if (operator.kind == AssignmentOperatorKind.ASSIGN) {
- // `super.a = b`.
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelector(
- node, setterSelector,
- alternateName: name);
- switch (semantics.kind) {
- case AccessKind.SUPER_FINAL_FIELD:
- reporter.reportWarningMessage(
- node, MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, {
- 'name': name,
- 'superclassName': semantics.setter.enclosingClass.name
- });
- // TODO(johnniwinther): This shouldn't be needed.
- registry.registerDynamicUse(new DynamicUse(setterSelector));
- registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
- break;
- case AccessKind.SUPER_METHOD:
- reporter.reportWarningMessage(
- node, MessageKind.ASSIGNING_METHOD_IN_SUPER, {
- 'name': name,
- 'superclassName': semantics.setter.enclosingClass.name
- });
- // TODO(johnniwinther): This shouldn't be needed.
- registry.registerDynamicUse(new DynamicUse(setterSelector));
- registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
- break;
- case AccessKind.SUPER_FIELD:
- FieldElement field = semantics.setter;
- registry.registerStaticUse(new StaticUse.superFieldSet(field));
- break;
- case AccessKind.SUPER_SETTER:
- MethodElement setter = semantics.setter;
- registry.registerStaticUse(new StaticUse.superSetterSet(setter));
- break;
- default:
- break;
- }
- }
- return handleUpdate(node, name, semantics);
- } else {
- // `super.a += b`.
- if (semantics == null) {
- semantics = computeSuperAccessSemanticsForSelectors(
- node, getterSelector, setterSelector);
- registerStaticUses(semantics);
- }
- return handleUpdate(node, name, semantics);
- }
- }
- }
-
- /// Handle update of an entity defined by [semantics]. For instance `a = b`,
- /// `a++` or `a += b` where [semantics] describe `a`.
- ResolutionResult handleUpdate(
- SendSet node, Name name, AccessSemantics semantics) {
- String operatorText = node.assignmentOperator.source;
- Selector getterSelector = new Selector.getter(name);
- Selector setterSelector = new Selector.setter(name);
- if (node.isPrefix || node.isPostfix) {
- // `e++` or `++e`.
- IncDecOperator operator = IncDecOperator.parse(operatorText);
- Selector operatorSelector =
- new Selector.binaryOperator(operator.selectorName);
-
- // TODO(23998): Remove these when selectors are only accessed
- // through the send structure.
- registry.setGetterSelectorInComplexSendSet(node, getterSelector);
- registry.setSelector(node, setterSelector);
- registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
- // TODO(23998): Remove these when elements are only accessed
- // through the send structure.
- registry.useElement(node, semantics.setter);
- registry.useElement(node.selector, semantics.getter);
-
- registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
- SendStructure sendStructure = node.isPrefix
- ? new PrefixStructure(semantics, operator)
- : new PostfixStructure(semantics, operator);
- registry.registerSendStructure(node, sendStructure);
- registry.registerConstantLiteral(new IntConstantExpression(1));
- } else {
- Node rhs = node.arguments.head;
- visitExpression(rhs);
-
- AssignmentOperator operator = AssignmentOperator.parse(operatorText);
- if (operator.kind == AssignmentOperatorKind.ASSIGN) {
- // `e1 = e2`.
-
- // TODO(23998): Remove these when elements are only accessed
- // through the send structure.
- registry.useElement(node, semantics.setter);
-
- // TODO(23998): Remove this when selectors are only accessed
- // through the send structure.
- registry.setSelector(node, setterSelector);
-
- SendStructure sendStructure = new SetStructure(semantics);
- registry.registerSendStructure(node, sendStructure);
- } else {
- // `e1 += e2`.
- Selector operatorSelector =
- new Selector.binaryOperator(operator.selectorName);
-
- // TODO(23998): Remove these when elements are only accessed
- // through the send structure.
- registry.useElement(node, semantics.setter);
- registry.useElement(node.selector, semantics.getter);
-
- // TODO(23998): Remove these when selectors are only accessed
- // through the send structure.
- registry.setGetterSelectorInComplexSendSet(node, getterSelector);
- registry.setSelector(node, setterSelector);
- registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
- SendStructure sendStructure;
- if (operator.kind == AssignmentOperatorKind.IF_NULL) {
- registry.registerConstantLiteral(new NullConstantExpression());
- registry.registerDynamicUse(new DynamicUse(Selectors.equals));
- sendStructure = new SetIfNullStructure(semantics);
- } else {
- registry.registerDynamicUse(new DynamicUse(operatorSelector));
- sendStructure = new CompoundStructure(semantics, operator);
- }
- registry.registerSendStructure(node, sendStructure);
- }
- }
- return new ResolutionResult.forElement(semantics.setter);
- }
-
- ResolutionResult visitSendSet(SendSet node) {
- if (node.isIndex) {
- // `a[b] = c`
- if (node.isSuperCall) {
- // `super[b] = c`
- return handleSuperIndexSendSet(node);
- } else {
- return handleIndexSendSet(node);
- }
- } else if (node.isSuperCall) {
- // `super.a = c`
- return handleSuperSendSet(node);
- } else if (node.receiver == null) {
- // `a = c`
- return handleUnqualifiedSendSet(node);
- } else {
- // `a.b = c`
- return handleQualifiedSendSet(node);
- }
- }
-
- ConstantResult visitLiteralInt(LiteralInt node) {
- ConstantExpression constant = new IntConstantExpression(node.value);
- registry.registerConstantLiteral(constant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
-
- ConstantResult visitLiteralDouble(LiteralDouble node) {
- ConstantExpression constant = new DoubleConstantExpression(node.value);
- registry.registerConstantLiteral(constant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
-
- ConstantResult visitLiteralBool(LiteralBool node) {
- ConstantExpression constant = new BoolConstantExpression(node.value);
- registry.registerConstantLiteral(constant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
-
- ResolutionResult visitLiteralString(LiteralString node) {
- if (node.dartString != null) {
- // [dartString] might be null on parser errors.
- ConstantExpression constant =
- new StringConstantExpression(node.dartString.slowToString());
- registry.registerConstantLiteral(constant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- return const NoneResult();
- }
-
- ConstantResult visitLiteralNull(LiteralNull node) {
- ConstantExpression constant = new NullConstantExpression();
- registry.registerConstantLiteral(constant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
-
- ConstantResult visitLiteralSymbol(LiteralSymbol node) {
- String name = node.slowNameString;
- // TODO(johnniwinther): Use [registerConstantLiteral] instead.
- registry.registerConstSymbol(name);
- if (!validateSymbol(node, name, reportError: false)) {
- reporter.reportErrorMessage(
- node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, {'value': name});
- }
- analyzeConstantDeferred(node);
- ConstantExpression constant = new SymbolConstantExpression(name);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
-
- ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) {
- registry.registerFeature(Feature.STRING_JUXTAPOSITION);
- ResolutionResult first = visit(node.first);
- ResolutionResult second = visit(node.second);
- if (first.isConstant && second.isConstant) {
- ConstantExpression constant = new ConcatenateConstantExpression(
- <ConstantExpression>[first.constant, second.constant]);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- return const NoneResult();
- }
-
- ResolutionResult visitNodeList(NodeList node) {
- for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
- visit(link.head);
- }
- return const NoneResult();
- }
-
- ResolutionResult visitRethrow(Rethrow node) {
- if (!inCatchBlock && node.throwToken.stringValue == 'rethrow') {
- reporter.reportErrorMessage(node, MessageKind.RETHROW_OUTSIDE_CATCH);
- }
- return const NoneResult();
- }
-
- ResolutionResult visitReturn(Return node) {
- Node expression = node.expression;
- if (expression != null) {
- if (enclosingElement.isGenerativeConstructor) {
- // It is a compile-time error if a return statement of the form
- // `return e;` appears in a generative constructor. (Dart Language
- // Specification 13.12.)
- reporter.reportErrorMessage(
- expression, MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR);
- } else if (!node.isArrowBody && currentAsyncMarker.isYielding) {
- reporter.reportErrorMessage(node, MessageKind.RETURN_IN_GENERATOR,
- {'modifier': currentAsyncMarker});
- }
- }
- visit(node.expression);
- return const NoneResult();
- }
-
- ResolutionResult visitYield(Yield node) {
- if (!resolution.target.supportsAsyncAwait) {
- reporter.reportErrorMessage(reporter.spanFromToken(node.yieldToken),
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
- } else {
- if (!currentAsyncMarker.isYielding) {
- reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
- }
- ClassElement cls;
- if (currentAsyncMarker.isAsync) {
- cls = commonElements.streamClass;
- } else {
- cls = commonElements.iterableClass;
- }
- cls.ensureResolved(resolution);
- }
- visit(node.expression);
- return const NoneResult();
- }
-
- ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) {
- if (!enclosingElement.isFactoryConstructor) {
- reporter.reportErrorMessage(
- node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
- reporter.reportHintMessage(
- enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
- }
-
- ConstructorElementX constructor = enclosingElement;
- bool isConstConstructor = constructor.isConst;
- bool isValidAsConstant = isConstConstructor;
- ConstructorResult result =
- resolveRedirectingFactory(node, inConstContext: isConstConstructor);
- ConstructorElement redirectionTarget = result.element;
- constructor.setImmediateRedirectionTarget(
- redirectionTarget, result.isDeferred ? result.prefix : null);
-
- registry.setRedirectingTargetConstructor(node, redirectionTarget);
- switch (result.kind) {
- case ConstructorResultKind.GENERATIVE:
- case ConstructorResultKind.FACTORY:
- // Register a post process to check for cycles in the redirection chain
- // and set the actual generative constructor at the end of the chain.
- addDeferredAction(constructor, () {
- resolver.resolveRedirectionChain(constructor, node);
- });
- break;
- case ConstructorResultKind.ABSTRACT:
- case ConstructorResultKind.INVALID_TYPE:
- case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
- case ConstructorResultKind.NON_CONSTANT:
- isValidAsConstant = false;
- constructor.setEffectiveTarget(result.element, result.type,
- isMalformed: true);
- break;
- }
- if (Elements.isUnresolved(redirectionTarget)) {
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- return const NoneResult();
- } else {
- if (isConstConstructor && !redirectionTarget.isConst) {
- reporter.reportErrorMessage(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
- isValidAsConstant = false;
- }
- if (redirectionTarget == constructor) {
- reporter.reportErrorMessage(
- node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
- // TODO(johnniwinther): Create constant constructor for this case and
- // let evaluation detect the cyclicity.
- isValidAsConstant = false;
- }
- }
-
- // Check that the target constructor is type compatible with the
- // redirecting constructor.
- ClassElement targetClass = redirectionTarget.enclosingClass;
- ResolutionInterfaceType type = registry.getType(node);
- ResolutionFunctionType targetConstructorType = redirectionTarget
- .computeType(resolution)
- .subst(type.typeArguments, targetClass.typeVariables);
- ResolutionFunctionType constructorType =
- constructor.computeType(resolution);
- bool isSubtype =
- resolution.types.isSubtype(targetConstructorType, constructorType);
- if (!isSubtype) {
- reporter.reportWarningMessage(node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': targetConstructorType, 'toType': constructorType});
- // TODO(johnniwinther): Handle this (potentially) erroneous case.
- isValidAsConstant = false;
- }
- if (type.typeArguments.any((ResolutionDartType type) => !type.isDynamic)) {
- registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
- }
-
- redirectionTarget.computeType(resolution);
- FunctionSignature targetSignature = redirectionTarget.functionSignature;
- constructor.computeType(resolution);
- FunctionSignature constructorSignature = constructor.functionSignature;
- if (!targetSignature.isCompatibleWith(constructorSignature)) {
- assert(!isSubtype);
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- isValidAsConstant = false;
- }
-
- registry.registerStaticUse(new StaticUse.constructorRedirect(
- redirectionTarget,
- redirectionTarget.enclosingClass.thisType
- .subst(type.typeArguments, targetClass.typeVariables)));
- if (resolution.commonElements.isSymbolConstructor(constructor)) {
- registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
- }
- if (isValidAsConstant) {
- List<String> names = <String>[];
- List<ConstantExpression> arguments = <ConstantExpression>[];
- int index = 0;
- constructorSignature.forEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- if (parameter.isNamed) {
- String name = parameter.name;
- names.add(name);
- arguments.add(new NamedArgumentReference(name));
- } else {
- arguments.add(new PositionalArgumentReference(index));
- }
- index++;
- });
- CallStructure callStructure =
- new CallStructure(constructorSignature.parameterCount, names);
- constructor.constantConstructor =
- new RedirectingFactoryConstantConstructor(
- new ConstructedConstantExpression(
- type, redirectionTarget, callStructure, arguments));
- }
- return const NoneResult();
- }
-
- ResolutionResult visitThrow(Throw node) {
- registry.registerFeature(Feature.THROW_EXPRESSION);
- visit(node.expression);
- return const NoneResult();
- }
-
- ResolutionResult visitAwait(Await node) {
- if (!resolution.target.supportsAsyncAwait) {
- reporter.reportErrorMessage(reporter.spanFromToken(node.awaitToken),
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
- } else {
- if (!currentAsyncMarker.isAsync) {
- reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
- }
- ClassElement futureClass = commonElements.futureClass;
- futureClass.ensureResolved(resolution);
- }
- visit(node.expression);
- return const NoneResult();
- }
-
- ResolutionResult visitVariableDefinitions(VariableDefinitions node) {
- ResolutionDartType type;
- if (node.type != null) {
- type = resolveTypeAnnotation(node.type);
- } else {
- type = const ResolutionDynamicType();
- }
- VariableList variables = new VariableList.node(node, type);
- VariableDefinitionsVisitor visitor =
- new VariableDefinitionsVisitor(resolution, node, this, variables);
-
- Modifiers modifiers = node.modifiers;
- void reportExtraModifier(String modifier) {
- Node modifierNode;
- for (Link<Node> nodes = modifiers.nodes.nodes;
- !nodes.isEmpty;
- nodes = nodes.tail) {
- if (modifier == nodes.head.asIdentifier().source) {
- modifierNode = nodes.head;
- break;
- }
- }
- assert(modifierNode != null);
- reporter.reportErrorMessage(modifierNode, MessageKind.EXTRANEOUS_MODIFIER,
- {'modifier': modifier});
- }
-
- if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) {
- reportExtraModifier('final');
- }
- if (modifiers.isVar && (modifiers.isConst || node.type != null)) {
- reportExtraModifier('var');
- }
- if (enclosingElement.isFunction || enclosingElement.isConstructor) {
- if (modifiers.isAbstract) {
- reportExtraModifier('abstract');
- }
- if (modifiers.isStatic) {
- reportExtraModifier('static');
- }
- }
- if (node.metadata != null) {
- variables.metadataInternal =
- resolver.resolveMetadata(enclosingElement, node);
- }
- visitor.visit(node.definitions);
- return const NoneResult();
- }
-
- ResolutionResult visitWhile(While node) {
- visit(node.condition);
- visitLoopBodyIn(node, node.body, new BlockScope(scope));
- return const NoneResult();
- }
-
- ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) {
- bool oldSendIsMemberAccess = sendIsMemberAccess;
- sendIsMemberAccess = false;
- var oldCategory = allowedCategory;
- allowedCategory = ElementCategory.VARIABLE |
- ElementCategory.FUNCTION |
- ElementCategory.IMPLIES_TYPE;
- ResolutionResult result = visit(node.expression);
- allowedCategory = oldCategory;
- sendIsMemberAccess = oldSendIsMemberAccess;
- if (result.kind == ResultKind.CONSTANT) {
- return result;
- }
- return const NoneResult();
- }
-
- ResolutionResult visitNewExpression(NewExpression node) {
- ConstructorResult result = resolveConstructor(node);
- ConstructorElement constructor = result.element;
- if (resolution.commonElements.isSymbolConstructor(constructor)) {
- registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
- }
- ArgumentsResult argumentsResult;
- if (node.isConst) {
- argumentsResult =
- inConstantContext(() => resolveArguments(node.send.argumentsNode));
- } else {
- if (!node.isConst && constructor.isFromEnvironmentConstructor) {
- // TODO(sigmund): consider turning this into a compile-time-error.
- reporter.reportHintMessage(
- node,
- MessageKind.FROM_ENVIRONMENT_MUST_BE_CONST,
- {'className': constructor.enclosingClass.name});
- registry.registerFeature(Feature.THROW_UNSUPPORTED_ERROR);
- }
- argumentsResult = resolveArguments(node.send.argumentsNode);
- }
- // TODO(johnniwinther): Avoid the need for a [Selector].
- Selector selector = resolveSelector(node.send, constructor);
- CallStructure callStructure = selector.callStructure;
- registry.useElement(node.send, constructor);
-
- ResolutionDartType type = result.type;
- ConstructorAccessKind kind;
- bool isInvalid = false;
- switch (result.kind) {
- case ConstructorResultKind.GENERATIVE:
- // Ensure that the signature of [constructor] has been computed.
- constructor.computeType(resolution);
- if (!callStructure.signatureApplies(constructor.parameterStructure)) {
- isInvalid = true;
- kind = ConstructorAccessKind.INCOMPATIBLE;
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- } else {
- kind = ConstructorAccessKind.GENERATIVE;
- }
- break;
- case ConstructorResultKind.FACTORY:
- // Ensure that the signature of [constructor] has been computed.
- constructor.computeType(resolution);
- if (!callStructure.signatureApplies(constructor.parameterStructure)) {
- // The effective target might still be valid(!) so the is not an
- // invalid case in itself. For instance
- //
- // class A {
- // factory A() = A.a;
- // A.a(a);
- // }
- // m() => new A(0); // This creates a warning but works at runtime.
- //
- registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
- }
- kind = ConstructorAccessKind.FACTORY;
- break;
- case ConstructorResultKind.ABSTRACT:
- isInvalid = true;
- kind = ConstructorAccessKind.ABSTRACT;
- break;
- case ConstructorResultKind.INVALID_TYPE:
- isInvalid = true;
- kind = ConstructorAccessKind.UNRESOLVED_TYPE;
- break;
- case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
- // TODO(johnniwinther): Unify codepaths to only have one return.
- ResolutionInterfaceType interfaceType = type;
- registry.registerNewStructure(
- node,
- new NewInvokeStructure(
- new ConstructorAccessSemantics(
- ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR,
- constructor,
- interfaceType),
- selector));
- return new ResolutionResult.forElement(constructor);
- case ConstructorResultKind.NON_CONSTANT:
- ResolutionInterfaceType interfaceType = type;
- registry.registerNewStructure(
- node,
- new NewInvokeStructure(
- new ConstructorAccessSemantics(
- ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR,
- constructor,
- interfaceType),
- selector));
- return new ResolutionResult.forElement(constructor);
- }
-
- if (!isInvalid) {
- // [constructor] might be the implementation element
- // and only declaration elements may be registered.
- // TODO(johniwinther): Avoid registration of `type` in face of redirecting
- // factory constructors.
- ResolutionInterfaceType interfaceType = type;
- ConstructorElement declaration = constructor.declaration;
- registry.registerStaticUse(node.isConst
- ? new StaticUse.constConstructorInvoke(
- declaration, callStructure, interfaceType)
- : new StaticUse.typedConstructorInvoke(
- constructor, callStructure, interfaceType));
- if (interfaceType.typeArguments
- .any((ResolutionDartType type) => !type.isDynamic)) {
- registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
- }
- }
-
- ResolutionResult resolutionResult = const NoneResult();
- if (node.isConst) {
- bool isValidAsConstant = !isInvalid && constructor.isConst;
-
- CommonElements commonElements = resolution.commonElements;
- if (commonElements.isSymbolConstructor(constructor)) {
- Node argumentNode = node.send.arguments.head;
- ConstantExpression constant = resolver.constantCompiler
- .compileNode(argumentNode, registry.mapping);
- ConstantValue name = resolution.constants.getConstantValue(constant);
- if (!name.isString) {
- ResolutionDartType type = name.getType(commonElements);
- reporter.reportErrorMessage(
- argumentNode, MessageKind.STRING_EXPECTED, {'type': type});
- } else {
- StringConstantValue stringConstant = name;
- String nameString = stringConstant.stringValue;
- if (validateSymbol(argumentNode, nameString)) {
- registry.registerConstSymbol(nameString);
- }
- }
- } else if (commonElements.isMirrorsUsedConstructor(constructor)) {
- resolution.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
- }
-
- analyzeConstantDeferred(node);
-
- if (type.containsTypeVariables) {
- reporter.reportErrorMessage(
- node.send.selector, MessageKind.TYPE_VARIABLE_IN_CONSTANT);
- isValidAsConstant = false;
- isInvalid = true;
- }
-
- if (result.isDeferred) {
- isValidAsConstant = false;
- }
-
- // Callback hook for when the compile-time constant evaluator has
- // analyzed the constant.
- // TODO(johnniwinther): Remove this when all constants are computed
- // in resolution.
- Function onAnalyzed;
- if (isValidAsConstant &&
- argumentsResult.isValidAsConstant &&
- // TODO(johnniwinther): Remove this when all constants are computed
- // in resolution.
- !constructor.isFromEnvironmentConstructor) {
- ResolutionInterfaceType interfaceType = type;
- CallStructure callStructure = argumentsResult.callStructure;
- List<ConstantExpression> arguments = argumentsResult.constantArguments;
-
- ConstructedConstantExpression constant =
- new ConstructedConstantExpression(
- interfaceType, constructor, callStructure, arguments);
- registry.registerNewStructure(node,
- new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant));
- resolutionResult = new ConstantResult(node, constant);
- } else if (isInvalid) {
- // Known to be non-constant.
- kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR;
- registry.registerNewStructure(
- node,
- new NewInvokeStructure(
- new ConstructorAccessSemantics(kind, constructor, type),
- selector));
- } else {
- // Might be valid but we don't know for sure. The compile-time constant
- // evaluator will compute the actual constant as a deferred action.
- LateConstInvokeStructure structure =
- new LateConstInvokeStructure(registry.mapping);
- // TODO(johnniwinther): Avoid registering the
- // [LateConstInvokeStructure]; it might not be necessary.
- registry.registerNewStructure(node, structure);
- onAnalyzed = () {
- registry.registerNewStructure(node, structure.resolve(node));
- };
- }
-
- analyzeConstantDeferred(node, onAnalyzed: onAnalyzed);
- } else {
- // Not constant.
- if (resolution.commonElements.isSymbolConstructor(constructor) &&
- !resolution.mirrorUsageAnalyzerTask
- .hasMirrorUsage(enclosingElement)) {
- reporter.reportHintMessage(
- reporter.spanFromToken(node.newToken),
- MessageKind.NON_CONST_BLOAT,
- {'name': commonElements.symbolClass.name});
- }
- registry.registerNewStructure(
- node,
- new NewInvokeStructure(
- new ConstructorAccessSemantics(kind, constructor, type),
- selector));
- }
-
- return resolutionResult;
- }
-
- void checkConstMapKeysDontOverrideEquals(
- Spannable spannable, MapConstantValue map) {
- for (ConstantValue key in map.keys) {
- if (!key.isObject) continue;
- ObjectConstantValue objectConstant = key;
- ResolutionInterfaceType keyType = objectConstant.type;
- ClassElement cls = keyType.element;
- if (cls == commonElements.stringClass) continue;
- Element equals = cls.lookupMember('==');
- if (equals.enclosingClass != commonElements.objectClass) {
- reporter.reportErrorMessage(spannable,
- MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType});
- }
- }
- }
-
- void analyzeConstant(Node node, {enforceConst: true}) {
- ConstantExpression constant = resolver.constantCompiler
- .compileNode(node, registry.mapping, enforceConst: enforceConst);
-
- if (constant == null) {
- assert(reporter.hasReportedError, failedAt(node));
- return;
- }
-
- ConstantValue value = resolution.constants.getConstantValue(constant);
- if (value.isMap) {
- checkConstMapKeysDontOverrideEquals(node, value);
- }
- }
-
- void analyzeConstantDeferred(Node node,
- {bool enforceConst: true, void onAnalyzed()}) {
- addDeferredAction(enclosingElement, () {
- analyzeConstant(node, enforceConst: enforceConst);
- if (onAnalyzed != null) {
- onAnalyzed();
- }
- });
- }
-
- bool validateSymbol(Node node, String name, {bool reportError: true}) {
- if (name.isEmpty) return true;
- if (name.startsWith('_')) {
- if (reportError) {
- reporter.reportErrorMessage(
- node, MessageKind.PRIVATE_IDENTIFIER, {'value': name});
- }
- return false;
- }
- if (!symbolValidationPattern.hasMatch(name)) {
- if (reportError) {
- reporter.reportErrorMessage(
- node, MessageKind.INVALID_SYMBOL, {'value': name});
- }
- return false;
- }
- return true;
- }
-
- /**
- * Try to resolve the constructor that is referred to by [node].
- * Note: this function may return an ErroneousFunctionElement instead of
- * [:null:], if there is no corresponding constructor, class or library.
- */
- ConstructorResult resolveConstructor(NewExpression node) {
- return node.accept(new ConstructorResolver(resolution, this,
- inConstContext: node.isConst));
- }
-
- ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node,
- {bool inConstContext: false}) {
- return node.accept(new ConstructorResolver(resolution, this,
- inConstContext: inConstContext));
- }
-
- ResolutionDartType resolveTypeAnnotation(TypeAnnotation node,
- {FunctionTypeParameterScope functionTypeParameters:
- const FunctionTypeParameterScope(),
- bool malformedIsError: false,
- bool deferredIsMalformed: true,
- bool registerCheckedModeCheck: true}) {
- ResolutionDartType type = typeResolver.resolveTypeAnnotation(
- this, node, functionTypeParameters,
- malformedIsError: malformedIsError,
- deferredIsMalformed: deferredIsMalformed);
- if (registerCheckedModeCheck) {
- registry.registerCheckedModeCheck(type);
- }
- return type;
- }
-
- ResolutionResult visitLiteralList(LiteralList node) {
- bool isValidAsConstant = true;
- sendIsMemberAccess = false;
-
- NodeList arguments = node.typeArguments;
- ResolutionDartType typeArgument;
- if (arguments != null) {
- Link<Node> nodes = arguments.nodes;
- if (nodes.isEmpty) {
- // The syntax [: <>[] :] is not allowed.
- reporter.reportErrorMessage(
- arguments, MessageKind.MISSING_TYPE_ARGUMENT);
- isValidAsConstant = false;
- } else {
- typeArgument = resolveTypeAnnotation(nodes.head);
- for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
- reporter.reportWarningMessage(
- nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
- resolveTypeAnnotation(nodes.head);
- }
- }
- }
- ResolutionInterfaceType listType;
- if (typeArgument != null) {
- if (node.isConst && typeArgument.containsTypeVariables) {
- reporter.reportErrorMessage(
- arguments.nodes.head, MessageKind.TYPE_VARIABLE_IN_CONSTANT);
- isValidAsConstant = false;
- }
- listType = commonElements.listType(typeArgument);
- } else {
- listType = commonElements.listType();
- }
- registry.registerLiteralList(node, listType,
- isConstant: node.isConst, isEmpty: node.elements.isEmpty);
- if (node.isConst) {
- List<ConstantExpression> constantExpressions = <ConstantExpression>[];
- inConstantContext(() {
- for (Node element in node.elements) {
- ResolutionResult elementResult = visit(element);
- if (isValidAsConstant && elementResult.isConstant) {
- constantExpressions.add(elementResult.constant);
- } else {
- isValidAsConstant = false;
- }
- }
- });
- analyzeConstantDeferred(node);
- sendIsMemberAccess = false;
- if (isValidAsConstant) {
- ConstantExpression constant =
- new ListConstantExpression(listType, constantExpressions);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- } else {
- visit(node.elements);
- sendIsMemberAccess = false;
- }
- return const NoneResult();
- }
-
- ResolutionResult visitConditional(Conditional node) {
- ResolutionResult conditionResult =
- doInPromotionScope(node.condition, () => visit(node.condition));
- ResolutionResult thenResult = doInPromotionScope(
- node.thenExpression, () => visit(node.thenExpression));
- ResolutionResult elseResult = visit(node.elseExpression);
- if (conditionResult.isConstant &&
- thenResult.isConstant &&
- elseResult.isConstant) {
- ConstantExpression constant = new ConditionalConstantExpression(
- conditionResult.constant, thenResult.constant, elseResult.constant);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- return const NoneResult();
- }
-
- ResolutionResult visitStringInterpolation(StringInterpolation node) {
- // TODO(johnniwinther): This should be a consequence of the registration
- // of [registerStringInterpolation].
- registry.registerFeature(Feature.STRING_INTERPOLATION);
-
- bool isValidAsConstant = true;
- List<ConstantExpression> parts = <ConstantExpression>[];
-
- void resolvePart(Node subnode) {
- ResolutionResult result = visit(subnode);
- if (isValidAsConstant && result.isConstant) {
- parts.add(result.constant);
- } else {
- isValidAsConstant = false;
- }
- }
-
- resolvePart(node.string);
- for (StringInterpolationPart part in node.parts) {
- resolvePart(part.expression);
- resolvePart(part.string);
- }
-
- if (isValidAsConstant) {
- ConstantExpression constant = new ConcatenateConstantExpression(parts);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- return const NoneResult();
- }
-
- ResolutionResult visitBreakStatement(BreakStatement node) {
- JumpTargetX target;
- if (node.target == null) {
- target = statementScope.currentBreakTarget();
- if (target == null) {
- reporter.reportErrorMessage(node, MessageKind.NO_BREAK_TARGET);
- return const NoneResult();
- }
- target.isBreakTarget = true;
- } else {
- String labelName = node.target.source;
- LabelDefinitionX label = statementScope.lookupLabel(labelName);
- if (label == null) {
- reporter.reportErrorMessage(
- node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
- return const NoneResult();
- }
- target = label.target;
- if (!target.statement.isValidBreakTarget()) {
- reporter.reportErrorMessage(node.target, MessageKind.INVALID_BREAK);
- return const NoneResult();
- }
- label.setBreakTarget();
- registry.useLabel(node, label);
- }
- registry.registerTargetOf(node, target);
- return const NoneResult();
- }
-
- ResolutionResult visitContinueStatement(ContinueStatement node) {
- JumpTargetX target;
- if (node.target == null) {
- target = statementScope.currentContinueTarget();
- if (target == null) {
- reporter.reportErrorMessage(node, MessageKind.NO_CONTINUE_TARGET);
- return const NoneResult();
- }
- target.isContinueTarget = true;
- } else {
- String labelName = node.target.source;
- LabelDefinitionX label = statementScope.lookupLabel(labelName);
- if (label == null) {
- reporter.reportErrorMessage(
- node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
- return const NoneResult();
- }
- target = label.target;
- if (!target.statement.isValidContinueTarget()) {
- reporter.reportErrorMessage(node.target, MessageKind.INVALID_CONTINUE);
- }
- label.setContinueTarget();
- registry.useLabel(node, label);
- }
- registry.registerTargetOf(node, target);
- return const NoneResult();
- }
-
- ResolutionResult visitAsyncForIn(AsyncForIn node) {
- if (!resolution.target.supportsAsyncAwait) {
- reporter.reportErrorMessage(reporter.spanFromToken(node.awaitToken),
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
- } else {
- if (!currentAsyncMarker.isAsync) {
- reporter.reportErrorMessage(reporter.spanFromToken(node.awaitToken),
- MessageKind.INVALID_AWAIT_FOR_IN);
- }
- registry.registerFeature(Feature.ASYNC_FOR_IN);
- registry.registerDynamicUse(new DynamicUse(Selectors.cancel));
- registry.registerDynamicUse(new DynamicUse(Selectors.current));
- registry.registerDynamicUse(new DynamicUse(Selectors.moveNext));
- }
- visit(node.expression);
-
- Scope blockScope = new BlockScope(scope);
- visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope);
- visitLoopBodyIn(node, node.body, blockScope);
- return const NoneResult();
- }
-
- ResolutionResult visitSyncForIn(SyncForIn node) {
- registry.registerFeature(Feature.SYNC_FOR_IN);
- registry.registerDynamicUse(new DynamicUse(Selectors.iterator));
- registry.registerDynamicUse(new DynamicUse(Selectors.current));
- registry.registerDynamicUse(new DynamicUse(Selectors.moveNext));
-
- visit(node.expression);
-
- Scope blockScope = new BlockScope(scope);
- visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope);
- visitLoopBodyIn(node, node.body, blockScope);
- return const NoneResult();
- }
-
- void visitForInDeclaredIdentifierIn(
- Node declaration, ForIn node, Scope blockScope) {
- LibraryElement library = enclosingElement.library;
-
- bool oldAllowFinalWithoutInitializer = inLoopVariable;
- inLoopVariable = true;
- visitIn(declaration, blockScope);
- inLoopVariable = oldAllowFinalWithoutInitializer;
-
- Send send = declaration.asSend();
- VariableDefinitions variableDefinitions =
- declaration.asVariableDefinitions();
- Element loopVariable;
- Selector loopVariableSelector;
- if (send != null) {
- loopVariable = registry.getDefinition(send);
- Identifier identifier = send.selector.asIdentifier();
- if (identifier == null) {
- reporter.reportErrorMessage(send.selector, MessageKind.INVALID_FOR_IN);
- } else {
- loopVariableSelector =
- new Selector.setter(new Name(identifier.source, library));
- }
- if (send.receiver != null) {
- reporter.reportErrorMessage(send.receiver, MessageKind.INVALID_FOR_IN);
- }
- } else if (variableDefinitions != null) {
- Link<Node> nodes = variableDefinitions.definitions.nodes;
- if (!nodes.tail.isEmpty) {
- reporter.reportErrorMessage(
- nodes.tail.head, MessageKind.INVALID_FOR_IN);
- }
- Node first = nodes.head;
- Identifier identifier = first.asIdentifier();
- if (identifier == null) {
- reporter.reportErrorMessage(first, MessageKind.INVALID_FOR_IN);
- } else {
- loopVariableSelector =
- new Selector.setter(new Name(identifier.source, library));
- loopVariable = registry.getDefinition(identifier);
- }
- } else {
- reporter.reportErrorMessage(declaration, MessageKind.INVALID_FOR_IN);
- }
- if (loopVariableSelector != null) {
- registry.setSelector(declaration, loopVariableSelector);
- if (loopVariable == null || loopVariable.isInstanceMember) {
- registry.registerDynamicUse(new DynamicUse(loopVariableSelector));
- } else if (loopVariable.isStatic || loopVariable.isTopLevel) {
- MemberElement member = loopVariable.declaration;
- registry.registerStaticUse(new StaticUse.staticSet(member));
- }
- } else {
- // The selector may only be null if we reported an error.
- assert(reporter.hasReportedError, failedAt(declaration));
- }
- if (loopVariable != null) {
- // loopVariable may be null if it could not be resolved.
- registry.setForInVariable(node, loopVariable);
- }
- }
-
- visitLabel(Label node) {
- // Labels are handled by their containing statements/cases.
- }
-
- ResolutionResult visitLabeledStatement(LabeledStatement node) {
- Statement body = node.statement;
- JumpTarget targetElement = getOrDefineTarget(body);
- Map<String, LabelDefinitionX> labelElements = <String, LabelDefinitionX>{};
- for (Label label in node.labels) {
- String labelName = label.labelName;
- if (labelElements.containsKey(labelName)) continue;
- LabelDefinition element = targetElement.addLabel(label, labelName);
- labelElements[labelName] = element;
- }
- statementScope.enterLabelScope(labelElements);
- visit(node.statement);
- statementScope.exitLabelScope();
- labelElements.forEach((String labelName, LabelDefinitionX element) {
- if (element.isTarget) {
- registry.defineLabel(element.label, element);
- } else {
- reporter.reportWarningMessage(
- element.label, MessageKind.UNUSED_LABEL, {'labelName': labelName});
- }
- });
- if (!targetElement.isTarget) {
- registry.undefineTarget(body);
- }
- return const NoneResult();
- }
-
- ResolutionResult visitLiteralMap(LiteralMap node) {
- bool isValidAsConstant = true;
- sendIsMemberAccess = false;
-
- NodeList arguments = node.typeArguments;
- ResolutionDartType keyTypeArgument;
- ResolutionDartType valueTypeArgument;
- if (arguments != null) {
- Link<Node> nodes = arguments.nodes;
- if (nodes.isEmpty) {
- // The syntax [: <>{} :] is not allowed.
- reporter.reportErrorMessage(
- arguments, MessageKind.MISSING_TYPE_ARGUMENT);
- isValidAsConstant = false;
- } else {
- keyTypeArgument = resolveTypeAnnotation(nodes.head);
- nodes = nodes.tail;
- if (nodes.isEmpty) {
- reporter.reportWarningMessage(
- arguments, MessageKind.MISSING_TYPE_ARGUMENT);
- } else {
- valueTypeArgument = resolveTypeAnnotation(nodes.head);
- for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
- reporter.reportWarningMessage(
- nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
- resolveTypeAnnotation(nodes.head);
- }
- }
- }
- }
- ResolutionInterfaceType mapType;
- if (valueTypeArgument != null) {
- mapType = commonElements.mapType(keyTypeArgument, valueTypeArgument);
- } else {
- mapType = commonElements.mapType();
- }
- if (node.isConst && mapType.containsTypeVariables) {
- reporter.reportErrorMessage(
- arguments, MessageKind.TYPE_VARIABLE_IN_CONSTANT);
- isValidAsConstant = false;
- }
- registry.registerMapLiteral(node, mapType,
- isConstant: node.isConst, isEmpty: node.entries.isEmpty);
-
- if (node.isConst) {
- List<ConstantExpression> keyExpressions = <ConstantExpression>[];
- List<ConstantExpression> valueExpressions = <ConstantExpression>[];
- inConstantContext(() {
- for (LiteralMapEntry entry in node.entries) {
- ResolutionResult keyResult = visit(entry.key);
- ResolutionResult valueResult = visit(entry.value);
- if (isValidAsConstant &&
- keyResult.isConstant &&
- valueResult.isConstant) {
- keyExpressions.add(keyResult.constant);
- valueExpressions.add(valueResult.constant);
- } else {
- isValidAsConstant = false;
- }
- }
- });
- analyzeConstantDeferred(node);
- sendIsMemberAccess = false;
- if (isValidAsConstant) {
- ConstantExpression constant = new MapConstantExpression(
- mapType, keyExpressions, valueExpressions);
- registry.setConstant(node, constant);
- return new ConstantResult(node, constant);
- }
- } else {
- node.visitChildren(this);
- sendIsMemberAccess = false;
- }
- return const NoneResult();
- }
-
- ResolutionResult visitLiteralMapEntry(LiteralMapEntry node) {
- node.visitChildren(this);
- return const NoneResult();
- }
-
- ResolutionResult visitNamedArgument(NamedArgument node) {
- return visit(node.expression);
- }
-
- ResolutionInterfaceType typeOfConstant(ConstantValue constant) {
- if (constant.isInt) return commonElements.intType;
- if (constant.isBool) return commonElements.boolType;
- if (constant.isDouble) return commonElements.doubleType;
- if (constant.isString) return commonElements.stringType;
- if (constant.isNull) return commonElements.nullType;
- if (constant.isFunction) return commonElements.functionType;
- assert(constant.isObject);
- ObjectConstantValue objectConstant = constant;
- ResolutionInterfaceType type = objectConstant.type;
- return type;
- }
-
- bool overridesEquals(ResolutionDartType type) {
- ClassElement cls = type.element;
- Element equals = cls.lookupMember('==');
- return equals.enclosingClass != commonElements.objectClass;
- }
-
- void checkCaseExpressions(SwitchStatement node) {
- CaseMatch firstCase = null;
- ResolutionDartType firstCaseType = null;
- DiagnosticMessage error;
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-
- for (Link<Node> cases = node.cases.nodes;
- !cases.isEmpty;
- cases = cases.tail) {
- SwitchCase switchCase = cases.head;
-
- for (Node labelOrCase in switchCase.labelsAndCases) {
- CaseMatch caseMatch = labelOrCase.asCaseMatch();
- if (caseMatch == null) continue;
-
- // Analyze the constant.
- ConstantExpression constant =
- registry.getConstant(caseMatch.expression);
- assert(
- constant != null, failedAt(node, 'No constant computed for $node'));
-
- ConstantValue value = resolution.constants.getConstantValue(constant);
- ResolutionDartType caseType =
- value.getType(commonElements); //typeOfConstant(value);
-
- if (firstCaseType == null) {
- firstCase = caseMatch;
- firstCaseType = caseType;
-
- // We only report the bad type on the first class element. All others
- // get a "type differs" error.
- if (caseType == commonElements.doubleType) {
- reporter.reportErrorMessage(
- node,
- MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
- {'type': "double"});
- } else if (caseType == commonElements.functionType) {
- reporter.reportErrorMessage(
- node, MessageKind.SWITCH_CASE_FORBIDDEN, {'type': "Function"});
- } else if (value.isObject && overridesEquals(caseType)) {
- reporter.reportErrorMessage(
- firstCase.expression,
- MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
- {'type': caseType});
- }
- } else {
- if (caseType != firstCaseType) {
- if (error == null) {
- error = reporter.createMessage(
- node,
- MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
- {'type': firstCaseType});
- infos.add(reporter.createMessage(
- firstCase.expression,
- MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
- {'type': firstCaseType}));
- }
- infos.add(reporter.createMessage(
- caseMatch.expression,
- MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
- {'type': caseType}));
- }
- }
- }
- }
- if (error != null) {
- reporter.reportError(error, infos);
- }
- }
-
- ResolutionResult visitSwitchStatement(SwitchStatement node) {
- node.expression.accept(this);
-
- JumpTarget breakElement = getOrDefineTarget(node);
- Map<String, LabelDefinitionX> continueLabels = <String, LabelDefinitionX>{};
- Set<SwitchCase> switchCasesWithContinues = new Set<SwitchCase>();
- Link<Node> cases = node.cases.nodes;
- while (!cases.isEmpty) {
- SwitchCase switchCase = cases.head;
- for (Node labelOrCase in switchCase.labelsAndCases) {
- CaseMatch caseMatch = labelOrCase.asCaseMatch();
- if (caseMatch != null) {
- analyzeConstantDeferred(caseMatch.expression);
- continue;
- }
- Label label = labelOrCase;
- String labelName = label.labelName;
-
- LabelDefinitionX existingElement = continueLabels[labelName];
- if (existingElement != null) {
- // It's an error if the same label occurs twice in the same switch.
- reporter.reportError(
- reporter.createMessage(
- label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName}),
- <DiagnosticMessage>[
- reporter.createMessage(existingElement.label,
- MessageKind.EXISTING_LABEL, {'labelName': labelName}),
- ]);
- } else {
- // It's only a warning if it shadows another label.
- existingElement = statementScope.lookupLabel(labelName);
- if (existingElement != null) {
- reporter.reportWarning(
- reporter.createMessage(label, MessageKind.DUPLICATE_LABEL,
- {'labelName': labelName}),
- <DiagnosticMessage>[
- reporter.createMessage(existingElement.label,
- MessageKind.EXISTING_LABEL, {'labelName': labelName}),
- ]);
- }
- }
-
- JumpTarget targetElement = getOrDefineTarget(switchCase);
- LabelDefinition labelElement = targetElement.addLabel(label, labelName);
- registry.defineLabel(label, labelElement);
- continueLabels[labelName] = labelElement;
- }
- cases = cases.tail;
- // Test that only the last case, if any, is a default case.
- if (switchCase.defaultKeyword != null && !cases.isEmpty) {
- reporter.reportErrorMessage(
- switchCase, MessageKind.INVALID_CASE_DEFAULT);
- }
- if (cases.isNotEmpty && switchCase.statements.isNotEmpty) {
- Node last = switchCase.statements.last;
- if (last.asReturn() == null &&
- last.asBreakStatement() == null &&
- last.asContinueStatement() == null &&
- (last.asExpressionStatement() == null ||
- last.asExpressionStatement().expression.asThrow() == null)) {
- registry.registerFeature(Feature.FALL_THROUGH_ERROR);
- }
- }
- }
-
- addDeferredAction(enclosingElement, () {
- checkCaseExpressions(node);
- });
-
- statementScope.enterSwitch(breakElement, continueLabels);
- node.cases.accept(this);
- statementScope.exitSwitch();
-
- continueLabels.forEach((String key, LabelDefinition label) {
- if (label.isContinueTarget) {
- JumpTarget targetElement = label.target;
- SwitchCase switchCase = targetElement.statement;
- switchCasesWithContinues.add(switchCase);
- }
- });
-
- // Clean-up unused labels.
- continueLabels.forEach((String key, LabelDefinitionX label) {
- if (!label.isContinueTarget) {
- JumpTarget targetElement = label.target;
- SwitchCase switchCase = targetElement.statement;
- if (!switchCasesWithContinues.contains(switchCase)) {
- registry.undefineTarget(switchCase);
- }
- registry.undefineLabel(label.label);
- }
- });
- // TODO(15575): We should warn if we can detect a fall through
- // error.
- return const NoneResult();
- }
-
- ResolutionResult visitSwitchCase(SwitchCase node) {
- node.labelsAndCases.accept(this);
- visitIn(node.statements, new BlockScope(scope));
- return const NoneResult();
- }
-
- ResolutionResult visitCaseMatch(CaseMatch node) {
- visit(node.expression);
- return const NoneResult();
- }
-
- ResolutionResult visitTryStatement(TryStatement node) {
- // TODO(karlklose): also track the information about mutated variables,
- // catch, and finally-block.
- registry.registerTryStatement();
-
- visit(node.tryBlock);
- if (node.catchBlocks.isEmpty && node.finallyBlock == null) {
- reporter.reportErrorMessage(
- reporter.spanFromToken(node.getEndToken().next),
- MessageKind.NO_CATCH_NOR_FINALLY);
- }
- visit(node.catchBlocks);
- visit(node.finallyBlock);
- return const NoneResult();
- }
-
- ResolutionResult visitCatchBlock(CatchBlock node) {
- registry.registerFeature(Feature.CATCH_STATEMENT);
- // Check that if catch part is present, then
- // it has one or two formal parameters.
- VariableDefinitions exceptionDefinition;
- VariableDefinitions stackTraceDefinition;
- if (node.formals != null) {
- Link<Node> formalsToProcess = node.formals.nodes;
- if (formalsToProcess.isEmpty) {
- reporter.reportErrorMessage(node, MessageKind.EMPTY_CATCH_DECLARATION);
- } else {
- exceptionDefinition = formalsToProcess.head.asVariableDefinitions();
- formalsToProcess = formalsToProcess.tail;
- if (!formalsToProcess.isEmpty) {
- stackTraceDefinition = formalsToProcess.head.asVariableDefinitions();
- formalsToProcess = formalsToProcess.tail;
- if (!formalsToProcess.isEmpty) {
- for (Node extra in formalsToProcess) {
- reporter.reportErrorMessage(
- extra, MessageKind.EXTRA_CATCH_DECLARATION);
- }
- }
- registry.registerFeature(Feature.STACK_TRACE_IN_CATCH);
- }
- }
-
- // Check that the formals aren't optional and that they have no
- // modifiers or type.
- for (Link<Node> link = node.formals.nodes;
- !link.isEmpty;
- link = link.tail) {
- // If the formal parameter is a node list, it means that it is a
- // sequence of optional parameters.
- NodeList nodeList = link.head.asNodeList();
- if (nodeList != null) {
- reporter.reportErrorMessage(
- nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH);
- } else {
- VariableDefinitions declaration = link.head;
-
- for (Node modifier in declaration.modifiers.nodes) {
- reporter.reportErrorMessage(
- modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH);
- }
- TypeAnnotation type = declaration.type;
- if (type != null) {
- reporter.reportErrorMessage(
- type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH);
- }
- }
- }
- }
-
- Scope blockScope = new BlockScope(scope);
- inCatchParameters = true;
- visitIn(node.formals, blockScope);
- inCatchParameters = false;
- var oldInCatchBlock = inCatchBlock;
- inCatchBlock = true;
- visitIn(node.block, blockScope);
- inCatchBlock = oldInCatchBlock;
-
- if (node.type != null) {
- ResolutionDartType exceptionType =
- resolveTypeAnnotation(node.type, registerCheckedModeCheck: false);
- if (exceptionDefinition != null) {
- Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
- VariableElementX exceptionElement =
- registry.getDefinition(exceptionVariable);
- exceptionElement.variables.type = exceptionType;
- }
- registry.registerTypeUse(new TypeUse.catchType(exceptionType));
- }
- if (stackTraceDefinition != null) {
- Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head;
- VariableElementX stackTraceElement =
- registry.getDefinition(stackTraceVariable);
- ResolutionInterfaceType stackTraceType = commonElements.stackTraceType;
- stackTraceElement.variables.type = stackTraceType;
- }
- return const NoneResult();
- }
-}
-
-/// Looks up [name] in [scope] and unwraps the result.
-Element lookupInScope(
- DiagnosticReporter reporter, Node node, Scope scope, String name) {
- return Elements.unwrap(scope.lookup(name), reporter, node);
-}
diff --git a/pkg/compiler/lib/src/resolution/no_such_method_resolver.dart b/pkg/compiler/lib/src/resolution/no_such_method_resolver.dart
deleted file mode 100644
index 5e4955f..0000000
--- a/pkg/compiler/lib/src/resolution/no_such_method_resolver.dart
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import '../common/names.dart' show Identifiers, Names;
-import '../elements/elements.dart';
-import '../js_backend/no_such_method_registry.dart';
-import '../tree/tree.dart';
-
-/// AST-based implementation of [NoSuchMethodResolver].
-class ResolutionNoSuchMethodResolver implements NoSuchMethodResolver {
- bool hasForwardingSyntax(MethodElement element) {
- // At this point we know that this is signature-compatible with
- // Object.noSuchMethod, but it may have more than one argument as long as
- // it only has one required argument.
- if (!element.hasResolvedAst) {
- // TODO(johnniwinther): Why do we see unresolved elements here?
- return false;
- }
- ResolvedAst resolvedAst = element.resolvedAst;
- if (resolvedAst.kind != ResolvedAstKind.PARSED) {
- return false;
- }
- String param = element.parameters.first.name;
- Statement body = resolvedAst.body;
- Expression expr;
- if (body is Return && body.isArrowBody) {
- expr = body.expression;
- } else if (body is Block &&
- !body.statements.isEmpty &&
- body.statements.nodes.tail.isEmpty) {
- Statement stmt = body.statements.nodes.head;
- if (stmt is Return && stmt.hasExpression) {
- expr = stmt.expression;
- }
- }
- if (expr is Send && expr.isTypeCast) {
- Send sendExpr = expr;
- var typeAnnotation = sendExpr.typeAnnotationFromIsCheckOrCast;
- var typeName = typeAnnotation.asNominalTypeAnnotation()?.typeName;
- if (typeName is Identifier && typeName.source == "dynamic") {
- expr = sendExpr.receiver;
- }
- }
- if (expr is Send &&
- expr.isSuperCall &&
- expr.selector is Identifier &&
- (expr.selector as Identifier).source == Identifiers.noSuchMethod_) {
- var arg = expr.arguments.head;
- if (expr.arguments.tail.isEmpty &&
- arg is Send &&
- arg.argumentsNode == null &&
- arg.receiver == null &&
- arg.selector is Identifier) {
- Identifier selector = arg.selector;
- if (selector.source == param) {
- return true;
- }
- }
- }
- return false;
- }
-
- bool hasThrowingSyntax(MethodElement element) {
- if (!element.hasResolvedAst) {
- // TODO(johnniwinther): Why do we see unresolved elements here?
- return false;
- }
- ResolvedAst resolvedAst = element.resolvedAst;
- if (resolvedAst.kind != ResolvedAstKind.PARSED) {
- return false;
- }
- Statement body = resolvedAst.body;
- if (body is Return && body.isArrowBody) {
- if (body.expression is Throw) {
- return true;
- }
- } else if (body is Block &&
- !body.statements.isEmpty &&
- body.statements.nodes.tail.isEmpty) {
- if (body.statements.nodes.head is ExpressionStatement) {
- ExpressionStatement stmt = body.statements.nodes.head;
- return stmt.expression is Throw;
- }
- }
- return false;
- }
-
- MethodElement getSuperNoSuchMethod(MethodElement method) {
- return method.enclosingClass.lookupSuperByName(Names.noSuchMethod_);
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index 2094ecf..2d713f1 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -4,29 +4,16 @@
library dart2js.resolution.registry;
-import '../common.dart';
-import '../common/backend_api.dart' show ForeignResolver, NativeRegistry;
-import '../common/resolution.dart' show ResolutionImpact, Target;
+import '../common/resolution.dart' show ResolutionImpact;
import '../constants/expressions.dart';
-import '../diagnostics/source_span.dart';
-import '../elements/elements.dart';
import '../elements/entities.dart' show ClassEntity;
-import '../elements/jumps.dart';
-import '../elements/resolution_types.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
import '../universe/feature.dart';
-import '../universe/selector.dart' show Selector;
-import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilderImpl;
import '../util/enumset.dart' show EnumSet;
import '../util/util.dart' show Setlet;
-import 'members.dart' show ResolverVisitor;
-import 'send_structure.dart';
-import 'tree_elements.dart' show TreeElementMapping;
class ResolutionWorldImpactBuilder extends WorldImpactBuilderImpl
- implements NativeRegistry, ResolutionImpact {
+ implements ResolutionImpact {
final String name;
EnumSet<Feature> _features;
Setlet<MapLiteralUse> _mapLiterals;
@@ -171,295 +158,3 @@
return sb.toString();
}
}
-
-/// [ResolutionRegistry] collects all resolution information. It stores node
-/// related information in a [TreeElements] mapping and registers calls with
-/// [Backend], [World] and [Enqueuer].
-// TODO(johnniwinther): Split this into an interface and implementation class.
-class ResolutionRegistry {
- final Target target;
- final TreeElementMapping mapping;
- final ResolutionWorldImpactBuilder impactBuilder;
-
- ResolutionRegistry(this.target, TreeElementMapping mapping)
- : this.mapping = mapping,
- this.impactBuilder = new ResolutionWorldImpactBuilder(
- mapping.analyzedElement.toString());
-
- bool get isForResolution => true;
-
- String toString() => 'ResolutionRegistry for ${mapping.analyzedElement}';
-
- //////////////////////////////////////////////////////////////////////////////
- // Node-to-Element mapping functionality.
- //////////////////////////////////////////////////////////////////////////////
-
- /// Register [node] as the declaration of [element].
- void defineFunction(FunctionExpression node, FunctionElement element) {
- // TODO(sigurdm): Remove when not needed by the dart2dart backend.
- if (node.name != null) {
- mapping[node.name] = element;
- }
- mapping[node] = element;
- }
-
- /// Register [node] as a reference to [element].
- Element useElement(Node node, Element element) {
- if (element == null) return null;
- return mapping[node] = element;
- }
-
- /// Register [node] as the declaration of [element].
- void defineElement(Node node, Element element) {
- mapping[node] = element;
- }
-
- /// Returns the [Element] defined by [node].
- Element getDefinition(Node node) {
- return mapping[node];
- }
-
- /// Sets the loop variable of the for-in [node] to be [element].
- void setForInVariable(ForIn node, Element element) {
- mapping[node] = element;
- }
-
- /// Sets the target constructor [node] to be [element].
- void setRedirectingTargetConstructor(
- RedirectingFactoryBody node, ConstructorElement element) {
- useElement(node, element);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Node-to-Selector mapping functionality.
- //////////////////////////////////////////////////////////////////////////////
-
- void setSelector(Node node, Selector selector) {
- mapping.setSelector(node, selector);
- }
-
- void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
- mapping.setGetterSelectorInComplexSendSet(node, selector);
- }
-
- void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
- mapping.setOperatorSelectorInComplexSendSet(node, selector);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Node-to-Type mapping functionality.
- //////////////////////////////////////////////////////////////////////////////
-
- ResolutionDartType useType(Node annotation, ResolutionDartType type) {
- if (type != null) {
- mapping.setType(annotation, type);
- }
- return type;
- }
-
- void setType(Node node, ResolutionDartType type) =>
- mapping.setType(node, type);
-
- ResolutionDartType getType(Node node) => mapping.getType(node);
-
- //////////////////////////////////////////////////////////////////////////////
- // Node-to-Constant mapping functionality.
- //////////////////////////////////////////////////////////////////////////////
-
- ConstantExpression getConstant(Node node) => mapping.getConstant(node);
-
- void setConstant(Node node, ConstantExpression constant) {
- mapping.setConstant(node, constant);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Target/Label functionality.
- //////////////////////////////////////////////////////////////////////////////
-
- /// Register [node] to be the declaration of [label].
- void defineLabel(Label node, LabelDefinition label) {
- mapping.defineLabel(node, label);
- }
-
- /// Undefine the label of [node].
- /// This is used to cleanup and detect unused labels.
- void undefineLabel(Label node) {
- mapping.undefineLabel(node);
- }
-
- /// Register the target of [node] as reference to [label].
- void useLabel(GotoStatement node, LabelDefinition label) {
- mapping.registerTargetLabel(node, label);
- }
-
- /// Register [node] to be the declaration of [target].
- void defineTarget(Node node, JumpTarget target) {
- assert(node is Statement || node is SwitchCase,
- failedAt(node, "Only statements and switch cases can define targets."));
- mapping.defineTarget(node, target);
- }
-
- /// Returns the [JumpTarget] defined by [node].
- JumpTarget getTargetDefinition(Node node) {
- assert(node is Statement || node is SwitchCase,
- failedAt(node, "Only statements and switch cases can define targets."));
- return mapping.getTargetDefinition(node);
- }
-
- /// Undefine the target of [node]. This is used to cleanup unused targets.
- void undefineTarget(Node node) {
- assert(node is Statement || node is SwitchCase,
- failedAt(node, "Only statements and switch cases can define targets."));
- mapping.undefineTarget(node);
- }
-
- /// Register the target of [node] to be [target].
- void registerTargetOf(GotoStatement node, JumpTarget target) {
- mapping.registerTargetOf(node, target);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Potential access registration.
- //////////////////////////////////////////////////////////////////////////////
-
- void setAccessedByClosureIn(
- Node contextNode, VariableElement element, Node accessNode) {
- mapping.setAccessedByClosureIn(contextNode, element, accessNode);
- }
-
- void registerPotentialMutation(VariableElement element, Node mutationNode) {
- mapping.registerPotentialMutation(element, mutationNode);
- }
-
- void registerPotentialMutationInClosure(
- VariableElement element, Node mutationNode) {
- mapping.registerPotentialMutationInClosure(element, mutationNode);
- }
-
- void registerPotentialMutationIn(
- Node contextNode, VariableElement element, Node mutationNode) {
- mapping.registerPotentialMutationIn(contextNode, element, mutationNode);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Various Backend/Enqueuer/World registration.
- //////////////////////////////////////////////////////////////////////////////
-
- void registerStaticUse(StaticUse staticUse) {
- impactBuilder.registerStaticUse(staticUse);
- }
-
- /// Register the use of a type.
- void registerTypeUse(TypeUse typeUse) {
- impactBuilder.registerTypeUse(typeUse);
- }
-
- /// Register checked mode check of [type] if it isn't `dynamic`.
- void registerCheckedModeCheck(ResolutionDartType type) {
- if (!type.isDynamic) {
- impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type));
- }
- }
-
- void registerSuperUse(SourceSpan span) {
- mapping.addSuperUse(span);
- }
-
- void registerTypeLiteral(Send node, ResolutionDartType type) {
- mapping.setType(node, type);
- impactBuilder.registerTypeUse(new TypeUse.typeLiteral(type));
- }
-
- void registerLiteralList(Node node, ResolutionInterfaceType type,
- {bool isConstant, bool isEmpty}) {
- setType(node, type);
- impactBuilder.registerListLiteral(
- new ListLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
- }
-
- void registerMapLiteral(Node node, ResolutionInterfaceType type,
- {bool isConstant, bool isEmpty}) {
- setType(node, type);
- impactBuilder.registerMapLiteral(
- new MapLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
- }
-
- void registerForeignCall(Node node, Element element,
- CallStructure callStructure, ResolverVisitor visitor) {
- var nativeData = target.resolveForeignCall(node, element, callStructure,
- new ForeignResolutionResolver(visitor, this));
- if (nativeData != null) {
- // Split impact from resolution result.
- mapping.registerNativeData(node, nativeData);
- impactBuilder.registerNativeData(nativeData);
- }
- }
-
- void registerDynamicUse(DynamicUse dynamicUse) {
- impactBuilder.registerDynamicUse(dynamicUse);
- }
-
- void registerFeature(Feature feature) {
- impactBuilder.registerFeature(feature);
- }
-
- void registerConstSymbol(String name) {
- impactBuilder.registerConstSymbolName(name);
- }
-
- void registerConstantLiteral(ConstantExpression constant) {
- impactBuilder.registerConstantLiteral(constant);
- }
-
- ClassElement defaultSuperclass(ClassElement element) {
- return target.defaultSuperclass(element);
- }
-
- void registerInstantiation(ResolutionInterfaceType type) {
- impactBuilder.registerTypeUse(new TypeUse.instantiation(type));
- }
-
- void registerSendStructure(Send node, SendStructure sendStructure) {
- mapping.setSendStructure(node, sendStructure);
- }
-
- void registerNewStructure(NewExpression node, NewStructure newStructure) {
- mapping.setNewStructure(node, newStructure);
- }
-
- // TODO(johnniwinther): Remove this when [SendStructure]s are part of the
- // [ResolutionResult].
- SendStructure getSendStructure(Send node) {
- return mapping.getSendStructure(node);
- }
-
- void registerTryStatement() {
- mapping.containsTryStatement = true;
- }
-
- void registerSeenClass(ClassEntity seenClass) {
- impactBuilder.registerSeenClass(seenClass);
- }
-}
-
-class ForeignResolutionResolver implements ForeignResolver {
- final ResolverVisitor visitor;
- final ResolutionRegistry registry;
-
- ForeignResolutionResolver(this.visitor, this.registry);
-
- @override
- ConstantExpression getConstant(Node node) {
- return registry.getConstant(node);
- }
-
- @override
- void registerInstantiatedType(ResolutionInterfaceType type) {
- registry.registerInstantiation(type);
- }
-
- @override
- ResolutionDartType resolveTypeFromString(Node node, String typeName) {
- return visitor.resolveTypeFromString(node, typeName);
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
deleted file mode 100644
index ed4c280..0000000
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ /dev/null
@@ -1,1192 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution;
-
-import 'dart:collection' show Queue;
-
-import '../common.dart';
-import '../common/names.dart' show Identifiers;
-import '../common/resolution.dart'
- show ParsingContext, Resolution, ResolutionImpact, Target;
-import '../common/tasks.dart' show CompilerTask, Measurer;
-import '../compile_time_constants.dart' show ConstantCompiler;
-import '../constants/expressions.dart'
- show
- ConstantExpression,
- ConstantExpressionKind,
- ConstructedConstantExpression,
- ErroneousConstantExpression;
-import '../constants/values.dart' show ConstantValue;
-import '../common_elements.dart' show CommonElements;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../elements/modelx.dart'
- show
- BaseClassElementX,
- BaseFunctionElementX,
- ConstructorElementX,
- FieldElementX,
- FunctionElementX,
- GetterElementX,
- MetadataAnnotationX,
- MixinApplicationElementX,
- ParameterMetadataAnnotation,
- SetterElementX,
- TypedefElementX;
-import '../enqueue.dart';
-import '../options.dart';
-import 'package:front_end/src/fasta/scanner.dart'
- show
- isBinaryOperator,
- isMinusOperator,
- isTernaryOperator,
- isUnaryOperator,
- isUserDefinableOperator;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../universe/use.dart' show StaticUse;
-import '../universe/world_impact.dart' show WorldImpact;
-import '../util/util.dart' show Link, Setlet;
-import '../world.dart';
-import 'class_hierarchy.dart';
-import 'class_members.dart' show MembersCreator;
-import 'constructors.dart';
-import 'members.dart';
-import 'registry.dart';
-import 'resolution_result.dart';
-import 'signatures.dart';
-import 'tree_elements.dart';
-import 'typedefs.dart';
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-class ResolverTask extends CompilerTask {
- final ConstantCompiler constantCompiler;
- final Resolution resolution;
-
- ResolverTask(this.resolution, this.constantCompiler, Measurer measurer)
- : super(measurer);
-
- String get name => 'Resolver';
-
- DiagnosticReporter get reporter => resolution.reporter;
- Target get target => resolution.target;
- CommonElements get commonElements => resolution.commonElements;
- ParsingContext get parsingContext => resolution.parsingContext;
- CompilerOptions get options => resolution.options;
- ResolutionEnqueuer get enqueuer => resolution.enqueuer;
- OpenWorld get world => enqueuer.worldBuilder;
-
- ResolutionImpact resolve(Element element) {
- return measure(() {
- if (Elements.isMalformed(element)) {
- // TODO(johnniwinther): Add a predicate for this.
- assert(
- element is! ErroneousElement,
- failedAt(
- element, "Element $element expected to have parse errors."));
- _ensureTreeElements(element);
- return const ResolutionImpact();
- }
-
- WorldImpact processMetadata([WorldImpact result]) {
- for (MetadataAnnotation metadata in element.implementation.metadata) {
- metadata.ensureResolved(resolution);
- }
- return result;
- }
-
- if (element.isConstructor ||
- element.isFunction ||
- element.isGetter ||
- element.isSetter) {
- return processMetadata(resolveMethodElement(element));
- }
-
- if (element.isField) {
- return processMetadata(resolveField(element));
- }
- if (element.isClass) {
- ClassElement cls = element;
- cls.ensureResolved(resolution);
- return processMetadata(const ResolutionImpact());
- } else if (element.isTypedef) {
- TypedefElement typdef = element;
- return processMetadata(resolveTypedef(typdef));
- }
-
- reporter.internalError(element, "resolve($element) not implemented.");
- });
- }
-
- void resolveRedirectingConstructor(InitializerResolver resolver, Node node,
- FunctionElement constructor, FunctionElement redirection) {
- assert(
- constructor.isImplementation,
- failedAt(
- node,
- 'Redirecting constructors must be resolved on implementation '
- 'elements.'));
- Setlet<FunctionElement> seen = new Setlet<FunctionElement>();
- seen.add(constructor);
- while (redirection != null) {
- // Ensure that we follow redirections through implementation elements.
- redirection = redirection.implementation;
- if (redirection.isError) {
- break;
- }
- if (seen.contains(redirection)) {
- reporter.reportErrorMessage(
- node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
- return;
- }
- seen.add(redirection);
- redirection = resolver.visitor.resolveConstructorRedirection(redirection);
- }
- }
-
- static void processAsyncMarker(Resolution resolution,
- BaseFunctionElementX element, ResolutionRegistry registry) {
- DiagnosticReporter reporter = resolution.reporter;
- CommonElements commonElements = resolution.commonElements;
- FunctionExpression functionExpression = element.node;
- AsyncModifier asyncModifier = functionExpression.asyncModifier;
- if (asyncModifier != null) {
- if (!resolution.target.supportsAsyncAwait) {
- reporter.reportErrorMessage(functionExpression.asyncModifier,
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
- } else {
- if (asyncModifier.isAsynchronous) {
- element.asyncMarker = asyncModifier.isYielding
- ? AsyncMarker.ASYNC_STAR
- : AsyncMarker.ASYNC;
- } else {
- element.asyncMarker = AsyncMarker.SYNC_STAR;
- }
- if (element.isAbstract) {
- reporter.reportErrorMessage(
- asyncModifier,
- MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
- {'modifier': element.asyncMarker});
- } else if (element.isConstructor) {
- reporter.reportErrorMessage(
- asyncModifier,
- MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
- {'modifier': element.asyncMarker});
- } else {
- if (element.isSetter) {
- reporter.reportErrorMessage(
- asyncModifier,
- MessageKind.ASYNC_MODIFIER_ON_SETTER,
- {'modifier': element.asyncMarker});
- }
- if (functionExpression.body.asReturn() != null &&
- element.asyncMarker.isYielding) {
- reporter.reportErrorMessage(
- asyncModifier,
- MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
- {'modifier': element.asyncMarker});
- }
- }
- ClassElement cls;
- switch (element.asyncMarker) {
- case AsyncMarker.ASYNC:
- registry.registerFeature(Feature.ASYNC);
- cls = commonElements.futureClass;
- break;
- case AsyncMarker.ASYNC_STAR:
- registry.registerFeature(Feature.ASYNC_STAR);
- cls = commonElements.streamClass;
- break;
- case AsyncMarker.SYNC_STAR:
- registry.registerFeature(Feature.SYNC_STAR);
- cls = commonElements.iterableClass;
- break;
- }
- cls?.ensureResolved(resolution);
- }
- }
- }
-
- bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
- assert(classElement != null);
- while (classElement != null) {
- if (target.isNativeClass(classElement)) return true;
- classElement = classElement.superclass;
- }
- return false;
- }
-
- WorldImpact resolveMethodElementImplementation(
- FunctionElementX element, FunctionExpression tree) {
- return reporter.withCurrentElement(element, () {
- if (element.isMarkedExternal && tree.hasBody) {
- reporter.reportErrorMessage(element, MessageKind.EXTERNAL_WITH_BODY,
- {'functionName': element.name});
- }
- if (element.isConstructor) {
- if (tree.returnType != null) {
- reporter.reportErrorMessage(
- tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
- }
- if (tree.hasBody && element.isConst) {
- if (element.isGenerativeConstructor) {
- reporter.reportErrorMessage(
- tree, MessageKind.CONST_CONSTRUCTOR_WITH_BODY);
- } else if (!tree.isRedirectingFactory) {
- reporter.reportErrorMessage(tree, MessageKind.CONST_FACTORY);
- }
- }
- }
-
- ResolverVisitor visitor = visitorFor(element);
- ResolutionRegistry registry = visitor.registry;
- registry.defineFunction(tree, element);
- visitor.setupFunction(tree, element); // Modifies the scope.
- processAsyncMarker(resolution, element, registry);
-
- if (element.isGenerativeConstructor) {
- // Even if there is no initializer list we still have to do the
- // resolution in case there is an implicit super constructor call.
- InitializerResolver resolver =
- new InitializerResolver(visitor, element, tree);
- FunctionElement redirection = resolver.resolveInitializers();
- if (redirection != null) {
- resolveRedirectingConstructor(resolver, tree, element, redirection);
- }
- } else if (tree.initializers != null) {
- reporter.reportErrorMessage(
- tree, MessageKind.FUNCTION_WITH_INITIALIZER);
- }
-
- if (!options.analyzeSignaturesOnly || tree.isRedirectingFactory) {
- // We need to analyze the redirecting factory bodies to ensure that
- // we can analyze compile-time constants.
- visitor.visit(tree.body);
- }
-
- // Get the resolution tree and check that the resolved
- // function doesn't use 'super' if it is mixed into another
- // class. This is the part of the 'super' mixin check that
- // happens when a function is resolved after the mixin
- // application has been performed.
- TreeElements resolutionTree = registry.mapping;
- ClassElement enclosingClass = element.enclosingClass;
- if (enclosingClass != null) {
- // TODO(johnniwinther): Find another way to obtain mixin uses.
- ClassElement mixin = enclosingClass;
- for (MixinApplicationElement mixinApplication
- in world.allMixinUsesOf(enclosingClass)) {
- checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
- }
- }
-
- // TODO(9631): support noSuchMethod on native classes.
- if (element.isFunction &&
- element.isInstanceMember &&
- element.name == Identifiers.noSuchMethod_ &&
- _isNativeClassOrExtendsNativeClass(enclosingClass)) {
- reporter.reportErrorMessage(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
- }
-
- resolution.target.resolveNativeMember(element, registry.impactBuilder);
-
- return registry.impactBuilder;
- });
- }
-
- /// Returns `true` if [element] has been processed by the resolution enqueuer.
- bool _hasBeenProcessed(MemberElement element) {
- assert(element == element.analyzableElement.declaration,
- failedAt(element, "Unexpected element $element"));
- return enqueuer.processedEntities.contains(element);
- }
-
- WorldImpact resolveMethodElement(FunctionElementX element) {
- assert(element.isDeclaration, failedAt(element));
- return reporter.withCurrentElement(element, () {
- if (_hasBeenProcessed(element)) {
- // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
- // should never be non-null, not even for constructors.
- assert(
- element.isConstructor,
- failedAt(element,
- 'Non-constructor element $element has already been analyzed.'));
- return const ResolutionImpact();
- }
- if (element.isSynthesized) {
- if (element.isGenerativeConstructor) {
- ResolutionRegistry registry =
- new ResolutionRegistry(this.target, _ensureTreeElements(element));
- ConstructorElement constructor = element.asFunctionElement();
- ConstructorElement target = constructor.definingConstructor;
- // Ensure the signature of the synthesized element is
- // resolved. This is the only place where the resolver is
- // seeing this element.
- ResolutionFunctionType type = element.computeType(resolution);
- if (!target.isMalformed) {
- registry.registerStaticUse(new StaticUse.superConstructorInvoke(
- // TODO(johnniwinther): Provide the right call structure for
- // forwarding constructors.
- target,
- CallStructure.NO_ARGS));
- }
- // TODO(johnniwinther): Remove this substitution when synthesized
- // constructors handle type variables correctly.
- type = type.substByContext(
- constructor.enclosingClass.asInstanceOf(target.enclosingClass));
- type.parameterTypes.forEach(registry.registerCheckedModeCheck);
- type.optionalParameterTypes
- .forEach(registry.registerCheckedModeCheck);
- type.namedParameterTypes.forEach(registry.registerCheckedModeCheck);
- return registry.impactBuilder;
- } else {
- assert(element.isDeferredLoaderGetter || element.isMalformed);
- _ensureTreeElements(element);
- return const ResolutionImpact();
- }
- } else {
- element.parseNode(resolution.parsingContext);
- element.computeType(resolution);
- FunctionElementX implementation = element;
- if (element.isMarkedExternal) {
- implementation = target.resolveExternalFunction(element);
- }
- return resolveMethodElementImplementation(
- implementation, implementation.node);
- }
- });
- }
-
- /// Creates a [ResolverVisitor] for resolving an AST in context of [element].
- /// If [useEnclosingScope] is `true` then the initial scope of the visitor
- /// does not include inner scope of [element].
- ///
- /// This method should only be used by this library (or tests of
- /// this library).
- ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) {
- return new ResolverVisitor(resolution, element,
- new ResolutionRegistry(target, _ensureTreeElements(element)),
- useEnclosingScope: useEnclosingScope);
- }
-
- WorldImpact resolveField(FieldElementX element) {
- return reporter.withCurrentElement(element, () {
- VariableDefinitions tree = element.parseNode(parsingContext);
- if (element.modifiers.isStatic && element.isTopLevel) {
- reporter.reportErrorMessage(element.modifiers.getStatic(),
- MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
- }
- ResolverVisitor visitor = visitorFor(element);
- ResolutionRegistry registry = visitor.registry;
- // TODO(johnniwinther): Maybe remove this when placeholderCollector
- // migrates to the backend ast.
- registry.defineElement(element.definition, element);
- // TODO(johnniwinther): Share the resolved type between all variables
- // declared in the same declaration.
- if (tree.type != null) {
- ResolutionDartType type = visitor.resolveTypeAnnotation(tree.type);
- assert(
- element.variables.type == null ||
- // Crude check but we have no equivalence relation that
- // equates malformed types, like matching creations of type
- // `Foo<Unresolved>`.
- element.variables.type.toString() == type.toString(),
- failedAt(
- element,
- "Unexpected type computed for $element. "
- "Was ${element.variables.type}, computed $type."));
- element.variables.type = type;
- } else if (element.variables.type == null) {
- // Only assign the dynamic type if the element has no known type. This
- // happens for enum fields where the type is known but is not in the
- // synthesized AST.
- element.variables.type = const ResolutionDynamicType();
- } else {
- registry.registerCheckedModeCheck(element.variables.type);
- }
-
- Expression initializer = element.initializer;
- Modifiers modifiers = element.modifiers;
- if (initializer != null) {
- // TODO(johnniwinther): Avoid analyzing initializers if
- // [Compiler.analyzeSignaturesOnly] is set.
- ResolutionResult result = visitor.visit(initializer);
- if (result.isConstant) {
- element.constant = result.constant;
- }
- } else if (modifiers.isConst) {
- reporter.reportErrorMessage(
- element, MessageKind.CONST_WITHOUT_INITIALIZER);
- } else if (modifiers.isFinal && !element.isInstanceMember) {
- reporter.reportErrorMessage(
- element, MessageKind.FINAL_WITHOUT_INITIALIZER);
- } else {
- registry.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER);
- }
-
- if (Elements.isStaticOrTopLevelField(element)) {
- visitor.addDeferredAction(element, () {
- if (element.modifiers.isConst) {
- element.constant = constantCompiler.compileConstant(element);
- } else {
- element.constant = constantCompiler.compileVariable(element);
- }
- });
- if (initializer != null) {
- if (!element.modifiers.isConst &&
- initializer.asLiteralNull() == null) {
- // TODO(johnniwinther): Determine the const-ness eagerly to avoid
- // unnecessary registrations.
- registry.registerFeature(Feature.LAZY_FIELD);
- }
- }
- }
-
- // Perform various checks as side effect of "computing" the type.
- element.computeType(resolution);
-
- resolution.target.resolveNativeMember(element, registry.impactBuilder);
-
- return registry.impactBuilder;
- });
- }
-
- ResolutionDartType resolveTypeAnnotation(
- Element element, TypeAnnotation annotation) {
- ResolutionDartType type = _resolveReturnType(element, annotation);
- if (type.isVoid) {
- reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED);
- }
- return type;
- }
-
- ResolutionDartType _resolveReturnType(
- Element element, TypeAnnotation annotation) {
- if (annotation == null) return const ResolutionDynamicType();
- ResolutionDartType result =
- visitorFor(element).resolveTypeAnnotation(annotation);
- assert(result != null,
- failedAt(annotation, "No type computed for $annotation."));
- if (result == null) {
- // TODO(karklose): warning.
- return const ResolutionDynamicType();
- }
- return result;
- }
-
- void resolveRedirectionChain(ConstructorElement constructor, Spannable node) {
- ConstructorElement target = constructor;
- ResolutionDartType targetType;
- List<ConstructorElement> seen = new List<ConstructorElement>();
- bool isMalformed = false;
- // Follow the chain of redirections and check for cycles.
- while (target.isRedirectingFactory) {
- if (target.hasEffectiveTarget) {
- // We found a constructor that already has been processed.
- // TODO(johnniwinther): Should `effectiveTargetType` be part of the
- // interface?
- targetType =
- target.computeEffectiveTargetType(target.enclosingClass.thisType);
- assert(
- targetType != null,
- failedAt(target,
- 'Redirection target type has not been computed for $target'));
- target = target.effectiveTarget;
- break;
- }
-
- Element nextTarget = target.immediateRedirectionTarget;
-
- if (seen.contains(nextTarget)) {
- reporter.reportErrorMessage(
- node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
- targetType = target.enclosingClass.thisType;
- isMalformed = true;
- break;
- }
- seen.add(target);
- target = nextTarget;
- }
-
- if (target.isGenerativeConstructor && target.enclosingClass.isAbstract) {
- isMalformed = true;
- }
- if (target.isMalformed) {
- isMalformed = true;
- }
-
- if (targetType == null) {
- assert(!target.isRedirectingFactory);
- targetType = target.enclosingClass.thisType;
- }
-
- // [target] is now the actual target of the redirections. Run through
- // the constructors again and set their [redirectionTarget], so that we
- // do not have to run the loop for these constructors again. Furthermore,
- // compute [redirectionTargetType] for each factory by computing the
- // substitution of the target type with respect to the factory type.
- while (!seen.isEmpty) {
- ConstructorElementX factory = seen.removeLast();
- ResolvedAst resolvedAst = factory.resolvedAst;
- assert(
- resolvedAst != null, failedAt(node, 'No ResolvedAst for $factory.'));
- RedirectingFactoryBody redirectionNode = resolvedAst.body;
- ResolutionDartType factoryType =
- resolvedAst.elements.getType(redirectionNode);
- if (!factoryType.isDynamic) {
- targetType = targetType.substByContext(factoryType);
- }
- factory.setEffectiveTarget(target, targetType, isMalformed: isMalformed);
- }
- }
-
- /**
- * Load and resolve the supertypes of [cls].
- *
- * Warning: do not call this method directly. It should only be
- * called by [resolveClass] and [ClassSupertypeResolver].
- */
- void loadSupertypes(BaseClassElementX cls, Spannable from) {
- measure(() {
- if (cls.supertypeLoadState == STATE_DONE) return;
- if (cls.supertypeLoadState == STATE_STARTED) {
- reporter.reportErrorMessage(
- from, MessageKind.CYCLIC_CLASS_HIERARCHY, {'className': cls.name});
- cls.supertypeLoadState = STATE_DONE;
- cls.hasIncompleteHierarchy = true;
- ClassElement objectClass = commonElements.objectClass;
- cls.allSupertypesAndSelf = objectClass.allSupertypesAndSelf
- .extendClass(cls.computeType(resolution));
- cls.supertype = cls.allSupertypes.head;
- assert(cls.supertype != null,
- failedAt(from, 'Missing supertype on cyclic class $cls.'));
- cls.interfaces = const Link<ResolutionDartType>();
- return;
- }
- cls.supertypeLoadState = STATE_STARTED;
- reporter.withCurrentElement(cls, () {
- // TODO(ahe): Cache the node in cls.
- cls
- .parseNode(parsingContext)
- .accept(new ClassSupertypeResolver(resolution, cls));
- if (cls.supertypeLoadState != STATE_DONE) {
- cls.supertypeLoadState = STATE_DONE;
- }
- });
- });
- }
-
- // TODO(johnniwinther): Remove this queue when resolution has been split into
- // syntax and semantic resolution.
- /// Whether or not we are currently resolving a type declaration.
- ///
- /// When we are resolving a type declaration, we want to avoid resolving
- /// other type declarations that are encountered through type annotations
- /// until after we finish resolving the current declaration.
- bool isResolvingTypeDeclaration = false;
-
- bool isPostProcessingTypeDeclaration = false;
-
- /// Classes found in type annotations while resolving a type declaration.
- ///
- /// These are stored here so that they may be resolved after the original
- /// type annotation.
- Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>();
-
- /// Classes to be post-processed after the type declaration is resolved.
- Queue<ClassElement> pendingClassesToBePostProcessed =
- new Queue<ClassElement>();
-
- /// Resolve [element] using [resolveTypeDeclaration].
- ///
- /// This method ensures that class declarations encountered through type
- /// annotations during the resolution of [element] are resolved after
- /// [element] has been resolved.
- // TODO(johnniwinther): Encapsulate this functionality in a
- // 'TypeDeclarationResolver'.
- _resolveTypeDeclaration(
- TypeDeclarationElement element, resolveTypeDeclaration()) {
- return reporter.withCurrentElement(element, () {
- return measure(() {
- bool previouslyResolvingTypeDeclaration = isResolvingTypeDeclaration;
- isResolvingTypeDeclaration = true;
- var result = resolveTypeDeclaration();
- isResolvingTypeDeclaration = previouslyResolvingTypeDeclaration;
- if (!isResolvingTypeDeclaration) {
- do {
- while (pendingClassesToBeResolved.isNotEmpty) {
- pendingClassesToBeResolved
- .removeFirst()
- .ensureResolved(resolution);
- }
- if (!isPostProcessingTypeDeclaration) {
- isPostProcessingTypeDeclaration = true;
- while (pendingClassesToBePostProcessed.isNotEmpty) {
- _postProcessClassElement(
- pendingClassesToBePostProcessed.removeFirst());
- }
- isPostProcessingTypeDeclaration = false;
- }
- } while (pendingClassesToBeResolved.isNotEmpty);
- assert(pendingClassesToBeResolved.isEmpty);
- assert(pendingClassesToBePostProcessed.isEmpty ||
- isPostProcessingTypeDeclaration);
- }
- return result;
- });
- });
- }
-
- /**
- * Resolve the class [element].
- *
- * Before calling this method, [element] was constructed by the
- * scanner and most fields are null or empty. This method fills in
- * these fields and also ensure that the supertypes of [element] are
- * resolved.
- *
- * Warning: Do not call this method directly. Instead use
- * [:element.ensureResolved(resolution):].
- */
- TreeElements resolveClass(BaseClassElementX element) {
- return _resolveTypeDeclaration(element, () {
- // TODO(johnniwinther): Store the mapping in the resolution enqueuer.
- ResolutionRegistry registry = new ResolutionRegistry(
- resolution.target, _ensureTreeElements(element));
- resolveClassInternal(element, registry);
- return element.treeElements;
- });
- }
-
- void ensureClassWillBeResolvedInternal(ClassElement element) {
- if (!isResolvingTypeDeclaration) {
- element.ensureResolved(resolution);
- } else {
- pendingClassesToBeResolved.add(element);
- }
- }
-
- void resolveClassInternal(
- BaseClassElementX element, ResolutionRegistry registry) {
- if (!element.isPatch) {
- reporter.withCurrentElement(
- element,
- () => measure(() {
- assert(element.resolutionState == STATE_NOT_STARTED);
- element.resolutionState = STATE_STARTED;
- Node tree = element.parseNode(parsingContext);
- loadSupertypes(element, tree);
-
- ClassResolverVisitor visitor =
- new ClassResolverVisitor(resolution, element, registry);
- visitor.visit(tree);
- element.resolutionState = STATE_DONE;
- pendingClassesToBePostProcessed.add(element);
- }));
- if (element.isPatched) {
- // Ensure handling patch after origin.
- element.patch.ensureResolved(resolution);
- }
- } else {
- // Handle patch classes:
- element.resolutionState = STATE_STARTED;
- // Ensure handling origin before patch.
- element.origin.ensureResolved(resolution);
- // Ensure that the type is computed.
- element.computeType(resolution);
- // Copy class hierarchy from origin.
- element.supertype = element.origin.supertype;
- element.interfaces = element.origin.interfaces;
- element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf;
- // Stepwise assignment to ensure invariant.
- element.supertypeLoadState = STATE_STARTED;
- element.supertypeLoadState = STATE_DONE;
- element.resolutionState = STATE_DONE;
- // TODO(johnniwinther): Check matching type variables and
- // empty extends/implements clauses.
- }
- }
-
- void _postProcessClassElement(BaseClassElementX element) {
- for (MetadataAnnotation metadata in element.implementation.metadata) {
- metadata.ensureResolved(resolution);
- ConstantValue value =
- resolution.constants.getConstantValue(metadata.constant);
- if (!element.isProxy && resolution.isProxyConstant(value)) {
- element.isProxy = true;
- }
- }
-
- // Force resolution of metadata on non-instance members since they may be
- // inspected by the backend while emitting. Metadata on instance members is
- // handled as a result of processing instantiated class members in the
- // enqueuer.
- // TODO(ahe): Avoid this eager resolution.
- element.forEachMember((_, Element member) {
- if (!member.isInstanceMember) {
- reporter.withCurrentElement(member, () {
- for (MetadataAnnotation metadata in member.implementation.metadata) {
- metadata.ensureResolved(resolution);
- }
- });
- }
- });
-
- computeClassMember(element, Identifiers.call);
- }
-
- void computeClassMembers(ClassElement element) {
- MembersCreator.computeAllClassMembers(resolution, element);
- }
-
- void computeClassMember(ClassElement element, String name) {
- MembersCreator.computeClassMembersByName(resolution, element, name);
- }
-
- void checkClass(ClassElement element) {
- computeClassMembers(element);
- if (element.isMixinApplication) {
- checkMixinApplication(element);
- } else {
- checkClassMembers(element);
- }
- }
-
- void checkMixinApplication(MixinApplicationElementX mixinApplication) {
- Modifiers modifiers = mixinApplication.modifiers;
- int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
- if (illegalFlags != 0) {
- Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
- reporter.reportErrorMessage(
- modifiers,
- MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
- {'modifiers': illegalModifiers});
- }
-
- // In case of cyclic mixin applications, the mixin chain will have
- // been cut. If so, we have already reported the error to the
- // user so we just return from here.
- ClassElement mixin = mixinApplication.mixin;
- if (mixin == null) return;
-
- // Check that we're not trying to use Object as a mixin.
- if (mixin.superclass == null) {
- reporter.reportErrorMessage(
- mixinApplication, MessageKind.ILLEGAL_MIXIN_OBJECT);
- // Avoid reporting additional errors for the Object class.
- return;
- }
-
- if (mixin.isEnumClass) {
- // Mixing in an enum has already caused a compile-time error.
- return;
- }
-
- // Check that the mixed in class has Object as its superclass.
- if (!mixin.superclass.isObject) {
- reporter.reportErrorMessage(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
- }
-
- // Check that the mixed in class doesn't have any constructors and
- // make sure we aren't mixing in methods that use 'super'.
- mixin.forEachLocalMember((_member) {
- AstElement member = _member;
- if (member.isGenerativeConstructor && !member.isSynthesized) {
- reporter.reportErrorMessage(
- member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
- } else {
- // Get the resolution tree and check that the resolved member
- // doesn't use 'super'. This is the part of the 'super' mixin
- // check that happens when a function is resolved before the
- // mixin application has been performed.
- // TODO(johnniwinther): Obtain the [TreeElements] for [member]
- // differently.
- if (_hasBeenProcessed(member)) {
- if (member.resolvedAst.kind == ResolvedAstKind.PARSED) {
- checkMixinSuperUses(
- member.resolvedAst.elements, mixinApplication, mixin);
- }
- }
- }
- });
- }
-
- void checkMixinSuperUses(TreeElements elements,
- MixinApplicationElement mixinApplication, ClassElement mixin) {
- // TODO(johnniwinther): Avoid the use of [TreeElements] here.
- Iterable<SourceSpan> superUses = elements.superUses;
- if (superUses.isEmpty) return;
- DiagnosticMessage error = reporter.createMessage(mixinApplication,
- MessageKind.ILLEGAL_MIXIN_WITH_SUPER, {'className': mixin.name});
- // Show the user the problematic uses of 'super' in the mixin.
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- for (SourceSpan use in superUses) {
- infos.add(
- reporter.createMessage(use, MessageKind.ILLEGAL_MIXIN_SUPER_USE));
- }
- reporter.reportError(error, infos);
- }
-
- void checkClassMembers(ClassElement cls) {
- assert(cls.isDeclaration, failedAt(cls));
- if (cls.isObject) return;
- // TODO(johnniwinther): Should this be done on the implementation element as
- // well?
- List<Element> constConstructors = <Element>[];
- List<Element> nonFinalInstanceFields = <Element>[];
- cls.forEachMember((holder, dynamic member) {
- reporter.withCurrentElement(member, () {
- // Perform various checks as side effect of "computing" the type.
- member.computeType(resolution);
-
- // Check modifiers.
- // ignore: UNDEFINED_GETTER
- if (member.isFunction && member.modifiers.isFinal) {
- reporter.reportErrorMessage(
- member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
- }
- if (member.isConstructor) {
- // ignore: UNDEFINED_GETTER
- final mismatchedFlagsBits = member.modifiers.flags &
- (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
- if (mismatchedFlagsBits != 0) {
- final mismatchedFlags =
- new Modifiers.withFlags(null, mismatchedFlagsBits);
- reporter.reportErrorMessage(
- member,
- MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
- {'modifiers': mismatchedFlags});
- }
- // ignore: UNDEFINED_GETTER
- if (member.modifiers.isConst) {
- constConstructors.add(member);
- }
- }
- if (member.isField) {
- // ignore: UNDEFINED_GETTER
- if (member.modifiers.isConst && !member.modifiers.isStatic) {
- reporter.reportErrorMessage(
- member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
- }
- // ignore: UNDEFINED_GETTER
- if (!member.modifiers.isStatic && !member.modifiers.isFinal) {
- nonFinalInstanceFields.add(member);
- }
- }
- checkAbstractField(member);
- checkUserDefinableOperator(member);
- });
- });
- if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) {
- Spannable span =
- constConstructors.length > 1 ? cls : constConstructors[0];
- DiagnosticMessage error = reporter.createMessage(
- span,
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
- {'className': cls.name});
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- if (constConstructors.length > 1) {
- for (Element constructor in constConstructors) {
- infos.add(reporter.createMessage(constructor,
- MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR));
- }
- }
- for (Element field in nonFinalInstanceFields) {
- infos.add(reporter.createMessage(
- field, MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD));
- }
- reporter.reportError(error, infos);
- }
- }
-
- void checkAbstractField(Element member) {
- // Only check for getters. The test can only fail if there is both a setter
- // and a getter with the same name, and we only need to check each abstract
- // field once, so we just ignore setters.
- if (!member.isGetter) return;
-
- // Find the associated abstract field.
- ClassElement classElement = member.enclosingClass;
- Element lookupElement = classElement.lookupLocalMember(member.name);
- if (lookupElement == null) {
- reporter.internalError(member, "No abstract field for accessor");
- } else if (!lookupElement.isAbstractField) {
- if (lookupElement.isMalformed || lookupElement.isAmbiguous) return;
- reporter.internalError(
- member, "Inaccessible abstract field for accessor");
- }
- AbstractFieldElement field = lookupElement;
-
- GetterElementX getter = field.getter;
- if (getter == null) return;
- SetterElementX setter = field.setter;
- if (setter == null) return;
- int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
- int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
- if (getterFlags != setterFlags) {
- final mismatchedFlags =
- new Modifiers.withFlags(null, getterFlags ^ setterFlags);
- reporter.reportWarningMessage(field.getter, MessageKind.GETTER_MISMATCH,
- {'modifiers': mismatchedFlags});
- reporter.reportWarningMessage(field.setter, MessageKind.SETTER_MISMATCH,
- {'modifiers': mismatchedFlags});
- }
- }
-
- void checkUserDefinableOperator(Element member) {
- FunctionElement function = member.asFunctionElement();
- if (function == null) return;
- String value = member.name;
- if (value == null) return;
- if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return;
-
- bool isMinus = false;
- int requiredParameterCount;
- MessageKind messageKind;
- if (identical(value, 'unary-')) {
- isMinus = true;
- messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY;
- requiredParameterCount = 0;
- } else if (isMinusOperator(value)) {
- isMinus = true;
- messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY;
- requiredParameterCount = 1;
- } else if (isUnaryOperator(value)) {
- messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY;
- requiredParameterCount = 0;
- } else if (isBinaryOperator(value)) {
- messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY;
- requiredParameterCount = 1;
- if (identical(value, '==')) checkOverrideHashCode(member);
- } else if (isTernaryOperator(value)) {
- messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY;
- requiredParameterCount = 2;
- } else {
- reporter.internalError(
- function, 'Unexpected user defined operator $value');
- }
- checkArity(function, requiredParameterCount, messageKind, isMinus);
- }
-
- void checkOverrideHashCode(FunctionElement operatorEquals) {
- if (operatorEquals.isAbstract) return;
- ClassElement cls = operatorEquals.enclosingClass;
- Element hashCodeImplementation = cls.lookupLocalMember('hashCode');
- if (hashCodeImplementation != null) return;
- reporter.reportHintMessage(operatorEquals,
- MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, {'class': cls.name});
- }
-
- void checkArity(FunctionElement function, int requiredParameterCount,
- MessageKind messageKind, bool isMinus) {
- FunctionExpression node = function.node;
- FunctionSignature signature = function.functionSignature;
- if (signature.requiredParameterCount != requiredParameterCount) {
- Node errorNode = node;
- if (node.parameters != null) {
- if (isMinus ||
- signature.requiredParameterCount < requiredParameterCount) {
- // If there are too few parameters, point to the whole parameter list.
- // For instance
- //
- // int operator +() {}
- // ^^
- //
- // int operator []=(value) {}
- // ^^^^^^^
- //
- // For operator -, always point the whole parameter list, like
- //
- // int operator -(a, b) {}
- // ^^^^^^
- //
- // instead of
- //
- // int operator -(a, b) {}
- // ^
- //
- // since the correction might not be to remove 'b' but instead to
- // remove 'a, b'.
- errorNode = node.parameters;
- } else {
- errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
- }
- }
- reporter.reportErrorMessage(
- errorNode, messageKind, {'operatorName': function.name});
- }
- if (signature.optionalParameterCount != 0) {
- Node errorNode =
- node.parameters.nodes.skip(signature.requiredParameterCount).head;
- if (signature.optionalParametersAreNamed) {
- reporter.reportErrorMessage(
- errorNode,
- MessageKind.OPERATOR_NAMED_PARAMETERS,
- {'operatorName': function.name});
- } else {
- reporter.reportErrorMessage(
- errorNode,
- MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
- {'operatorName': function.name});
- }
- }
- }
-
- reportErrorWithContext(Element errorneousElement, MessageKind errorMessage,
- Element contextElement, MessageKind contextMessage) {
- reporter.reportError(
- reporter.createMessage(errorneousElement, errorMessage, {
- 'memberName': contextElement.name,
- 'className': contextElement.enclosingClass.name
- }),
- <DiagnosticMessage>[
- reporter.createMessage(contextElement, contextMessage),
- ]);
- }
-
- FunctionSignature resolveSignature(FunctionElementX element) {
- MessageKind defaultValuesError = null;
- if (element.isFactoryConstructor) {
- FunctionExpression body = element.parseNode(parsingContext);
- if (body.isRedirectingFactory) {
- defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
- }
- }
- return reporter.withCurrentElement(element, () {
- FunctionExpression node = element.parseNode(parsingContext);
- return measure(() => SignatureResolver.analyze(
- resolution,
- element.enclosingElement.buildScope(),
- const FunctionTypeParameterScope(),
- node.typeVariables,
- node.parameters,
- node.returnType,
- element,
- new ResolutionRegistry(
- resolution.target, _ensureTreeElements(element)),
- defaultValuesError: defaultValuesError,
- createRealParameters: true));
- });
- }
-
- WorldImpact resolveTypedef(TypedefElementX element) {
- if (element.isResolved) return const ResolutionImpact();
- world.registerTypedef(element);
- return _resolveTypeDeclaration(element, () {
- ResolutionRegistry registry = new ResolutionRegistry(
- resolution.target, _ensureTreeElements(element));
- return reporter.withCurrentElement(element, () {
- return measure(() {
- assert(element.resolutionState == STATE_NOT_STARTED);
- element.resolutionState = STATE_STARTED;
- Typedef node = element.parseNode(parsingContext);
- TypedefResolverVisitor visitor =
- new TypedefResolverVisitor(resolution, element, registry);
- visitor.visit(node);
- element.resolutionState = STATE_DONE;
- return registry.impactBuilder;
- });
- });
- });
- }
-
- void resolveMetadataAnnotation(MetadataAnnotationX annotation) {
- reporter.withCurrentElement(
- annotation.annotatedElement,
- () => measure(() {
- assert(annotation.resolutionState == STATE_NOT_STARTED);
- annotation.resolutionState = STATE_STARTED;
-
- Node node = annotation.parseNode(parsingContext);
- Element annotatedElement = annotation.annotatedElement;
- AnalyzableElement context = annotatedElement.analyzableElement;
- ClassElement classElement = annotatedElement.enclosingClass;
- if (classElement != null) {
- // The annotation is resolved in the scope of [classElement].
- classElement.ensureResolved(resolution);
- }
- assert(
- context != null,
- failedAt(
- node,
- "No context found for metadata annotation "
- "on $annotatedElement."));
- ResolverVisitor visitor =
- visitorFor(context, useEnclosingScope: true);
- ResolutionRegistry registry = visitor.registry;
- node.accept(visitor);
- // TODO(johnniwinther): Avoid passing the [TreeElements] to
- // [compileMetadata].
- ConstantExpression constant = constantCompiler.compileMetadata(
- annotation, node, registry.mapping);
- switch (constant.kind) {
- case ConstantExpressionKind.CONSTRUCTED:
- ConstructedConstantExpression constructedConstant = constant;
- ResolutionInterfaceType type = constructedConstant.type;
- if (type.isGeneric && !type.isRaw) {
- // Const constructor calls cannot have type arguments.
- // TODO(24312): Remove this.
- reporter.reportErrorMessage(
- node, MessageKind.INVALID_METADATA_GENERIC);
- constant = new ErroneousConstantExpression();
- }
- break;
- case ConstantExpressionKind.FIELD:
- 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 retrieve the backend constant and only register
- // metadata on the elements for which it is needed. (Issue 17732).
- annotation.resolutionState = STATE_DONE;
- }));
- }
-
- List<MetadataAnnotation> resolveMetadata(
- Element element, VariableDefinitions node) {
- List<MetadataAnnotation> metadata = <MetadataAnnotation>[];
- for (Metadata annotation in node.metadata.nodes) {
- ParameterMetadataAnnotation metadataAnnotation =
- new ParameterMetadataAnnotation(annotation);
- metadataAnnotation.annotatedElement = element;
- metadata.add(metadataAnnotation.ensureResolved(resolution));
- }
- return metadata;
- }
-}
-
-TreeElements _ensureTreeElements(AnalyzableElementX element) {
- if (element._treeElements == null) {
- element._treeElements = new TreeElementMapping(element);
- }
- return element._treeElements;
-}
-
-abstract class AnalyzableElementX implements AnalyzableElement {
- TreeElements _treeElements;
-
- bool get hasTreeElements => _treeElements != null;
-
- TreeElements get treeElements {
- assert(_treeElements != null,
- failedAt(this, "TreeElements have not been computed for $this."));
- return _treeElements;
- }
-
- void reuseElement() {
- _treeElements = null;
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution_common.dart b/pkg/compiler/lib/src/resolution/resolution_common.dart
deleted file mode 100644
index 4428cd3..0000000
--- a/pkg/compiler/lib/src/resolution/resolution_common.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.common;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../enqueue.dart' show DeferredAction;
-import '../tree/tree.dart';
-import 'registry.dart' show ResolutionRegistry;
-import 'scope.dart' show Scope;
-import 'type_resolver.dart' show TypeResolver;
-
-class CommonResolverVisitor<R> extends Visitor<R> {
- final Resolution resolution;
-
- CommonResolverVisitor(this.resolution);
-
- DiagnosticReporter get reporter => resolution.reporter;
-
- R visitNode(Node node) {
- return reporter.internalError(
- node, 'internal error: Unhandled node: ${node.getObjectDescription()}');
- }
-
- R visitEmptyStatement(EmptyStatement node) => null;
-
- /** Convenience method for visiting nodes that may be null. */
- R visit(Node node) => (node == null) ? null : node.accept(this);
-
- void addDeferredAction(Element element, void action()) {
- resolution.enqueuer.addDeferredAction(new DeferredAction(element, action));
- }
-}
-
-/**
- * Common supertype for resolver visitors that record resolutions in a
- * [ResolutionRegistry].
- */
-abstract class MappingVisitor<T> extends CommonResolverVisitor<T> {
- final ResolutionRegistry registry;
- final TypeResolver typeResolver;
-
- /// The current enclosing element for the visited AST nodes.
- Element get enclosingElement;
-
- /// The current scope of the visitor.
- Scope get scope;
-
- MappingVisitor(Resolution resolution, this.registry)
- : typeResolver = new TypeResolver(resolution),
- super(resolution);
-
- AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC;
-
- /// Add [element] to the current scope and check for duplicate definitions.
- void addToScope(Element element) {
- if (element is FormalElement && element.isUnnamed) {
- // No duplicate names possible.
- return;
- }
- Element existing = scope.add(element);
- if (existing != element) {
- reportDuplicateDefinition(element.name, element, existing);
- }
- }
-
- void checkLocalDefinitionName(Node node, Element element) {
- if (currentAsyncMarker != AsyncMarker.SYNC) {
- if (element.name == 'yield' ||
- element.name == 'async' ||
- element.name == 'await') {
- reporter.reportErrorMessage(
- node,
- MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
- {'keyword': element.name, 'modifier': currentAsyncMarker});
- }
- }
- }
-
- /// Register [node] as the definition of [element].
- void defineLocalVariable(Node node, LocalVariableElement element) {
- if (element == null) {
- throw reporter.internalError(node, 'element is null');
- }
- checkLocalDefinitionName(node, element);
- registry.defineElement(node, element);
- }
-
- void reportDuplicateDefinition(
- String name, Spannable definition, Spannable existing) {
- reporter.reportError(
- reporter.createMessage(
- definition, MessageKind.DUPLICATE_DEFINITION, {'name': name}),
- <DiagnosticMessage>[
- reporter.createMessage(
- existing, MessageKind.EXISTING_DEFINITION, {'name': name}),
- ]);
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution_result.dart b/pkg/compiler/lib/src/resolution/resolution_result.dart
deleted file mode 100644
index fd7576f..0000000
--- a/pkg/compiler/lib/src/resolution/resolution_result.dart
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.result;
-
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-
-enum ResultKind {
- NONE,
- ELEMENT,
- TYPE,
- ASSERT,
- CONSTANT,
- PREFIX,
-}
-
-/// The result of resolving a node.
-abstract class ResolutionResult {
- const ResolutionResult();
-
- // TODO(johnniwinther): Remove this factory constructor when `null` is never
- // passed as an element result.
- factory ResolutionResult.forElement(Element element) {
- return element != null ? new ElementResult(element) : const NoneResult();
- }
-
- ResultKind get kind;
- Node get node => null;
- Element get element => null;
- ResolutionDartType get type => null;
- ConstantExpression get constant => null;
- bool get isConstant => false;
-}
-
-/// The prefix of top level or member access, like `prefix.member`,
-/// `prefix.Class.member` or `Class.member`.
-class PrefixResult extends ResolutionResult {
- final PrefixElement prefix;
- final ClassElement cls;
-
- PrefixResult(this.prefix, this.cls);
-
- Element get element => cls != null ? cls : prefix;
-
- bool get isDeferred => prefix != null && prefix.isDeferred;
-
- ResultKind get kind => ResultKind.PREFIX;
-
- String toString() => 'PrefixResult($prefix,$cls)';
-}
-
-/// The result for the resolution of a node that points to an [Element].
-class ElementResult extends ResolutionResult {
- final Element element;
-
- ResultKind get kind => ResultKind.ELEMENT;
-
- ElementResult(this.element) {
- assert(element != null);
- }
-
- String toString() => 'ElementResult($element)';
-}
-
-/// The result for the resolution of a node that points to an
-/// [ResolutionDartType].
-class TypeResult extends ResolutionResult {
- final ResolutionDartType type;
-
- TypeResult(this.type) {
- assert(type != null);
- }
-
- ResultKind get kind => ResultKind.TYPE;
-
- Element get element => type.element;
-
- String toString() => 'TypeResult($type)';
-}
-
-/// The result for resolving a constant expression.
-class ConstantResult extends ResolutionResult {
- final Node node;
- final ConstantExpression constant;
- final Element element;
-
- /// Creates a result for the [constant] expression. [node] is provided for
- /// error reporting on the constant and [element] is provided if the
- /// expression additionally serves an [Element] like [ElementResult].
- ConstantResult(this.node, this.constant, {this.element});
-
- bool get isConstant => true;
-
- ResultKind get kind => ResultKind.CONSTANT;
-
- String toString() => 'ConstantResult(${constant.toDartText()})';
-}
-
-class NoneResult extends ResolutionResult {
- const NoneResult();
-
- ResultKind get kind => ResultKind.NONE;
-
- String toString() => 'NoneResult()';
-}
-
-/// The result of resolving a list of arguments.
-class ArgumentsResult {
- /// The call structure of the arguments.
- final CallStructure callStructure;
-
- /// The resolutions results for each argument.
- final List<ResolutionResult> argumentResults;
-
- /// `true` if the arguments are valid as arguments to a constructed constant
- /// expression.
- final bool isValidAsConstant;
-
- ArgumentsResult(this.callStructure, this.argumentResults,
- {this.isValidAsConstant});
-
- /// Returns the list of [ConstantExpression]s for each of the arguments. If
- /// [isValidAsConstant] is `false`, `null` is returned.
- List<ConstantExpression> get constantArguments {
- if (!isValidAsConstant) return null;
- return argumentResults.map((ResolutionResult result) {
- return result.constant;
- }).toList();
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
deleted file mode 100644
index 0b51c6f..0000000
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ /dev/null
@@ -1,1069 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution_strategy;
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import '../../compiler_new.dart' as api;
-import '../common.dart';
-import '../common/backend_api.dart';
-import '../common/names.dart';
-import '../common/resolution.dart';
-import '../common/tasks.dart';
-import '../common/work.dart';
-import '../common_elements.dart';
-import '../compiler.dart';
-import '../constants/expressions.dart' show ConstantExpression;
-import '../constants/values.dart';
-import '../deferred_load.dart' show DeferredLoadTask;
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/modelx.dart';
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../enqueue.dart';
-import '../environment.dart';
-import '../frontend_strategy.dart';
-import '../js_backend/backend.dart';
-import '../js_backend/backend_usage.dart';
-import '../js_backend/interceptor_data.dart';
-import '../js_backend/mirrors_analysis.dart';
-import '../js_backend/mirrors_data.dart';
-import '../js_backend/native_data.dart';
-import '../js_backend/no_such_method_registry.dart';
-import '../js_backend/runtime_types.dart';
-import '../library_loader.dart';
-import '../native/enqueue.dart' show NativeResolutionEnqueuer;
-import '../native/resolver.dart';
-import '../patch_parser.dart';
-import '../resolved_uri_translator.dart';
-import '../tree/tree.dart' show Node;
-import '../universe/call_structure.dart';
-import '../universe/class_hierarchy_builder.dart';
-import '../universe/use.dart';
-import '../universe/world_builder.dart';
-import '../universe/world_impact.dart';
-
-import 'deferred_load.dart';
-import 'no_such_method_resolver.dart';
-
-/// [FrontendStrategy] that loads '.dart' files and creates a resolved element
-/// model using the resolver.
-class ResolutionFrontEndStrategy extends FrontendStrategyBase
- with ComputeSpannableMixin {
- final Compiler _compiler;
- final _CompilerElementEnvironment _elementEnvironment;
- final CommonElements commonElements;
- RuntimeTypesNeedBuilder _runtimeTypesNeedBuilder;
-
- AnnotationProcessor _annotationProcessor;
-
- factory ResolutionFrontEndStrategy(Compiler compiler) {
- ElementEnvironment elementEnvironment =
- new _CompilerElementEnvironment(compiler);
- CommonElements commonElements = new CommonElements(elementEnvironment);
- return new ResolutionFrontEndStrategy.internal(
- compiler, elementEnvironment, commonElements);
- }
-
- ResolutionFrontEndStrategy.internal(
- this._compiler, this._elementEnvironment, this.commonElements);
-
- ElementEnvironment get elementEnvironment => _elementEnvironment;
-
- DartTypes get dartTypes => _compiler.resolution.types;
-
- LibraryLoaderTask createLibraryLoader(
- ResolvedUriTranslator uriTranslator,
- ScriptLoader scriptLoader,
- api.CompilerInput compilerInput,
- ElementScanner scriptScanner,
- PatchResolverFunction patchResolverFunc,
- PatchParserTask patchParser,
- Environment environment,
- DiagnosticReporter reporter,
- Measurer measurer) {
- return new ResolutionLibraryLoaderTask(
- uriTranslator,
- scriptLoader,
- scriptScanner,
- patchResolverFunc,
- patchParser,
- environment,
- reporter,
- measurer);
- }
-
- AnnotationProcessor get annotationProcesser => _annotationProcessor ??=
- new _ElementAnnotationProcessor(_compiler, nativeBasicDataBuilder);
-
- DeferredLoadTask createDeferredLoadTask(Compiler compiler) =>
- new AstDeferredLoadTask(_compiler);
-
- @override
- NativeClassFinder createNativeClassFinder(NativeBasicData nativeBasicData) {
- return new ResolutionNativeClassFinder(
- _compiler.resolution,
- _compiler.reporter,
- elementEnvironment,
- commonElements,
- nativeBasicData);
- }
-
- NoSuchMethodResolver createNoSuchMethodResolver() =>
- new ResolutionNoSuchMethodResolver();
-
- MirrorsDataBuilder createMirrorsDataBuilder() {
- return new ResolutionMirrorsData(
- _compiler, elementEnvironment, commonElements);
- }
-
- MirrorsResolutionAnalysis createMirrorsResolutionAnalysis(
- JavaScriptBackend backend) =>
- new MirrorsResolutionAnalysisImpl(backend, _compiler.resolution);
-
- RuntimeTypesNeedBuilder createRuntimeTypesNeedBuilder() {
- return _runtimeTypesNeedBuilder ??= _compiler.options.disableRtiOptimization
- ? const TrivialRuntimeTypesNeedBuilder()
- : new ResolutionRuntimeTypesNeedBuilderImpl(
- elementEnvironment, dartTypes);
- }
-
- RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
- _runtimeTypesNeedBuilder;
-
- ResolutionWorldBuilder createResolutionWorldBuilder(
- NativeBasicData nativeBasicData,
- NativeDataBuilder nativeDataBuilder,
- InterceptorDataBuilder interceptorDataBuilder,
- BackendUsageBuilder backendUsageBuilder,
- RuntimeTypesNeedBuilder rtiNeedBuilder,
- NativeResolutionEnqueuer nativeResolutionEnqueuer,
- NoSuchMethodRegistry noSuchMethodRegistry,
- SelectorConstraintsStrategy selectorConstraintsStrategy,
- ClassHierarchyBuilder classHierarchyBuilder,
- ClassQueries classQueries) {
- return new ElementResolutionWorldBuilder(
- _compiler.backend,
- _compiler.resolution,
- nativeBasicData,
- nativeDataBuilder,
- interceptorDataBuilder,
- backendUsageBuilder,
- rtiNeedBuilder,
- nativeResolutionEnqueuer,
- noSuchMethodRegistry,
- selectorConstraintsStrategy,
- classHierarchyBuilder,
- classQueries);
- }
-
- WorkItemBuilder createResolutionWorkItemBuilder(
- NativeBasicData nativeBasicData,
- NativeDataBuilder nativeDataBuilder,
- ImpactTransformer impactTransformer,
- Map<Entity, WorldImpact> impactCache) {
- return new ResolutionWorkItemBuilder(_compiler.resolution);
- }
-
- ClassQueries createClassQueries() {
- return new ElementClassQueries(commonElements);
- }
-
- FunctionEntity computeMain(
- covariant LibraryElement mainApp, WorldImpactBuilder impactBuilder) {
- _elementEnvironment._mainLibrary = mainApp;
- if (mainApp == null) return null;
- MethodElement mainFunction;
- Element main = mainApp.findExported(Identifiers.main);
- ErroneousElement errorElement = null;
- if (main == null) {
- if (_compiler.options.analyzeOnly) {
- if (!_compiler.analyzeAll) {
- errorElement = new ErroneousElementX(MessageKind.CONSIDER_ANALYZE_ALL,
- {'main': Identifiers.main}, Identifiers.main, mainApp);
- }
- } else {
- // Compilation requires a main method.
- errorElement = new ErroneousElementX(MessageKind.MISSING_MAIN,
- {'main': Identifiers.main}, Identifiers.main, mainApp);
- }
- mainFunction = commonElements.missingMain;
- } else if (main.isError && main.isSynthesized) {
- if (main is ErroneousElement) {
- errorElement = main;
- } else {
- _compiler.reporter
- .internalError(main, 'Problem with ${Identifiers.main}.');
- }
- mainFunction = commonElements.badMain;
- } else if (!main.isFunction) {
- errorElement = new ErroneousElementX(MessageKind.MAIN_NOT_A_FUNCTION,
- {'main': Identifiers.main}, Identifiers.main, main);
- mainFunction = commonElements.badMain;
- } else {
- mainFunction = main;
- mainFunction.computeType(_compiler.resolution);
- FunctionSignature parameters = mainFunction.functionSignature;
- if (parameters.requiredParameterCount > 2) {
- int index = 0;
- parameters.orderedForEachParameter((Element parameter) {
- if (index++ < 2) return;
- errorElement = new ErroneousElementX(
- MessageKind.MAIN_WITH_EXTRA_PARAMETER,
- {'main': Identifiers.main},
- Identifiers.main,
- parameter);
- // Don't warn about main not being used:
- impactBuilder.registerStaticUse(
- new StaticUse.staticInvoke(mainFunction, CallStructure.NO_ARGS));
-
- mainFunction = commonElements.mainHasTooManyParameters;
- });
- }
- }
- if (mainFunction == null) {
- if (errorElement == null &&
- !_compiler.options.analyzeOnly &&
- !_compiler.analyzeAll) {
- _compiler.reporter
- .internalError(mainApp, "Problem with '${Identifiers.main}'.");
- } else {
- mainFunction = errorElement;
- }
- }
- if (errorElement != null &&
- errorElement.isSynthesized &&
- !mainApp.isSynthesized) {
- _compiler.reporter.reportWarningMessage(errorElement,
- errorElement.messageKind, errorElement.messageArguments);
- }
- MethodElement mainMethod;
- if (mainFunction != null && !mainFunction.isMalformed) {
- mainFunction.computeType(_compiler.resolution);
- mainMethod = mainFunction;
- }
- _elementEnvironment._mainFunction = mainMethod;
- return mainMethod;
- }
-}
-
-class ComputeSpannableMixin {
- SourceSpan spanFromToken(Element currentElement, Token token) =>
- _spanFromTokens(currentElement, token, token);
-
- SourceSpan _spanFromTokens(Element currentElement, Token begin, Token end,
- [Uri uri]) {
- if (begin == null || end == null) {
- // TODO(ahe): We can almost always do better. Often it is only
- // end that is null. Otherwise, we probably know the current
- // URI.
- throw 'Cannot find tokens to produce error message.';
- }
- if (uri == null && currentElement != null) {
- if (currentElement is! Element) {
- throw 'Can only find tokens from an Element.';
- }
- Element element = currentElement;
- uri = element.compilationUnit.script.resourceUri;
- String message;
- assert(() {
- bool sameToken(Token token, Token sought) {
- if (token == sought) return true;
- if (token.stringValue == '[') {
- // `[` is converted to `[]` in the parser when needed.
- return sought.stringValue == '[]' &&
- token.charOffset <= sought.charOffset &&
- sought.charOffset < token.charEnd;
- }
- if (token.stringValue == '>>') {
- // `>>` is converted to `>` in the parser when needed.
- return sought.stringValue == '>' &&
- token.charOffset <= sought.charOffset &&
- sought.charOffset < token.charEnd;
- }
- return false;
- }
-
- /// Check that [begin] and [end] can be found between [from] and [to].
- validateToken(Token from, Token to) {
- if (from == null || to == null) return true;
- bool foundBegin = false;
- bool foundEnd = false;
- Token token = from;
- while (true) {
- if (sameToken(token, begin)) {
- foundBegin = true;
- }
- if (sameToken(token, end)) {
- foundEnd = true;
- }
- if (foundBegin && foundEnd) {
- return true;
- }
- if (token == to || token == token.next || token.next == null) {
- break;
- }
- token = token.next;
- }
-
- // Create a good message for when the tokens were not found.
- StringBuffer sb = new StringBuffer();
- sb.write('Invalid current element: $element. ');
- sb.write('Looking for ');
- sb.write('[${begin} (${begin.hashCode}),');
- sb.write('${end} (${end.hashCode})] in');
-
- token = from;
- while (true) {
- sb.write('\n ${token} (${token.hashCode})');
- if (token == to || token == token.next || token.next == null) {
- break;
- }
- token = token.next;
- }
- message = sb.toString();
- return false;
- }
-
- if (element.enclosingClass != null &&
- element.enclosingClass.isEnumClass) {
- // Enums ASTs are synthesized (and give messed up messages).
- return true;
- }
-
- if (element is AstElement) {
- AstElement astElement = element;
- if (astElement.hasNode) {
- Token from = astElement.node.getBeginToken();
- Token to = astElement.node.getEndToken();
- if (astElement.metadata.isNotEmpty) {
- if (!astElement.metadata.first.hasNode) {
- // We might try to report an error while parsing the metadata
- // itself.
- return true;
- }
- from = astElement.metadata.first.node.getBeginToken();
- }
- return validateToken(from, to);
- }
- }
- return true;
- }(), failedAt(currentElement, message));
- }
- return new SourceSpan.fromTokens(uri, begin, end);
- }
-
- SourceSpan _spanFromNode(Element currentElement, Node node) {
- return _spanFromTokens(
- currentElement, node.getBeginToken(), node.getPrefixEndToken());
- }
-
- SourceSpan _spanFromElement(Element currentElement, Element element) {
- if (element != null && element.sourcePosition != null) {
- return element.sourcePosition;
- }
- while (element != null && element.isSynthesized) {
- element = element.enclosingElement;
- }
- if (element != null &&
- element.sourcePosition == null &&
- !element.isLibrary &&
- !element.isCompilationUnit) {
- // Sometimes, the backend fakes up elements that have no
- // position. So we use the enclosing element instead. It is
- // not a good error location, but cancel really is "internal
- // error" or "not implemented yet", so the vicinity is good
- // enough for now.
- element = element.enclosingElement;
- // TODO(ahe): I plan to overhaul this infrastructure anyways.
- }
- if (element == null) {
- element = currentElement;
- }
- if (element == null) {
- return null;
- }
-
- if (element.sourcePosition != null) {
- return element.sourcePosition;
- }
- Token position = element.position;
- Uri uri = element.compilationUnit.script.resourceUri;
- return (position == null)
- ? new SourceSpan(uri, 0, 0)
- : _spanFromTokens(currentElement, position, position, uri);
- }
-
- SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement) {
- if (spannable is Node) {
- return _spanFromNode(currentElement, spannable);
- } else if (spannable is Element) {
- return _spanFromElement(currentElement, spannable);
- } else if (spannable is MetadataAnnotation) {
- return spannable.sourcePosition;
- } else if (spannable is LocalVariable) {
- return spanFromSpannable(spannable.executableContext, currentElement);
- }
- return null;
- }
-}
-
-/// An element environment base on a [Compiler].
-class _CompilerElementEnvironment extends ElementEnvironment {
- final Compiler _compiler;
-
- LibraryEntity _mainLibrary;
- FunctionEntity _mainFunction;
-
- _CompilerElementEnvironment(this._compiler);
-
- LibraryProvider get _libraryProvider => _compiler.libraryLoader;
- Resolution get _resolution => _compiler.resolution;
-
- ResolutionDynamicType get dynamicType => const ResolutionDynamicType();
-
- @override
- LibraryEntity get mainLibrary => _mainLibrary;
-
- @override
- FunctionEntity get mainFunction => _mainFunction;
-
- @override
- Iterable<LibraryEntity> get libraries => _compiler.libraryLoader.libraries;
-
- @override
- String getLibraryName(covariant LibraryElement library) =>
- library.libraryName;
-
- @override
- ResolutionInterfaceType getThisType(covariant ClassElement cls) {
- cls.ensureResolved(_resolution);
- return cls.thisType;
- }
-
- @override
- ResolutionInterfaceType getRawType(covariant ClassElement cls) {
- cls.ensureResolved(_resolution);
- return cls.rawType;
- }
-
- @override
- bool isGenericClass(ClassEntity cls) {
- return getThisType(cls).typeArguments.isNotEmpty;
- }
-
- @override
- bool isMixinApplication(covariant ClassElement cls) {
- return cls.isMixinApplication;
- }
-
- @override
- bool isUnnamedMixinApplication(covariant ClassElement cls) {
- return cls.isUnnamedMixinApplication;
- }
-
- @override
- ClassEntity getEffectiveMixinClass(covariant ClassElement cls) {
- if (!cls.isMixinApplication) return null;
- do {
- MixinApplicationElement mixinApplication = cls;
- cls = mixinApplication.mixin;
- } while (cls.isMixinApplication);
- return cls;
- }
-
- @override
- ResolutionDartType getTypeVariableBound(
- covariant TypeVariableElement typeVariable) {
- return typeVariable.bound;
- }
-
- @override
- ResolutionInterfaceType createInterfaceType(covariant ClassElement cls,
- covariant List<ResolutionDartType> typeArguments) {
- cls.ensureResolved(_resolution);
- return cls.thisType.createInstantiation(typeArguments);
- }
-
- @override
- MemberElement lookupLocalClassMember(covariant ClassElement cls, String name,
- {bool setter: false, bool required: false}) {
- cls.ensureResolved(_resolution);
- Element member = cls.implementation.lookupLocalMember(name);
- if (member != null && member.isAbstractField) {
- AbstractFieldElement abstractField = member;
- if (setter) {
- member = abstractField.setter;
- } else {
- member = abstractField.getter;
- }
- if (member == null && required) {
- failedAt(
- cls,
- "The class '${cls.name}' does not contain required "
- "${setter ? 'setter' : 'getter'}: '$name'.");
- }
- }
- if (member == null && required) {
- throw new SpannableAssertionFailure(
- cls,
- "The class '${cls.name}' does not "
- "contain required member: '$name'.");
- }
- return member?.declaration;
- }
-
- @override
- ConstructorElement lookupConstructor(covariant ClassElement cls, String name,
- {bool required: false}) {
- cls.ensureResolved(_resolution);
- ConstructorElement constructor = cls.implementation.lookupConstructor(name);
- // TODO(johnniwinther): Skip redirecting factories.
- if (constructor == null && required) {
- throw new SpannableAssertionFailure(
- cls,
- "The class '${cls.name}' does not contain "
- "required constructor: '$name'.");
- }
- return constructor?.declaration;
- }
-
- @override
- void forEachLocalClassMember(
- covariant ClassElement cls, void f(MemberElement member)) {
- cls.ensureResolved(_resolution);
-
- void handleMember(_member) {
- MemberElement member = _member;
- if (member.isSynthesized) return;
- if (member.isMalformed) return;
- if (member.isConstructor) return;
- if (!member.isDeclaration) return;
- f(member);
- }
-
- cls.forEachLocalMember(handleMember);
- if (cls.isPatched) {
- cls.implementation.forEachLocalMember(handleMember);
- }
- }
-
- @override
- void forEachInjectedClassMember(
- covariant ClassElement cls, void f(MemberElement member)) {}
-
- @override
- void forEachClassMember(covariant ClassElement cls,
- void f(ClassElement declarer, MemberElement member)) {
- cls.ensureResolved(_resolution);
- cls.forEachMember((ClassElement declarer, _member) {
- MemberElement member = _member;
- if (member.isSynthesized) return;
- if (member.isMalformed) return;
- if (member.isConstructor) return;
- f(declarer, member);
- }, includeSuperAndInjectedMembers: true);
- }
-
- @override
- void forEachConstructor(
- covariant ClassElement cls, void f(ConstructorEntity constructor),
- {bool ensureResolved: true}) {
- if (ensureResolved) cls.ensureResolved(_resolution);
- for (ConstructorElement constructor in cls.implementation.constructors) {
- if (ensureResolved) _resolution.ensureResolved(constructor.declaration);
- if (constructor.isRedirectingFactory) continue;
- f(constructor);
- }
- }
-
- @override
- void forEachConstructorBody(
- covariant ClassElement cls, void f(ConstructorBodyEntity constructor)) {
- cls.forEachConstructorBody(f);
- }
-
- @override
- void forEachNestedClosure(
- covariant MemberElement member, void f(FunctionEntity closure)) {
- for (var closure in member.nestedClosures) {
- f(closure);
- }
- }
-
- @override
- ClassEntity getSuperClass(covariant ClassElement cls,
- {bool skipUnnamedMixinApplications: false}) {
- cls.ensureResolved(_resolution);
- ClassElement superclass = cls.superclass;
- if (skipUnnamedMixinApplications) {
- while (superclass != null && superclass.isUnnamedMixinApplication) {
- superclass = superclass.superclass;
- }
- }
- return superclass;
- }
-
- @override
- void forEachSupertype(
- covariant ClassElement cls, void f(ResolutionInterfaceType supertype)) {
- cls.allSupertypes.forEach((InterfaceType supertype) => f(supertype));
- }
-
- @override
- void forEachMixin(covariant ClassElement cls, void f(ClassElement mixin)) {
- for (; cls != null; cls = cls.superclass) {
- if (cls.isMixinApplication) {
- MixinApplicationElement mixinApplication = cls;
- f(mixinApplication.mixin);
- }
- }
- }
-
- @override
- MemberElement lookupLibraryMember(
- covariant LibraryElement library, String name,
- {bool setter: false, bool required: false}) {
- Element member = library.implementation.findLocal(name);
- if (member != null && member.isAbstractField) {
- AbstractFieldElement abstractField = member;
- if (setter) {
- member = abstractField.setter;
- } else {
- member = abstractField.getter;
- }
- if (member == null && required) {
- failedAt(
- library,
- "The library '${library.canonicalUri}' does not contain required "
- "${setter ? 'setter' : 'getter'}: '$name'.");
- }
- }
- if (member is! MemberElement) {
- member = null;
- }
- if (member == null && required) {
- failedAt(
- library,
- "The library '${library.canonicalUri}' does not "
- "contain required member: '$name'.");
- }
- return member?.declaration;
- }
-
- @override
- void forEachLibraryMember(
- covariant LibraryElement library, void f(MemberEntity member)) {
- library.implementation.forEachLocalMember((Element element) {
- if (!element.isClass && !element.isTypedef) {
- MemberElement member = element;
- f(member);
- }
- });
- }
-
- @override
- ClassElement lookupClass(covariant LibraryElement library, String name,
- {bool required: false}) {
- Element cls = library.implementation.findLocal(name);
- if (cls is! ClassElement) {
- cls = null;
- }
- if (cls == null && required) {
- failedAt(
- library,
- "The library '${library.libraryName}' does not "
- "contain required class: '$name'.");
- }
- return cls?.declaration;
- }
-
- @override
- void forEachClass(covariant LibraryElement library, void f(ClassEntity cls)) {
- library.implementation.forEachLocalMember((dynamic member) {
- if (member.isClass) {
- ClassElement cls = member;
- f(cls);
- }
- });
- }
-
- @override
- LibraryElement lookupLibrary(Uri uri, {bool required: false}) {
- LibraryElement library = _libraryProvider.lookupLibrary(uri);
- // If the script of the library is synthesized, the library does not exist
- // and we do not try to load the helpers.
- //
- // This could for example happen if dart:async is disabled, then loading it
- // should not try to find the given element.
- if (library != null && library.isSynthesized) {
- return null;
- }
- if (library == null && required) {
- failedAt(NO_LOCATION_SPANNABLE, "The library '${uri}' was not found.");
- }
- return library;
- }
-
- @override
- bool isDeferredLoadLibraryGetter(covariant MemberElement member) {
- return member.isDeferredLoaderGetter;
- }
-
- @override
- ResolutionFunctionType getFunctionType(covariant MethodElement method) {
- if (method is ConstructorBodyElement) {
- return method.constructor.type;
- }
- method.computeType(_resolution);
- ResolutionFunctionType type = method.type;
- if (method.isConstructor) {
- ConstructorElement constructor = method;
- if (constructor.definingConstructor != null) {
- // The type of a defining constructor doesn't use the right type
- // variables. Substitute the type variable of the defining class by the
- // type variables of the enclosing class.
- ClassElement definingClass =
- constructor.definingConstructor.enclosingClass;
- type = type.substByContext(
- method.enclosingClass.thisType.asInstanceOf(definingClass));
- }
- }
- return type;
- }
-
- @override
- List<TypeVariableType> getFunctionTypeVariables(FunctionEntity function) {
- return const <TypeVariableType>[];
- }
-
- @override
- DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function) {
- return dynamicType;
- }
-
- @override
- DartType getAsyncOrSyncStarElementType(AsyncMarker marker, DartType type) {
- return dynamicType;
- }
-
- @override
- DartType getFieldType(covariant FieldElement field) {
- field.computeType(_resolution);
- return field.type;
- }
-
- @override
- ResolutionFunctionType getLocalFunctionType(
- covariant LocalFunctionElement function) {
- return function.type;
- }
-
- @override
- ConstantExpression getFieldConstant(covariant FieldElement field) {
- return field.constant;
- }
-
- @override
- ResolutionDartType getUnaliasedType(covariant ResolutionDartType type) {
- type.computeUnaliased(_resolution);
- return type.unaliased;
- }
-
- @override
- Iterable<ConstantValue> getMemberMetadata(covariant MemberElement element,
- {bool includeParameterMetadata: false}) {
- List<ConstantValue> values = <ConstantValue>[];
- values.addAll(_getMetadataOf(element));
- if (includeParameterMetadata) {
- if (element.isFunction || element.isConstructor || element.isSetter) {
- MethodElement function = element.implementation;
- function.functionSignature.forEachParameter(
- (parameter) => values.addAll(_getMetadataOf(parameter)));
- }
- }
- return values;
- }
-
- @override
- Iterable<ConstantValue> getLibraryMetadata(covariant LibraryElement element) {
- return _getMetadataOf(element);
- }
-
- @override
- Iterable<ImportEntity> getImports(covariant LibraryElement library) {
- return library.imports;
- }
-
- @override
- Iterable<ConstantValue> getClassMetadata(covariant ClassElement element) {
- return _getMetadataOf(element);
- }
-
- @override
- Iterable<ConstantValue> getTypedefMetadata(covariant TypedefElement element) {
- return _getMetadataOf(element);
- }
-
- Iterable<ConstantValue> _getMetadataOf(Element element) {
- List<ConstantValue> constants = <ConstantValue>[];
- _compiler.reporter.withCurrentElement(element, () {
- for (MetadataAnnotation metadata in element.implementation.metadata) {
- metadata.ensureResolved(_compiler.resolution);
- assert(metadata.constant != null,
- failedAt(metadata, "Unevaluated metadata constant."));
- constants.add(
- _compiler.backend.constants.getConstantValue(metadata.constant));
- }
- });
- return constants;
- }
-
- @override
- ResolutionFunctionType getFunctionTypeOfTypedef(
- covariant TypedefElement typedef) {
- var result = typedef.alias;
- if (result.isMalformed) return null;
- return result;
- }
-
- @override
- ResolutionTypedefType getTypedefTypeOfTypedef(
- covariant TypedefElement typedef) =>
- typedef.thisType;
-
- @override
- bool isEnumClass(covariant ClassElement cls) => cls.isEnumClass;
-}
-
-/// AST-based logic for processing annotations. These annotations are processed
-/// very early in the compilation pipeline, typically this is before resolution
-/// is complete. Because of that this processor does a lightweight parse of the
-/// annotation (which is restricted to a limited subset of the annotation
-/// syntax), and, once resolution completes, it validates that the parsed
-/// annotations correspond to the correct element.
-class _ElementAnnotationProcessor implements AnnotationProcessor {
- final Compiler _compiler;
- final NativeBasicDataBuilder _nativeBasicDataBuilder;
-
- _ElementAnnotationProcessor(this._compiler, this._nativeBasicDataBuilder);
-
- CommonElements get _commonElements => _compiler.resolution.commonElements;
-
- /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its
- /// native name from the annotation.
- void extractNativeAnnotations(covariant LibraryElement library) {
- library.forEachLocalMember((Element element) {
- if (element.isClass) {
- EagerAnnotationHandler.checkAnnotation(_compiler, element,
- new NativeAnnotationHandler(_nativeBasicDataBuilder));
- }
- });
- }
-
- void extractJsInteropAnnotations(covariant LibraryElement library) {
- bool checkJsInteropAnnotation(Element element) {
- return EagerAnnotationHandler.checkAnnotation(
- _compiler, element, const JsInteropAnnotationHandler());
- }
-
- if (checkJsInteropAnnotation(library)) {
- _nativeBasicDataBuilder.markAsJsInteropLibrary(library);
- }
- library.forEachLocalMember((Element element) {
- if (element.isClass) {
- ClassElement cls = element;
- if (checkJsInteropAnnotation(element)) {
- _nativeBasicDataBuilder.markAsJsInteropClass(cls);
- }
- }
- });
- }
-
- void processJsInteropAnnotations(
- NativeBasicData nativeBasicData, NativeDataBuilder nativeDataBuilder) {
- if (_commonElements.jsAnnotationClass == null) return;
-
- ClassElement cls = _commonElements.jsAnnotationClass;
- FieldElement nameField = cls.lookupMember('name');
-
- /// Resolves the metadata of [element] and returns the name of the `JS(...)`
- /// annotation for js interop, if found.
- String processJsInteropAnnotation(Element element) {
- for (MetadataAnnotation annotation in element.implementation.metadata) {
- // TODO(johnniwinther): Avoid processing unresolved elements.
- if (annotation.constant == null) continue;
- ConstantValue constant =
- _compiler.constants.getConstantValue(annotation.constant);
- if (constant == null || constant is! ConstructedConstantValue) continue;
- ConstructedConstantValue constructedConstant = constant;
- if (constructedConstant.type.element ==
- _commonElements.jsAnnotationClass) {
- ConstantValue value = constructedConstant.fields[nameField];
- String name;
- if (value.isString) {
- StringConstantValue stringValue = value;
- name = stringValue.stringValue;
- } else {
- // TODO(jacobr): report a warning if the value is not a String.
- name = '';
- }
- return name;
- }
- }
- return null;
- }
-
- void checkFunctionParameters(MethodElement fn) {
- if (fn.hasFunctionSignature &&
- fn.functionSignature.optionalParametersAreNamed) {
- _compiler.reporter.reportErrorMessage(
- fn,
- MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
- {'method': fn.name});
- }
- }
-
- bool hasAnonymousAnnotation(Element element) {
- if (_commonElements.jsAnonymousClass == null) return false;
- return element.metadata.any((MetadataAnnotation annotation) {
- ConstantValue constant =
- _compiler.constants.getConstantValue(annotation.constant);
- if (constant == null || constant is! ConstructedConstantValue)
- return false;
- ConstructedConstantValue constructedConstant = constant;
- return constructedConstant.type.element ==
- _commonElements.jsAnonymousClass;
- });
- }
-
- void processJsInteropAnnotationsInLibrary(LibraryElement library) {
- String libraryName = processJsInteropAnnotation(library);
- if (libraryName != null) {
- nativeDataBuilder.setJsInteropLibraryName(library, libraryName);
- }
- library.implementation.forEachLocalMember((Element element) {
- if (element is MemberElement) {
- String memberName = processJsInteropAnnotation(element);
- if (memberName != null) {
- nativeDataBuilder.setJsInteropMemberName(element, memberName);
- if (element is MethodElement) {
- checkFunctionParameters(element);
- }
- }
- }
-
- if (!element.isClass) return;
-
- ClassElement classElement = element;
- String className = processJsInteropAnnotation(classElement);
- if (className != null) {
- nativeDataBuilder.setJsInteropClassName(classElement, className);
- }
- if (!nativeBasicData.isJsInteropClass(classElement)) return;
-
- bool isAnonymous = hasAnonymousAnnotation(classElement);
- if (isAnonymous) {
- nativeDataBuilder.markJsInteropClassAsAnonymous(classElement);
- }
-
- // Skip classes that are completely unreachable. This should only happen
- // when all of jsinterop types are unreachable from main.
- if (!_compiler.resolutionWorldBuilder.isImplemented(classElement)) {
- return;
- }
-
- if (!classElement
- .implementsInterface(_commonElements.jsJavaScriptObjectClass)) {
- _compiler.reporter.reportErrorMessage(classElement,
- MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, {
- 'cls': classElement.name,
- 'superclass': classElement.superclass.name
- });
- }
-
- classElement.forEachMember((ClassElement classElement, _member) {
- MemberElement member = _member;
- String memberName = processJsInteropAnnotation(member);
- if (memberName != null) {
- nativeDataBuilder.setJsInteropMemberName(member, memberName);
- }
-
- if (!member.isSynthesized &&
- nativeBasicData.isJsInteropClass(classElement) &&
- member is MethodElement) {
- MethodElement fn = member;
- if (!fn.isExternal &&
- !fn.isAbstract &&
- !fn.isConstructor &&
- !fn.isStatic) {
- _compiler.reporter.reportErrorMessage(
- fn,
- MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
- {'cls': classElement.name, 'member': member.name});
- }
-
- if (fn.isFactoryConstructor && isAnonymous) {
- if (fn.functionSignature.requiredParameterCount > 0 ||
- fn.functionSignature.hasOptionalParameters &&
- !fn.functionSignature.optionalParametersAreNamed) {
- _compiler.reporter.reportErrorMessage(
- fn,
- MessageKind
- .JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
- {'cls': classElement.name});
- }
- } else {
- checkFunctionParameters(fn);
- }
- }
- });
- });
- }
-
- _compiler.libraryLoader.libraries
- .forEach((LibraryEntity l) => processJsInteropAnnotationsInLibrary(l));
- }
-}
-
-/// Builder that creates work item necessary for the resolution of a
-/// [MemberElement].
-class ResolutionWorkItemBuilder extends WorkItemBuilder {
- final Resolution _resolution;
-
- ResolutionWorkItemBuilder(this._resolution);
-
- @override
- WorkItem createWorkItem(MemberElement element) {
- assert(element.isDeclaration, failedAt(element));
- if (element.isMalformed) return null;
-
- assert(element is AnalyzableElement,
- failedAt(element, 'Element $element is not analyzable.'));
- return _resolution.createWorkItem(element);
- }
-}
-
-class ResolutionMirrorsData extends MirrorsDataImpl {
- ResolutionMirrorsData(Compiler compiler,
- ElementEnvironment elementEnvironment, CommonElements commonElements)
- : super(compiler, elementEnvironment, commonElements);
-
- @override
- bool isClassInjected(covariant ClassElement cls) => cls.isInjected;
-
- @override
- bool isClassResolved(covariant ClassElement cls) => cls.isResolved;
-
- @override
- void forEachConstructor(
- covariant ClassElement cls, void f(ConstructorEntity constructor)) {
- cls.constructors.forEach((Element _constructor) {
- ConstructorElement constructor = _constructor;
- f(constructor);
- });
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/scope.dart b/pkg/compiler/lib/src/resolution/scope.dart
deleted file mode 100644
index a047968..0000000
--- a/pkg/compiler/lib/src/resolution/scope.dart
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.scope;
-
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-
-abstract class Scope {
- /**
- * If an [Element] named `element.name` has already been added to this
- * [Scope], return that element and make no changes. If no such element has
- * been added, add the given [element] to this [Scope], and return [element].
- * Note that this operation is only allowed on mutable scopes such as
- * [MethodScope] and [BlockScope].
- */
- Element add(Element element);
-
- /**
- * Looks up the [Element] for [name] in this scope.
- */
- Element lookup(String name);
-
- static Scope buildEnclosingScope(Element element) {
- return element.enclosingElement != null
- ? element.enclosingElement.buildScope()
- : element.buildScope();
- }
-}
-
-abstract class NestedScope extends Scope {
- final Scope parent;
-
- NestedScope(this.parent);
-
- Element lookup(String name) {
- Element result = localLookup(name);
- if (result != null) return result;
- return parent.lookup(name);
- }
-
- Element localLookup(String name);
-}
-
-class VariableDefinitionScope extends NestedScope {
- final String variableName;
- bool variableReferencedInInitializer = false;
-
- VariableDefinitionScope(Scope parent, this.variableName) : super(parent);
-
- Element localLookup(String name) {
- if (name == variableName) {
- variableReferencedInInitializer = true;
- }
- return null;
- }
-
- Element add(Element newElement) {
- throw "Cannot add element to VariableDefinitionScope";
- }
-}
-
-/// [TypeVariablesScope] defines the outer scope in a context where some type
-/// variables are declared and the entities in the enclosing scope are
-/// available, but where locally declared and inherited members are not
-/// available.
-abstract class TypeVariablesScope extends NestedScope {
- List<ResolutionDartType> get typeVariables;
-
- TypeVariablesScope(Scope parent) : super(parent) {
- assert(parent != null);
- }
-
- Element add(Element newElement) {
- throw "Cannot add element to TypeDeclarationScope";
- }
-
- Element lookupTypeVariable(String name) {
- for (ResolutionTypeVariableType type in typeVariables) {
- if (type.name == name) {
- return type.element;
- }
- }
- return null;
- }
-
- Element localLookup(String name) => lookupTypeVariable(name);
-}
-
-/**
- * [TypeDeclarationScope] defines the outer scope of a type declaration in
- * which the declared type variables and the entities in the enclosing scope are
- * available but where declared and inherited members are not available. This
- * scope is used for class declarations during resolution of the class hierarchy
- * and when resolving typedef signatures. In other cases [ClassScope] is used.
- */
-class TypeDeclarationScope extends TypeVariablesScope {
- final GenericElement element;
-
- @override
- List<ResolutionDartType> get typeVariables => element.typeVariables;
-
- TypeDeclarationScope(Scope parent, this.element) : super(parent);
-
- String toString() => 'TypeDeclarationScope($element)';
-}
-
-abstract class MutableScope extends NestedScope {
- final Map<String, Element> elements;
-
- MutableScope(Scope parent)
- : this.elements = new Map<String, Element>(),
- super(parent) {
- assert(parent != null);
- }
-
- Element add(Element newElement) {
- if (elements.containsKey(newElement.name)) {
- return elements[newElement.name];
- }
- elements[newElement.name] = newElement;
- return newElement;
- }
-
- Element localLookup(String name) => elements[name];
-}
-
-/**
- * [ExtensionScope] enables the creation of an extended version of an
- * existing [NestedScope], received during construction and stored in
- * [extendee]. An [ExtensionScope] will treat an added `element` as conflicting
- * if an element `e` where `e.name == element.name` exists among the elements
- * added to this [ExtensionScope], or among the ones added to [extendee]
- * (according to `extendee.localLookup`). In this sense, it represents the
- * union of the bindings stored locally in [elements] and the bindings in
- * [extendee], not a new scope which is nested inside [extendee].
- *
- * Note that it is required that no bindings are added to [extendee] during the
- * lifetime of this [ExtensionScope]: That would enable duplicates to be
- * introduced into the extended scope consisting of [this] plus [extendee]
- * without detection.
- */
-class ExtensionScope extends Scope {
- final NestedScope extendee;
- final Map<String, Element> elements;
-
- ExtensionScope(this.extendee) : this.elements = new Map<String, Element>() {
- assert(extendee != null);
- }
-
- Element lookup(String name) {
- Element result = elements[name];
- if (result != null) return result;
- return extendee.lookup(name);
- }
-
- Element add(Element newElement) {
- if (elements.containsKey(newElement.name)) {
- return elements[newElement.name];
- }
- Element existing = extendee.localLookup(newElement.name);
- if (existing != null) return existing;
- elements[newElement.name] = newElement;
- return newElement;
- }
-}
-
-class MethodScope extends MutableScope {
- final Element element;
-
- MethodScope(Scope parent, this.element) : super(parent);
-
- String toString() => 'MethodScope($element${elements.keys.toList()})';
-}
-
-class BlockScope extends MutableScope {
- BlockScope(Scope parent) : super(parent);
-
- String toString() => 'BlockScope(${elements.keys.toList()})';
-}
-
-/**
- * [ClassScope] defines the inner scope of a class/interface declaration in
- * which declared members, declared type variables, entities in the enclosing
- * scope and inherited members are available, in the given order.
- */
-class ClassScope extends TypeDeclarationScope {
- ClassElement get element => super.element;
-
- ClassScope(Scope parentScope, ClassElement element)
- : super(parentScope, element) {
- assert(parent != null);
- }
-
- Element localLookup(String name) {
- Element result = element.lookupLocalMember(name);
- if (result != null) return result;
- return super.localLookup(name);
- }
-
- Element lookup(String name) {
- Element result = localLookup(name);
- if (result != null) return result;
- result = parent.lookup(name);
- if (result != null) return result;
- return element.lookupSuperMember(name);
- }
-
- Element add(Element newElement) {
- throw "Cannot add an element in a class scope";
- }
-
- String toString() => 'ClassScope($element)';
-}
-
-class LibraryScope implements Scope {
- final LibraryElement library;
-
- LibraryScope(LibraryElement this.library);
-
- Element localLookup(String name) => library.find(name);
- Element lookup(String name) => localLookup(name);
-
- Element add(Element newElement) {
- throw "Cannot add an element to a library scope";
- }
-
- String toString() => 'LibraryScope($library)';
-}
diff --git a/pkg/compiler/lib/src/resolution/secret_tree_element.dart b/pkg/compiler/lib/src/resolution/secret_tree_element.dart
deleted file mode 100644
index 9b118a6..0000000
--- a/pkg/compiler/lib/src/resolution/secret_tree_element.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.secret_tree_element;
-
-// The code in this library was moved to ../tree/nodes.dart to satisfy extra
-// restrictions on overriding private members.
-//
-// [See issue for more details](https://github.com/dart-lang/sdk/issues/28809).
-
-export '../tree/nodes.dart' show getTreeElement, setTreeElement;
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
deleted file mode 100644
index f917349..0000000
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart
+++ /dev/null
@@ -1,4725 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.semantics_visitor;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart';
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import 'send_resolver.dart';
-import 'send_structure.dart';
-import 'tree_elements.dart';
-
-part 'semantic_visitor_mixins.dart';
-
-/// Mixin that couples a [SendResolverMixin] to a [SemanticSendVisitor] in a
-/// [Visitor].
-abstract class SemanticSendResolvedMixin<R, A> implements Visitor<R> {
- TreeElements get elements;
-
- internalError(Spannable spannable, String message);
-
- SemanticSendVisitor<R, A> get sendVisitor;
-
- @override
- R visitIdentifier(Identifier node) {
- // TODO(johnniwinther): Support argument.
- A arg = null;
- if (node.isThis()) {
- // TODO(johnniwinther): Parse `this` as a [Send] whose selector is `this`
- // to normalize with `this(...)`.
- return sendVisitor.visitThisGet(node, arg);
- }
- return null;
- }
-
- @override
- R visitSend(Send node) {
- // TODO(johnniwinther): Support argument.
- A arg = null;
-
- SendStructure structure = elements.getSendStructure(node);
- if (structure == null) {
- return internalError(node, 'No structure for $node');
- } else {
- return structure.dispatch(sendVisitor, node, arg);
- }
- }
-
- @override
- R visitSendSet(SendSet node) {
- return visitSend(node);
- }
-
- @override
- R visitNewExpression(NewExpression node) {
- // TODO(johnniwinther): Support argument.
- A arg = null;
-
- NewStructure structure = elements.getNewStructure(node);
- if (structure == null) {
- return internalError(node, 'No structure for $node');
- } else {
- return structure.dispatch(sendVisitor, node, arg);
- }
- }
-}
-
-/// Mixin that couples a [DeclarationResolverMixin] to a
-/// [SemanticDeclarationVisitor] in a [Visitor].
-abstract class SemanticDeclarationResolvedMixin<R, A>
- implements Visitor<R>, DeclarationResolverMixin {
- SemanticDeclarationVisitor<R, A> get declVisitor;
-
- @override
- R visitFunctionExpression(FunctionExpression node) {
- // TODO(johnniwinther): Support argument.
- A arg = null;
-
- DeclStructure structure = computeFunctionStructure(node);
- if (structure == null) {
- return internalError(node, 'No structure for $node');
- } else {
- return structure.dispatch(declVisitor, node, arg);
- }
- }
-
- visitInitializers(FunctionExpression function, A arg) {
- InitializersStructure initializers = computeInitializersStructure(function);
- for (InitializerStructure structure in initializers.initializers) {
- structure.dispatch(declVisitor, arg);
- }
- }
-
- visitParameters(NodeList parameters, A arg) {
- List<ParameterStructure> structures =
- computeParameterStructures(parameters);
- for (ParameterStructure structure in structures) {
- structure.dispatch(declVisitor, arg);
- }
- }
-
- @override
- R visitVariableDefinitions(VariableDefinitions definitions) {
- // TODO(johnniwinther): Support argument.
- A arg = null;
-
- computeVariableStructures(definitions,
- (Node node, VariableStructure structure) {
- if (structure == null) {
- return internalError(node, 'No structure for $node');
- } else {
- return structure.dispatch(declVisitor, node, arg);
- }
- });
- return null;
- }
-}
-
-abstract class SemanticVisitor<R, A> extends Visitor<R>
- with
- SemanticSendResolvedMixin<R, A>,
- SemanticDeclarationResolvedMixin<R, A>,
- DeclarationResolverMixin {
- TreeElements elements;
-
- SemanticVisitor(this.elements);
-}
-
-// TODO(johnniwinther): Add visits for [visitLocalConstantGet],
-// [visitLocalConstantInvoke], [visitStaticConstantGet], etc.
-abstract class SemanticSendVisitor<R, A> {
- R apply(Node node, A arg);
-
- /// Read of the [parameter].
- ///
- /// For instance:
- ///
- /// m(parameter) => parameter;
- ///
- R visitParameterGet(Send node, ParameterElement parameter, A arg);
-
- /// Assignment of [rhs] to the [parameter].
- ///
- /// For instance:
- ///
- /// m(parameter) {
- /// parameter = rhs;
- /// }
- ///
- R visitParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg);
-
- /// Assignment of [rhs] to the final [parameter].
- ///
- /// For instance:
- ///
- /// m(final parameter) {
- /// parameter = rhs;
- /// }
- ///
- R visitFinalParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg);
-
- /// Invocation of the [parameter] with [arguments].
- ///
- /// For instance:
- ///
- /// m(parameter) {
- /// parameter(null, 42);
- /// }
- ///
- R visitParameterInvoke(Send node, ParameterElement parameter,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Read of the local [variable].
- ///
- /// For instance:
- ///
- /// m() {
- /// var variable;
- /// return variable;
- /// }
- ///
- R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg);
-
- /// Assignment of [rhs] to the local [variable].
- ///
- /// For instance:
- ///
- /// m() {
- /// var variable;
- /// variable = rhs;
- /// }
- ///
- R visitLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg);
-
- /// Assignment of [rhs] to the final local [variable].
- ///
- /// For instance:
- ///
- /// m() {
- /// final variable = null;
- /// variable = rhs;
- /// }
- ///
- R visitFinalLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg);
-
- /// Invocation of the local variable [variable] with [arguments].
- ///
- /// For instance:
- ///
- /// m() {
- /// var variable;
- /// variable(null, 42);
- /// }
- ///
- R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Closurization of the local [function].
- ///
- /// For instance:
- ///
- /// m() {
- /// o(a, b) {}
- /// return o;
- /// }
- ///
- R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg);
-
- /// Assignment of [rhs] to the local [function].
- ///
- /// For instance:
- ///
- /// m() {
- /// o(a, b) {}
- /// o = rhs;
- /// }
- ///
- R visitLocalFunctionSet(
- SendSet node, LocalFunctionElement function, Node rhs, A arg);
-
- /// Invocation of the local [function] with [arguments].
- ///
- /// For instance:
- ///
- /// m() {
- /// o(a, b) {}
- /// return o(null, 42);
- /// }
- ///
- R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Invocation of the local [function] with incompatible [arguments].
- ///
- /// For instance:
- ///
- /// m() {
- /// o(a) {}
- /// return o(null, 42);
- /// }
- ///
- R visitLocalFunctionIncompatibleInvoke(
- Send node,
- LocalFunctionElement function,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Getter call on [receiver] of the property defined by [selector].
- ///
- /// For instance:
- ///
- /// m(receiver) => receiver.foo;
- ///
- R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg);
-
- /// Conditional (if not null) getter call on [receiver] of the property
- /// defined by [selector].
- ///
- /// For instance:
- ///
- /// m(receiver) => receiver?.foo;
- ///
- R visitIfNotNullDynamicPropertyGet(
- Send node, Node receiver, Name name, A arg);
-
- /// Setter call on [receiver] with argument [rhs] of the property defined by
- /// [selector].
- ///
- /// For instance:
- ///
- /// m(receiver) {
- /// receiver.foo = rhs;
- /// }
- ///
- R visitDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg);
-
- /// Conditional (if not null) setter call on [receiver] with argument [rhs] of
- /// the property defined by [selector].
- ///
- /// For instance:
- ///
- /// m(receiver) {
- /// receiver?.foo = rhs;
- /// }
- ///
- R visitIfNotNullDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg);
-
- /// Invocation of the property defined by [selector] on [receiver] with
- /// [arguments].
- ///
- /// For instance:
- ///
- /// m(receiver) {
- /// receiver.foo(null, 42);
- /// }
- ///
- R visitDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg);
-
- /// Conditional invocation of the property defined by [selector] on [receiver]
- /// with [arguments], if [receiver] is not null.
- ///
- /// For instance:
- ///
- /// m(receiver) {
- /// receiver?.foo(null, 42);
- /// }
- ///
- R visitIfNotNullDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg);
-
- /// Getter call on `this` of the property defined by [selector].
- ///
- /// For instance:
- ///
- /// class C {
- /// m() => this.foo;
- /// }
- ///
- /// or
- ///
- /// class C {
- /// m() => foo;
- /// }
- ///
- R visitThisPropertyGet(Send node, Name name, A arg);
-
- /// Setter call on `this` with argument [rhs] of the property defined by
- /// [selector].
- ///
- /// For instance:
- ///
- /// class C {
- /// m() { this.foo = rhs; }
- /// }
- ///
- /// or
- ///
- /// class C {
- /// m() { foo = rhs; }
- /// }
- ///
- R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg);
-
- /// Invocation of the property defined by [selector] on `this` with
- /// [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// m() { this.foo(null, 42); }
- /// }
- ///
- /// or
- ///
- /// class C {
- /// m() { foo(null, 42); }
- /// }
- ///
- ///
- R visitThisPropertyInvoke(
- Send node, NodeList arguments, Selector selector, A arg);
-
- /// Read of `this`.
- ///
- /// For instance:
- ///
- /// class C {
- /// m() => this;
- /// }
- ///
- R visitThisGet(Identifier node, A arg);
-
- /// Invocation of `this` with [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// m() => this(null, 42);
- /// }
- ///
- R visitThisInvoke(
- Send node, NodeList arguments, CallStructure callStructure, A arg);
-
- /// Read of the super [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// var foo;
- /// }
- /// class C extends B {
- /// m() => super.foo;
- /// }
- ///
- R visitSuperFieldGet(Send node, FieldElement field, A arg);
-
- /// Assignment of [rhs] to the super [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// var foo;
- /// }
- /// class C extends B {
- /// m() { super.foo = rhs; }
- /// }
- ///
- R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
- /// Assignment of [rhs] to the final static [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// final foo = null;
- /// }
- /// class C extends B {
- /// m() { super.foo = rhs; }
- /// }
- ///
- R visitFinalSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
- /// Invocation of the super [field] with [arguments].
- ///
- /// For instance:
- ///
- /// class B {
- /// var foo;
- /// }
- /// class C extends B {
- /// m() { super.foo(null, 42); }
- /// }
- ///
- R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Closurization of the super [method].
- ///
- /// For instance:
- ///
- /// class B {
- /// foo(a, b) {}
- /// }
- /// class C extends B {
- /// m() => super.foo;
- /// }
- ///
- R visitSuperMethodGet(Send node, MethodElement method, A arg);
-
- /// Invocation of the super [method] with [arguments].
- ///
- /// For instance:
- ///
- /// class B {
- /// foo(a, b) {}
- /// }
- /// class C extends B {
- /// m() { super.foo(null, 42); }
- /// }
- ///
- R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Invocation of the super [method] with incompatible [arguments].
- ///
- /// For instance:
- ///
- /// class B {
- /// foo(a, b) {}
- /// }
- /// class C extends B {
- /// m() { super.foo(null); } // One argument missing.
- /// }
- ///
- R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Assignment of [rhs] to the super [method].
- ///
- /// For instance:
- ///
- /// class B {
- /// foo(a, b) {}
- /// }
- /// class C extends B {
- /// m() { super.foo = rhs; }
- /// }
- ///
- R visitSuperMethodSet(SendSet node, MethodElement method, Node rhs, A arg);
-
- /// Getter call to the super [getter].
- ///
- /// For instance:
- ///
- /// class B {
- /// get foo => null;
- /// }
- /// class C extends B {
- /// m() => super.foo;
- /// }
- ///
- R visitSuperGetterGet(Send node, GetterElement getter, A arg);
-
- /// Getter call the super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// set foo(_) {}
- /// }
- /// class C extends B {
- /// m() => super.foo;
- /// }
- ///
- R visitSuperSetterGet(Send node, SetterElement setter, A arg);
-
- /// Setter call to the super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// set foo(_) {}
- /// }
- /// class C extends B {
- /// m() { super.foo = rhs; }
- /// }
- ///
- R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
- /// Assignment of [rhs] to the super [getter].
- ///
- /// For instance:
- ///
- /// class B {
- /// get foo => null;
- /// }
- /// class C extends B {
- /// m() { super.foo = rhs; }
- /// }
- ///
- R visitSuperGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
- /// Invocation of the super [getter] with [arguments].
- ///
- /// For instance:
- ///
- /// class B {
- /// get foo => null;
- /// }
- /// class C extends B {
- /// m() { super.foo(null, 42; }
- /// }
- ///
- R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Invocation of the super [setter] with [arguments].
- ///
- /// For instance:
- ///
- /// class B {
- /// set foo(_) {}
- /// }
- /// class C extends B {
- /// m() { super.foo(null, 42; }
- /// }
- ///
- R visitSuperSetterInvoke(Send node, SetterElement setter, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Invocation of a [expression] with [arguments].
- ///
- /// For instance:
- ///
- /// m() => (a, b){}(null, 42);
- ///
- R visitExpressionInvoke(Send node, Node expression, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Read of the static [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static var foo;
- /// }
- /// m() => C.foo;
- ///
- R visitStaticFieldGet(Send node, FieldElement field, A arg);
-
- /// Assignment of [rhs] to the static [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static var foo;
- /// }
- /// m() { C.foo = rhs; }
- ///
- R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
- /// Assignment of [rhs] to the final static [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static final foo;
- /// }
- /// m() { C.foo = rhs; }
- ///
- R visitFinalStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
- /// Invocation of the static [field] with [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// static var foo;
- /// }
- /// m() { C.foo(null, 42); }
- ///
- R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Closurization of the static [function].
- ///
- /// For instance:
- ///
- /// class C {
- /// static foo(a, b) {}
- /// }
- /// m() => C.foo;
- ///
- R visitStaticFunctionGet(Send node, MethodElement function, A arg);
-
- /// Invocation of the static [function] with [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// static foo(a, b) {}
- /// }
- /// m() { C.foo(null, 42); }
- ///
- R visitStaticFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Invocation of the static [function] with incompatible [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// static foo(a, b) {}
- /// }
- /// m() { C.foo(null); }
- ///
- R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Assignment of [rhs] to the static [function].
- ///
- /// For instance:
- ///
- /// class C {
- /// static foo(a, b) {}
- /// }
- /// m() { C.foo = rhs; }
- ///
- R visitStaticFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg);
-
- /// Getter call to the static [getter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static get foo => null;
- /// }
- /// m() => C.foo;
- ///
- R visitStaticGetterGet(Send node, GetterElement getter, A arg);
-
- /// Getter call the static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static set foo(_) {}
- /// }
- /// m() => C.foo;
- ///
- R visitStaticSetterGet(Send node, SetterElement setter, A arg);
-
- /// Setter call to the static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static set foo(_) {}
- /// }
- /// m() { C.foo = rhs; }
- ///
- R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
- /// Assignment of [rhs] to the static [getter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static get foo => null;
- /// }
- /// m() { C.foo = rhs; }
- ///
- R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
- /// Invocation of the static [getter] with [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// static get foo => null;
- /// }
- /// m() { C.foo(null, 42; }
- ///
- R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Invocation of the static [setter] with [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// static set foo(_) {}
- /// }
- /// m() { C.foo(null, 42; }
- ///
- R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Read of the top level [field].
- ///
- /// For instance:
- ///
- /// var foo;
- /// m() => foo;
- ///
- R visitTopLevelFieldGet(Send node, FieldElement field, A arg);
-
- /// Assignment of [rhs] to the top level [field].
- ///
- /// For instance:
- ///
- /// var foo;
- /// m() { foo = rhs; }
- ///
- R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
- /// Assignment of [rhs] to the final top level [field].
- ///
- /// For instance:
- ///
- /// final foo = null;
- /// m() { foo = rhs; }
- ///
- R visitFinalTopLevelFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg);
-
- /// Invocation of the top level [field] with [arguments].
- ///
- /// For instance:
- ///
- /// var foo;
- /// m() { foo(null, 42); }
- ///
- R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg);
-
- /// Closurization of the top level [function].
- ///
- /// For instance:
- ///
- /// foo(a, b) {};
- /// m() => foo;
- ///
- R visitTopLevelFunctionGet(Send node, MethodElement function, A arg);
-
- /// Invocation of the top level [function] with [arguments].
- ///
- /// For instance:
- ///
- /// foo(a, b) {};
- /// m() { foo(null, 42); }
- ///
- R visitTopLevelFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Invocation of the top level [function] with incompatible [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// static foo(a, b) {}
- /// }
- /// m() { C.foo(null); }
- ///
- R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Assignment of [rhs] to the top level [function].
- ///
- /// For instance:
- ///
- /// foo(a, b) {};
- /// m() { foo = rhs; }
- ///
- R visitTopLevelFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg);
-
- /// Getter call to the top level [getter].
- ///
- /// For instance:
- ///
- /// get foo => null;
- /// m() => foo;
- ///
- R visitTopLevelGetterGet(Send node, GetterElement getter, A arg);
-
- /// Getter call the top level [setter].
- ///
- /// For instance:
- ///
- /// set foo(_) {}
- /// m() => foo;
- ///
- R visitTopLevelSetterGet(Send node, SetterElement setter, A arg);
-
- /// Setter call to the top level [setter].
- ///
- /// For instance:
- ///
- /// set foo(_) {}
- /// m() { foo = rhs; }
- ///
- R visitTopLevelSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
- /// Assignment of [rhs] to the top level [getter].
- ///
- /// For instance:
- ///
- /// get foo => null;
- /// m() { foo = rhs; }
- ///
- R visitTopLevelGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
- /// Invocation of the top level [getter] with [arguments].
- ///
- /// For instance:
- ///
- /// get foo => null;
- /// m() { foo(null, 42); }
- ///
- R visitTopLevelGetterInvoke(Send node, GetterElement getter,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Invocation of the top level [setter] with [arguments].
- ///
- /// For instance:
- ///
- /// set foo(_) {};
- /// m() { foo(null, 42); }
- ///
- R visitTopLevelSetterInvoke(Send node, SetterElement setter,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Read of the type literal for class [element].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() => C;
- ///
- R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg);
-
- /// Invocation of the type literal for class [element] with [arguments].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() => C(null, 42);
- ///
- R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Assignment of [rhs] to the type literal for class [element].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() { C = rhs; }
- ///
- R visitClassTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg);
-
- /// Read of the type literal for typedef [element].
- ///
- /// For instance:
- ///
- /// typedef F();
- /// m() => F;
- ///
- R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg);
-
- /// Invocation of the type literal for typedef [element] with [arguments].
- ///
- /// For instance:
- ///
- /// typedef F();
- /// m() => F(null, 42);
- ///
- R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Assignment of [rhs] to the type literal for typedef [element].
- ///
- /// For instance:
- ///
- /// typedef F();
- /// m() { F = rhs; }
- ///
- R visitTypedefTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg);
-
- /// Read of the type literal for type variable [element].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// m() => T;
- /// }
- ///
- R visitTypeVariableTypeLiteralGet(
- Send node, TypeVariableElement element, A arg);
-
- /// Invocation of the type literal for type variable [element] with
- /// [arguments].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// m() { T(null, 42); }
- /// }
- ///
- R visitTypeVariableTypeLiteralInvoke(Send node, TypeVariableElement element,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Assignment of [rhs] to the type literal for type variable [element].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// m() { T = rhs; }
- /// }
- ///
- R visitTypeVariableTypeLiteralSet(
- SendSet node, TypeVariableElement element, Node rhs, A arg);
-
- /// Read of the type literal for `dynamic`.
- ///
- /// For instance:
- ///
- /// m() => dynamic;
- ///
- R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg);
-
- /// Invocation of the type literal for `dynamic` with [arguments].
- ///
- /// For instance:
- ///
- /// m() { dynamic(null, 42); }
- ///
- R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Assignment of [rhs] to the type literal for `dynamic`.
- ///
- /// For instance:
- ///
- /// m() { dynamic = rhs; }
- ///
- R visitDynamicTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg);
-
- /// Binary expression `left operator right` where [operator] is a user
- /// definable operator. Binary expressions using operator `==` are handled
- /// by [visitEquals] and index operations `a[b]` are handled by [visitIndex].
- ///
- /// For instance:
- ///
- /// add(a, b) => a + b;
- /// sub(a, b) => a - b;
- /// mul(a, b) => a * b;
- ///
- R visitBinary(
- Send node, Node left, BinaryOperator operator, Node right, A arg);
-
- /// Binary expression `super operator argument` where [operator] is a user
- /// definable operator implemented on a superclass by [function]. Binary
- /// expressions using operator `==` are handled by [visitSuperEquals].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator +(_) => null;
- /// }
- /// class C extends B {
- /// m(a) => super + a;
- /// }
- ///
- R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
- Node argument, A arg);
-
- /// Binary operation on the unresolved super [element].
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m() => super + 42;
- /// }
- ///
- R visitUnresolvedSuperBinary(Send node, Element element,
- BinaryOperator operator, Node argument, A arg);
-
- /// Index expression `receiver[index]`.
- ///
- /// For instance:
- ///
- /// lookup(a, b) => a[b];
- ///
- R visitIndex(Send node, Node receiver, Node index, A arg);
-
- /// Prefix operation on an index expression `operator receiver[index]` where
- /// the operation is defined by [operator].
- ///
- /// For instance:
- ///
- /// lookup(a, b) => --a[b];
- ///
- R visitIndexPrefix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg);
-
- /// Postfix operation on an index expression `receiver[index] operator` where
- /// the operation is defined by [operator].
- ///
- /// For instance:
- ///
- /// lookup(a, b) => a[b]++;
- ///
- R visitIndexPostfix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg);
-
- /// Index expression `super[index]` where 'operator []' is implemented on a
- /// superclass by [function].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](_) => null;
- /// }
- /// class C extends B {
- /// m(a) => super[a];
- /// }
- ///
- R visitSuperIndex(Send node, MethodElement function, Node index, A arg);
-
- /// Index expression `super[index]` where 'operator []' is unresolved.
- ///
- /// For instance:
- ///
- /// class B {}
- /// class C extends B {
- /// m(a) => super[a];
- /// }
- ///
- R visitUnresolvedSuperIndex(Send node, Element element, Node index, A arg);
-
- /// Prefix operation on an index expression `operator super[index]` where
- /// 'operator []' is implemented on a superclass by [indexFunction] and
- /// 'operator []=' is implemented on by [indexSetFunction] and the operation
- /// is defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](_) => null;
- /// operator []=(a, b) {}
- /// }
- /// class C extends B {
- /// m(a) => --super[a];
- /// }
- ///
- R visitSuperIndexPrefix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg);
-
- /// Postfix operation on an index expression `super[index] operator` where
- /// 'operator []' is implemented on a superclass by [indexFunction] and
- /// 'operator []=' is implemented on by [indexSetFunction] and the operation
- /// is defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](_) => null;
- /// operator []=(a, b) {}
- /// }
- /// class C extends B {
- /// m(a) => super[a]++;
- /// }
- ///
- R visitSuperIndexPostfix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg);
-
- /// Prefix operation on an index expression `operator super[index]` where
- /// 'operator []' is unresolved, 'operator []=' is defined by [setter], and
- /// the operation is defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator []=(a, b) {}
- /// }
- /// class C extends B {
- /// m(a) => --super[a];
- /// }
- ///
- R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg);
-
- /// Postfix operation on an index expression `super[index] operator` where
- /// 'operator []' is unresolved, 'operator []=' is defined by [setter], and
- /// the operation is defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator []=(a, b) {}
- /// }
- /// class C extends B {
- /// m(a) => super[a]++;
- /// }
- ///
- R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg);
-
- /// Prefix operation on an index expression `operator super[index]` where
- /// 'operator []' is implemented on a superclass by [indexFunction] and
- /// 'operator []=' is unresolved and the operation is defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](_) => 42;
- /// }
- /// class C extends B {
- /// m(a) => --super[a];
- /// }
- ///
- R visitUnresolvedSuperSetterIndexPrefix(
- SendSet node,
- MethodElement indexFunction,
- Element element,
- Node index,
- IncDecOperator operator,
- A arg);
-
- /// Postfix operation on an index expression `super[index] operator` where
- /// 'operator []' is implemented on a superclass by [indexFunction] and
- /// 'operator []=' is unresolved and the operation is defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](_) => 42;
- /// }
- /// class C extends B {
- /// m(a) => super[a]++;
- /// }
- ///
- R visitUnresolvedSuperSetterIndexPostfix(
- SendSet node,
- MethodElement indexFunction,
- Element element,
- Node index,
- IncDecOperator operator,
- A arg);
-
- /// Prefix operation on an index expression `super[index] operator` where
- /// both 'operator []' and 'operator []=' are unresolved and the operation is
- /// defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](_) => 42;
- /// }
- /// class C extends B {
- /// m(a) => super[a]++;
- /// }
- ///
- R visitUnresolvedSuperIndexPrefix(
- Send node, Element element, Node index, IncDecOperator operator, A arg);
-
- /// Postfix operation on an index expression `super[index] operator` where
- /// both 'operator []' and 'operator []=' are unresolved and the operation is
- /// defined by [operator].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](_) => 42;
- /// }
- /// class C extends B {
- /// m(a) => super[a]++;
- /// }
- ///
- R visitUnresolvedSuperIndexPostfix(
- Send node, Element element, Node index, IncDecOperator operator, A arg);
-
- /// Binary expression `left == right`.
- ///
- /// For instance:
- ///
- /// neq(a, b) => a != b;
- ///
- R visitNotEquals(Send node, Node left, Node right, A arg);
-
- /// Binary expression `super != argument` where `==` is implemented on a
- /// superclass by [function].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator +(_) => null;
- /// }
- /// class C extends B {
- /// m(a) => super + a;
- /// }
- ///
- R visitSuperNotEquals(
- Send node, MethodElement function, Node argument, A arg);
-
- /// Binary expression `left == right`.
- ///
- /// For instance:
- ///
- /// eq(a, b) => a == b;
- ///
- R visitEquals(Send node, Node left, Node right, A arg);
-
- /// Binary expression `super == argument` where `==` is implemented on a
- /// superclass by [function].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator ==(_) => null;
- /// }
- /// class C extends B {
- /// m(a) => super == a;
- /// }
- ///
- R visitSuperEquals(Send node, MethodElement function, Node argument, A arg);
-
- /// Unary expression `operator expression` where [operator] is a user
- /// definable operator.
- ///
- /// For instance:
- ///
- /// neg(a, b) => -a;
- /// comp(a, b) => ~a;
- ///
- R visitUnary(Send node, UnaryOperator operator, Node expression, A arg);
-
- /// Unary expression `operator super` where [operator] is a user definable
- /// operator implemented on a superclass by [function].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator -() => null;
- /// }
- /// class C extends B {
- /// m(a) => -super;
- /// }
- ///
- R visitSuperUnary(
- Send node, UnaryOperator operator, MethodElement function, A arg);
-
- /// Unary operation on the unresolved super [element].
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m() => -super;
- /// }
- ///
- R visitUnresolvedSuperUnary(
- Send node, UnaryOperator operator, Element element, A arg);
-
- /// Unary expression `!expression`.
- ///
- /// For instance:
- ///
- /// not(a) => !a;
- ///
- R visitNot(Send node, Node expression, A arg);
-
- /// Index set expression `receiver[index] = rhs`.
- ///
- /// For instance:
- ///
- /// m(receiver, index, rhs) => receiver[index] = rhs;
- ///
- R visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, A arg);
-
- /// Index set expression `super[index] = rhs` where `operator []=` is defined
- /// on a superclass by [function].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator []=(a, b) {}
- /// }
- /// class C extends B {
- /// m(a, b) => super[a] = b;
- /// }
- ///
- R visitSuperIndexSet(
- SendSet node, FunctionElement function, Node index, Node rhs, A arg);
-
- /// Index set expression `super[index] = rhs` where `operator []=` is
- /// undefined.
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m() => super[1] = 42;
- /// }
- ///
- R visitUnresolvedSuperIndexSet(
- SendSet node, ErroneousElement element, Node index, Node rhs, A arg);
-
- /// If-null, ??, expression with operands [left] and [right].
- ///
- /// For instance:
- ///
- /// m() => left ?? right;
- ///
- R visitIfNull(Send node, Node left, Node right, A arg);
-
- /// Logical and, &&, expression with operands [left] and [right].
- ///
- /// For instance:
- ///
- /// m() => left && right;
- ///
- R visitLogicalAnd(Send node, Node left, Node right, A arg);
-
- /// Logical or, ||, expression with operands [left] and [right].
- ///
- /// For instance:
- ///
- /// m() => left || right;
- ///
- R visitLogicalOr(Send node, Node left, Node right, A arg);
-
- /// Is test of [expression] against [type].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() => expression is C;
- ///
- R visitIs(Send node, Node expression, ResolutionDartType type, A arg);
-
- /// Is not test of [expression] against [type].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() => expression is! C;
- ///
- R visitIsNot(Send node, Node expression, ResolutionDartType type, A arg);
-
- /// As cast of [expression] to [type].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() => expression as C;
- ///
- R visitAs(Send node, Node expression, ResolutionDartType type, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] of the property on
- /// [receiver] whose getter and setter are defined by [getterSelector] and
- /// [setterSelector], respectively.
- ///
- /// For instance:
- ///
- /// m(receiver, rhs) => receiver.foo += rhs;
- ///
- R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] of the property on
- /// a possibly null [receiver] whose getter and setter are defined by
- /// [getterSelector] and [setterSelector], respectively.
- ///
- /// For instance:
- ///
- /// m(receiver, rhs) => receiver?.foo += rhs;
- ///
- R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] of the property on
- /// `this` whose getter and setter are defined by [getterSelector] and
- /// [setterSelector], respectively.
- ///
- /// For instance:
- ///
- /// class C {
- /// m(rhs) => this.foo += rhs;
- /// }
- ///
- /// or
- ///
- /// class C {
- /// m(rhs) => foo += rhs;
- /// }
- ///
- R visitThisPropertyCompound(
- Send node, Name name, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a [parameter].
- ///
- /// For instance:
- ///
- /// m(parameter, rhs) => parameter += rhs;
- ///
- R visitParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a final
- /// [parameter].
- ///
- /// For instance:
- ///
- /// m(final parameter, rhs) => parameter += rhs;
- ///
- R visitFinalParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a local
- /// [variable].
- ///
- /// For instance:
- ///
- /// m(rhs) {
- /// var variable;
- /// variable += rhs;
- /// }
- ///
- R visitLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a final local
- /// [variable].
- ///
- /// For instance:
- ///
- /// m(rhs) {
- /// final variable = 0;
- /// variable += rhs;
- /// }
- ///
- R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a local
- /// [function].
- ///
- /// For instance:
- ///
- /// m(rhs) {
- /// function() {}
- /// function += rhs;
- /// }
- ///
- R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a static
- /// [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static var field;
- /// m(rhs) => field += rhs;
- /// }
- ///
- R visitStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a final static
- /// [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static final field = 0;
- /// m(rhs) => field += rhs;
- /// }
- ///
- R visitFinalStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// static [getter] and writing to a static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static get o => 0;
- /// static set o(_) {}
- /// m(rhs) => o += rhs;
- /// }
- ///
- R visitStaticGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// static [method], that is, closurizing [method], and writing to a static
- /// [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static o() {}
- /// static set o(_) {}
- /// m(rhs) => o += rhs;
- /// }
- ///
- R visitStaticMethodSetterCompound(Send node, MethodElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a top level
- /// [field].
- ///
- /// For instance:
- ///
- /// var field;
- /// m(rhs) => field += rhs;
- ///
- R visitTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a final top
- /// level [field].
- ///
- /// For instance:
- ///
- /// final field = 0;
- /// m(rhs) => field += rhs;
- ///
- R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// top level [getter] and writing to a top level [setter].
- ///
- /// For instance:
- ///
- /// get o => 0;
- /// set o(_) {}
- /// m(rhs) => o += rhs;
- ///
- R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// top level [method], that is, closurizing [method], and writing to a top
- /// level [setter].
- ///
- /// For instance:
- ///
- /// o() {}
- /// set o(_) {}
- /// m(rhs) => o += rhs;
- ///
- R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// top level [method], that is, closurizing [method], and writing to an
- /// unresolved setter.
- ///
- /// For instance:
- ///
- /// o() {}
- /// m(rhs) => o += rhs;
- ///
- R visitTopLevelMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a super
- /// [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// var field;
- /// }
- /// class C extends B {
- /// m(rhs) => super.field += rhs;
- /// }
- ///
- R visitSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a final super
- /// [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// final field = 42;
- /// }
- /// class C extends B {
- /// m(rhs) => super.field += rhs;
- /// }
- ///
- R visitFinalSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the [name] property on
- /// [receiver]. That is, [rhs] is only evaluated and assigned, if the value
- /// of [name] on [receiver] is `null`.
- ///
- /// For instance:
- ///
- /// m(receiver, rhs) => receiver.foo ??= rhs;
- ///
- R visitDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the [name] property on
- /// [receiver] if not null. That is, [rhs] is only evaluated and assigned,
- /// if the value of [receiver] is _not_ `null` and the value of [name] on
- /// [receiver] is `null`.
- ///
- /// For instance:
- ///
- /// m(receiver, rhs) => receiver?.foo ??= rhs;
- ///
- R visitIfNotNullDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the [name] property on `this`.
- /// That is, [rhs] is only evaluated and assigned, if the value of [name] on
- /// `this` is `null`.
- ///
- /// For instance:
- ///
- /// class C {
- /// m(rhs) => this.foo ??= rhs;
- /// }
- ///
- /// or
- ///
- /// class C {
- /// m(rhs) => foo ??= rhs;
- /// }
- ///
- R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to [parameter]. That is, [rhs] is
- /// only evaluated and assigned, if the value of the [parameter] is `null`.
- ///
- /// For instance:
- ///
- /// m(parameter, rhs) => parameter ??= rhs;
- ///
- R visitParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the final [parameter]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [parameter] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// m(final parameter, rhs) => parameter ??= rhs;
- ///
- R visitFinalParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the local [variable]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [variable] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// m(rhs) {
- /// var variable;
- /// variable ??= rhs;
- /// }
- ///
- R visitLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the final local [variable]. That
- /// is, [rhs] is only evaluated and assigned, if the value of the [variable]
- /// is `null`.
- ///
- /// For instance:
- ///
- /// m(rhs) {
- /// final variable = 0;
- /// variable ??= rhs;
- /// }
- ///
- R visitFinalLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the local [function]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [function] is
- /// `null`. The behavior is thus equivalent to a closurization of [function].
- ///
- /// For instance:
- ///
- /// m(rhs) {
- /// function() {}
- /// function ??= rhs;
- /// }
- ///
- R visitLocalFunctionSetIfNull(
- Send node, LocalFunctionElement function, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the static [field]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [field] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// class C {
- /// static var field;
- /// m(rhs) => field ??= rhs;
- /// }
- ///
- R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the final static [field]. That
- /// is, [rhs] is only evaluated and assigned, if the value of the [field] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// class C {
- /// static final field = 0;
- /// m(rhs) => field ??= rhs;
- /// }
- ///
- R visitFinalStaticFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the static property defined by
- /// [getter] and [setter]. That is, [rhs] is only evaluated and assigned to
- /// the [setter], if the value of the [getter] is `null`.
- ///
- /// For instance:
- ///
- /// class C {
- /// static get o => 0;
- /// static set o(_) {}
- /// m(rhs) => o ??= rhs;
- /// }
- ///
- R visitStaticGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the static property defined by
- /// [method] and [setter]. That is, [rhs] is only evaluated and assigned to
- /// the [setter], if the value of the [method] is `null`. The behavior is thus
- /// equivalent to a closurization of [method].
- ///
- /// For instance:
- ///
- /// class C {
- /// static o() {}
- /// static set o(_) {}
- /// m(rhs) => o ??= rhs;
- /// }
- ///
- R visitStaticMethodSetterSetIfNull(
- Send node, MethodElement method, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the static [method]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [method] is
- /// `null`. The behavior is thus equivalent to a closurization of [method].
- ///
- /// For instance:
- ///
- /// o() {}
- /// m(rhs) => o ??= rhs;
- ///
- R visitStaticMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level [field]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [field] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// var field;
- /// m(rhs) => field ??= rhs;
- ///
- R visitTopLevelFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the final top level [field].
- /// That is, [rhs] is only evaluated and assigned, if the value of the [field]
- /// is `null`.
- ///
- /// For instance:
- ///
- /// final field = 0;
- /// m(rhs) => field ??= rhs;
- ///
- R visitFinalTopLevelFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level property defined
- /// by [getter] and [setter]. That is, [rhs] is only evaluated and assigned to
- /// the [setter], if the value of the [getter] is `null`.
- ///
- /// For instance:
- ///
- /// get o => 0;
- /// set o(_) {}
- /// m(rhs) => o ??= rhs;
- ///
- R visitTopLevelGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level property defined
- /// by [method] and [setter]. That is, [rhs] is only evaluated and assigned to
- /// the [setter], if the value of the [method] is `null`. The behavior is thus
- /// equivalent to a closurization of [method].
- ///
- /// For instance:
- ///
- /// o() {}
- /// set o(_) {}
- /// m(rhs) => o ??= rhs;
- ///
- R visitTopLevelMethodSetterSetIfNull(
- Send node, FunctionElement method, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level [method]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [method] is
- /// `null`. The behavior is thus equivalent to a closurization of [method].
- ///
- /// For instance:
- ///
- /// o() {}
- /// m(rhs) => o ??= rhs;
- ///
- R visitTopLevelMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the super [field]. That is,
- /// [rhs] is only evaluated and assigned, if the value of the [field] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// class B {
- /// var field;
- /// }
- /// class C extends B {
- /// m(rhs) => super.field ??= rhs;
- /// }
- ///
- R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the final super [field]. That
- /// is, [rhs] is only evaluated and assigned, if the value of the [field] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// class B {
- /// final field = 42;
- /// }
- /// class C extends B {
- /// m(rhs) => super.field ??= rhs;
- /// }
- ///
- R visitFinalSuperFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the super property defined
- /// by [readField] and [writtenField]. That is, [rhs] is only evaluated and
- /// assigned to the [writtenField], if the value of the [readField] is `null`.
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// final field;
- /// }
- /// class C extends B {
- /// m() => super.field ??= rhs;
- /// }
- ///
- R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
- FieldElement writtenField, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the super property defined
- /// by [getter] and [setter]. That is, [rhs] is only evaluated and assigned to
- /// the [setter], if the value of the [getter] is `null`.
- ///
- /// For instance:
- ///
- /// class B {
- /// get o => 0;
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o ??= rhs;
- /// }
- ///
- R visitSuperGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the super property defined
- /// by [method] and [setter]. That is, [rhs] is only evaluated and assigned to
- /// the [setter], if the value of the [method] is `null`. The behavior is thus
- /// equivalent to a closurization of [method].
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o ??= rhs;
- /// }
- ///
- R visitSuperMethodSetterSetIfNull(
- Send node, FunctionElement method, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the super [method].
- /// That is, [rhs] is only evaluated and assigned, if the value of
- /// the [method] is `null`. The behavior is thus equivalent to a closurization
- /// of [method].
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o ??= rhs;
- /// }
- ///
- R visitSuperMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the super property defined
- /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated
- /// and assigned to the [setter], if the value of the unresolved getter is
- /// `null`. The behavior is thus equivalent to a no such method error.
- ///
- /// For instance:
- ///
- /// class B {
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o ??= rhs;
- /// }
- ///
- R visitUnresolvedSuperGetterSetIfNull(
- Send node, Element element, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the super property defined
- /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated
- /// and assigned to the unresolved setter, if the value of the [getter] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// class B {
- /// get o => 42;
- /// }
- /// class C extends B {
- /// m(rhs) => super.o ??= rhs;
- /// }
- ///
- R visitUnresolvedSuperSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level property defined
- /// by [field] and [setter]. That is, [rhs] is only evaluated and assigned to
- /// the [setter], if the value of the [field] is `null`.
- ///
- /// For instance:
- ///
- /// class A {
- /// var o;
- /// }
- /// class B extends A {
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o ??= rhs;
- /// }
- ///
- R visitSuperFieldSetterSetIfNull(
- Send node, FieldElement field, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level property defined
- /// by [getter] and [field]. That is, [rhs] is only evaluated and assigned to
- /// the [field], if the value of the [getter] is `null`.
- ///
- /// For instance:
- ///
- /// class A {
- /// var o;
- /// }
- /// class B extends A {
- /// get o => 0;
- /// }
- /// class C extends B {
- /// m(rhs) => super.o ??= rhs;
- /// }
- ///
- R visitSuperGetterFieldSetIfNull(
- Send node, GetterElement getter, FieldElement field, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to an unresolved super property.
- /// That is, [rhs] is only evaluated and assigned, if the value of the
- /// unresolved property is `null`. The behavior is thus equivalent to a no
- /// such method error.
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m(rhs) => super.unresolved ??= rhs;
- /// }
- ///
- R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the static property defined
- /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated
- /// and assigned to the [setter], if the value of the unresolved
- /// getter is `null`. The behavior is thus equivalent to a no such method
- /// error.
- ///
- /// For instance:
- ///
- /// class C {
- /// set foo(_) {}
- /// }
- /// m1() => C.foo ??= 42;
- ///
- R visitUnresolvedStaticGetterSetIfNull(
- Send node, Element element, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level property defined
- /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated
- /// and assigned to the [setter], if the value of the unresolved getter is
- /// `null`. The behavior is thus equivalent to a no such method error.
- ///
- /// For instance:
- ///
- /// set foo(_) {}
- /// m1() => foo ??= 42;
- ///
- R visitUnresolvedTopLevelGetterSetIfNull(
- Send node, Element element, SetterElement setter, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the static property defined
- /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated
- /// and assigned to the unresolved setter, if the value of the [getter] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// class C {
- /// get foo => 42;
- /// }
- /// m1() => C.foo ??= 42;
- ///
- R visitUnresolvedStaticSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the top level property defined
- /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated
- /// and assigned to the unresolved setter, if the value of the [getter] is
- /// `null`.
- ///
- /// For instance:
- ///
- /// get foo => 42;
- /// m1() => foo ??= 42;
- ///
- R visitUnresolvedTopLevelSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to an unresolved property.
- /// That is, [rhs] is only evaluated and assigned, if the value of the
- /// unresolved property is `null`. The behavior is thus equivalent to a no
- /// such method error.
- ///
- /// For instance:
- ///
- /// class C {}
- /// m1() => unresolved ??= 42;
- /// m2() => C.unresolved ??= 42;
- ///
- // TODO(johnniwinther): Split the cases in which a prefix is resolved.
- R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to an invalid expression.
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m() => p ??= 42;
- ///
- R errorInvalidSetIfNull(Send node, ErroneousElement error, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the class type literal
- /// [constant]. That is, [rhs] is only evaluated and assigned, if the value
- /// is of the [constant] is `null`. The behavior is thus equivalent to a type
- /// literal access.
- ///
- /// For instance:
- ///
- /// class C {}
- /// m(rhs) => C ??= rhs;
- ///
- R visitClassTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the typedef type literal
- /// [constant]. That is, [rhs] is only evaluated and assigned, if the value
- /// is of the [constant] is `null`. The behavior is thus equivalent to a type
- /// literal access.
- ///
- /// For instance:
- ///
- /// typedef F();
- /// m(rhs) => F ??= rhs;
- ///
- R visitTypedefTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the type literal for the type
- /// variable [element]. That is, [rhs] is only evaluated and assigned, if
- /// the value is of the [element] is `null`. The behavior is thus equivalent
- /// to a type literal access.
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// m(rhs) => T ??= rhs;
- /// }
- ///
- R visitTypeVariableTypeLiteralSetIfNull(
- Send node, TypeVariableElement element, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to the dynamic type literal
- /// [constant]. That is, [rhs] is only evaluated and assigned, if the value
- /// is of the [constant] is `null`. The behavior is thus equivalent to a type
- /// literal access.
- ///
- /// For instance:
- ///
- /// m(rhs) => dynamic ??= rhs;
- ///
- R visitDynamicTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg);
-
- /// Prefix expression with [operator] on a final super [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// final field = 42;
- /// }
- /// class C extends B {
- /// m(rhs) => ++super.field;
- /// }
- ///
- R visitFinalSuperFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on an unresolved super property.
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m(rhs) => ++super.unresolved;
- /// }
- ///
- R visitUnresolvedSuperPrefix(
- SendSet node, Element element, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on an unresolved super property.
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m(rhs) => super.unresolved++;
- /// }
- ///
- R visitUnresolvedSuperPostfix(
- SendSet node, Element element, IncDecOperator operator, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on an unresolved
- /// super property.
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m(rhs) => super.unresolved += rhs;
- /// }
- ///
- R visitUnresolvedSuperCompound(
- Send node, Element element, AssignmentOperator operator, Node rhs, A arg);
-
- /// Postfix expression with [operator] on a final super [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// final field = 42;
- /// }
- /// class C extends B {
- /// m(rhs) => super.field++;
- /// }
- ///
- R visitFinalSuperFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from the
- /// super field [readField] and writing to the different super field
- /// [writtenField].
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// final field;
- /// }
- /// class C extends B {
- /// m() => super.field += rhs;
- /// }
- ///
- R visitSuperFieldFieldCompound(Send node, FieldElement readField,
- FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// super [getter] and writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// get o => 0;
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o += rhs;
- /// }
- ///
- R visitSuperGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// super [method], that is, closurizing [method], and writing to a super
- /// [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o += rhs;
- /// }
- ///
- R visitSuperMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading the
- /// closurized super [method] and trying to invoke the non-existing setter.
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o += rhs;
- /// }
- ///
- R visitSuperMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from the
- /// non-existing super getter and writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o += rhs;
- /// }
- ///
- R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// super [getter] and writing to the non-existing super setter.
- ///
- /// For instance:
- ///
- /// class B {
- /// get o => 42;
- /// }
- /// class C extends B {
- /// m(rhs) => super.o += rhs;
- /// }
- ///
- R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// super [field] and writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class A {
- /// var o;
- /// }
- /// class B extends A {
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m(rhs) => super.o += rhs;
- /// }
- ///
- R visitSuperFieldSetterCompound(Send node, FieldElement field,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] reading from a
- /// super [getter] and writing to a super [field].
- ///
- /// For instance:
- ///
- /// class A {
- /// var o;
- /// }
- /// class B extends A {
- /// get o => 0;
- /// }
- /// class C extends B {
- /// m(rhs) => super.o += rhs;
- /// }
- ///
- R visitSuperGetterFieldCompound(Send node, GetterElement getter,
- FieldElement field, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a type literal
- /// for class [element].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m(rhs) => C += rhs;
- ///
- R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a type literal
- /// for typedef [element].
- ///
- /// For instance:
- ///
- /// typedef F();
- /// m(rhs) => F += rhs;
- ///
- R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on a type literal
- /// for type variable [element].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// m(rhs) => T += rhs;
- /// }
- ///
- R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment expression of [rhs] with [operator] on the type
- /// literal for `dynamic`.
- ///
- /// For instance:
- ///
- /// m(rhs) => dynamic += rhs;
- ///
- R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound index assignment of [rhs] with [operator] to [index] on the
- /// index operators of [receiver].
- ///
- /// For instance:
- ///
- /// m(receiver, index, rhs) => receiver[index] += rhs;
- ///
- R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound index assignment of [rhs] with [operator] to [index] on the index
- /// operators of a super class defined by [getter] and [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](index) {}
- /// operator [](index, value) {}
- /// }
- /// class C extends B {
- /// m(index, rhs) => super[index] += rhs;
- /// }
- ///
- R visitSuperCompoundIndexSet(
- SendSet node,
- MethodElement getter,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg);
-
- /// Compound index assignment of [rhs] with [operator] to [index] on a super
- /// class where the index getter is undefined and the index setter is defined
- /// by [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m() => super[1] += 42;
- /// }
- ///
- R visitUnresolvedSuperGetterCompoundIndexSet(
- SendSet node,
- Element element,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg);
-
- /// Compound index assignment of [rhs] with [operator] to [index] on a super
- /// class where the index getter is defined by [getter] but the index setter
- /// is undefined.
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](index) => 42;
- /// }
- /// class C extends B {
- /// m() => super[1] += 42;
- /// }
- ///
- R visitUnresolvedSuperSetterCompoundIndexSet(
- SendSet node,
- MethodElement getter,
- Element element,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg);
-
- /// Compound index assignment of [rhs] with [operator] to [index] on a super
- /// class where the index getter and setter are undefined.
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m() => super[1] += 42;
- /// }
- ///
- R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
- Node index, AssignmentOperator operator, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to [index] on the index operators
- /// of [receiver].
- ///
- /// For instance:
- ///
- /// m(receiver, index, rhs) => receiver[index] ??= rhs;
- ///
- R visitIndexSetIfNull(
- SendSet node, Node receiver, Node index, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to [index] on the index operators
- /// of a super class defined by [getter] and [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](index) {}
- /// operator [](index, value) {}
- /// }
- /// class C extends B {
- /// m(index, rhs) => super[index] ??= rhs;
- /// }
- ///
- R visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
- MethodElement setter, Node index, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to [index] on a super class where
- /// the index getter is undefined and the index setter is defined by [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](index, value) {}
- /// }
- /// class C extends B {
- /// m() => super[1] ??= 42;
- /// }
- ///
- R visitUnresolvedSuperGetterIndexSetIfNull(SendSet node, Element element,
- MethodElement setter, Node index, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to [index] on a super class where
- /// the index getter is defined by [getter] but the index setter is undefined.
- ///
- /// For instance:
- ///
- /// class B {
- /// operator [](index) => 42;
- /// }
- /// class C extends B {
- /// m() => super[1] ??= 42;
- /// }
- ///
- R visitUnresolvedSuperSetterIndexSetIfNull(SendSet node, MethodElement getter,
- Element element, Node index, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to [index] on a super class where
- /// the index getter and setter are undefined.
- ///
- /// For instance:
- ///
- /// class B {
- /// }
- /// class C extends B {
- /// m() => super[1] ??= 42;
- /// }
- ///
- R visitUnresolvedSuperIndexSetIfNull(
- Send node, Element element, Node index, Node rhs, A arg);
-
- /// Prefix expression with [operator] of the property on [receiver] whose
- /// getter and setter are defined by [getterSelector] and [setterSelector],
- /// respectively.
- ///
- /// For instance:
- ///
- /// m(receiver) => ++receiver.foo;
- ///
- R visitDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] of the property on a possibly null
- /// [receiver] whose getter and setter are defined by [getterSelector] and
- /// [setterSelector], respectively.
- ///
- /// For instance:
- ///
- /// m(receiver) => ++receiver?.foo;
- ///
- R visitIfNotNullDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a [parameter].
- ///
- /// For instance:
- ///
- /// m(parameter) => ++parameter;
- ///
- R visitParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a final [parameter].
- ///
- /// For instance:
- ///
- /// m(final parameter) => ++parameter;
- ///
- R visitFinalParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a local [variable].
- ///
- /// For instance:
- ///
- /// m() {
- /// var variable;
- /// ++variable;
- /// }
- ///
- R visitLocalVariablePrefix(
- Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a final local [variable].
- ///
- /// For instance:
- ///
- /// m() {
- /// final variable;
- /// ++variable;
- /// }
- ///
- R visitFinalLocalVariablePrefix(
- Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a local [function].
- ///
- /// For instance:
- ///
- /// m() {
- /// function() {}
- /// ++function;
- /// }
- ///
- R visitLocalFunctionPrefix(
- Send node, LocalFunctionElement function, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] of the property on `this` whose getter
- /// and setter are defined by [getterSelector] and [setterSelector],
- /// respectively.
- ///
- /// For instance:
- ///
- /// class C {
- /// m() => ++foo;
- /// }
- ///
- /// or
- ///
- /// class C {
- /// m() => ++this.foo;
- /// }
- ///
- R visitThisPropertyPrefix(
- Send node, Name name, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a static [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static var field;
- /// m() => ++field;
- /// }
- ///
- R visitStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a final static [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static final field = 42;
- /// m() => ++field;
- /// }
- ///
- R visitFinalStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a static [getter] and
- /// writing to a static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static get o => 0;
- /// static set o(_) {}
- /// m() => ++o;
- /// }
- ///
- R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a static [method], that is,
- /// closurizing [method], and writing to a static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static o() {}
- /// static set o(_) {}
- /// m() => ++o;
- /// }
- ///
- R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a top level [field].
- ///
- /// For instance:
- ///
- /// var field;
- /// m() => ++field;
- ///
- R visitTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a final top level [field].
- ///
- /// For instance:
- ///
- /// final field;
- /// m() => ++field;
- ///
- R visitFinalTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a top level [getter] and
- /// writing to a top level [setter].
- ///
- /// For instance:
- ///
- /// get o => 0;
- /// set o(_) {}
- /// m() => ++o;
- ///
- R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a top level [method], that
- /// is, closurizing [method], and writing to a top level [setter].
- ///
- /// For instance:
- ///
- /// o() {}
- /// set o(_) {}
- /// m() => ++o;
- ///
- R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a super [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// var field;
- /// }
- /// class C extends B {
- /// m() => ++super.field;
- /// }
- ///
- R visitSuperFieldPrefix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from the super field [readField]
- /// and writing to the different super field [writtenField].
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// final field;
- /// }
- /// class C extends B {
- /// m() => ++super.field;
- /// }
- ///
- R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a super [field] and writing
- /// to a super [setter].
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// set field(_) {}
- /// }
- /// class C extends B {
- /// m() => ++super.field;
- /// }
- ///
- R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a super [getter] and
- /// writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// get field => 0;
- /// set field(_) {}
- /// }
- /// class C extends B {
- /// m() => ++super.field;
- /// }
- ///
- R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a super [getter] and
- /// writing to a super [field].
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// get field => 0;
- /// }
- /// class C extends B {
- /// m() => ++super.field;
- /// }
- ///
- R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a super [method], that is,
- /// closurizing [method], and writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m() => ++super.o;
- /// }
- ///
- R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a super [method], that is,
- /// closurizing [method], and writing to an unresolved super setter.
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m() => ++super.o;
- /// }
- ///
- R visitSuperMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from an unresolved super getter
- /// and writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m() => ++super.o;
- /// }
- ///
- ///
- R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a super [getter] and
- /// writing to an unresolved super setter.
- ///
- /// For instance:
- ///
- /// class B {
- /// get o => 42
- /// }
- /// class C extends B {
- /// m() => ++super.o;
- /// }
- ///
- ///
- R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a type literal for a class [element].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() => ++C;
- ///
- R visitClassTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a type literal for a typedef
- /// [element].
- ///
- /// For instance:
- ///
- /// typedef F();
- /// m() => ++F;
- ///
- R visitTypedefTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on a type literal for a type variable
- /// [element].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// m() => ++T;
- /// }
- ///
- R visitTypeVariableTypeLiteralPrefix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] on the type literal for `dynamic`.
- ///
- /// For instance:
- ///
- /// m() => ++dynamic;
- ///
- R visitDynamicTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] of the property on [receiver] whose
- /// getter and setter are defined by [getterSelector] and [setterSelector],
- /// respectively.
- ///
- /// For instance:
- ///
- /// m(receiver) => receiver.foo++;
- ///
- R visitDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] of the property on a possibly null
- /// [receiver] whose getter and setter are defined by [getterSelector] and
- /// [setterSelector], respectively.
- ///
- /// For instance:
- ///
- /// m(receiver) => receiver?.foo++;
- ///
- R visitIfNotNullDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a [parameter].
- ///
- /// For instance:
- ///
- /// m(parameter) => parameter++;
- ///
- R visitParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a final [parameter].
- ///
- /// For instance:
- ///
- /// m(final parameter) => parameter++;
- ///
- R visitFinalParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a local [variable].
- ///
- /// For instance:
- ///
- /// m() {
- /// var variable;
- /// variable++;
- /// }
- ///
- R visitLocalVariablePostfix(
- Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a final local [variable].
- ///
- /// For instance:
- ///
- /// m() {
- /// final variable;
- /// variable++;
- /// }
- ///
- R visitFinalLocalVariablePostfix(
- Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a local [function].
- ///
- /// For instance:
- ///
- /// m() {
- /// function() {}
- /// function++;
- /// }
- ///
- R visitLocalFunctionPostfix(
- Send node, LocalFunctionElement function, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] of the property on `this` whose getter
- /// and setter are defined by [getterSelector] and [setterSelector],
- /// respectively.
- ///
- /// For instance:
- ///
- /// class C {
- /// m() => foo++;
- /// }
- ///
- /// or
- ///
- /// class C {
- /// m() => this.foo++;
- /// }
- ///
- R visitThisPropertyPostfix(
- Send node, Name name, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a static [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static var field;
- /// m() => field++;
- /// }
- ///
- R visitStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a final static [field].
- ///
- /// For instance:
- ///
- /// class C {
- /// static final field;
- /// m() => field++;
- /// }
- ///
- R visitFinalStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a static [getter] and
- /// writing to a static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static get o => 0;
- /// static set o(_) {}
- /// m() => o++;
- /// }
- ///
- R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a static [method], that
- /// is, closurizing [method], and writing to a static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static o() {}
- /// static set o(_) {}
- /// m() => o++;
- /// }
- ///
- R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a top level [field].
- ///
- /// For instance:
- ///
- /// var field;
- /// m() => field++;
- ///
- R visitTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a final top level [field].
- ///
- /// For instance:
- ///
- /// final field = 42;
- /// m() => field++;
- ///
- R visitFinalTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a top level [getter] and
- /// writing to a top level [setter].
- ///
- /// For instance:
- ///
- /// get o => 0;
- /// set o(_) {}
- /// m() => o++;
- ///
- R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a top level [method], that
- /// is, closurizing [method], and writing to a top level [setter].
- ///
- /// For instance:
- ///
- /// o() {}
- /// set o(_) {}
- /// m() => o++;
- ///
- R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a super [field].
- ///
- /// For instance:
- ///
- /// class B {
- /// var field;
- /// }
- /// class C extends B {
- /// m() => super.field++;
- /// }
- ///
- R visitSuperFieldPostfix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from the super field
- /// [readField] and writing to the different super field [writtenField].
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// final field;
- /// }
- /// class C extends B {
- /// m() => super.field++;
- /// }
- ///
- R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a super [field] and
- /// writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// set field(_) {}
- /// }
- /// class C extends B {
- /// m() => super.field++;
- /// }
- ///
- R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a super [getter] and
- /// writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// get field => 0;
- /// set field(_) {}
- /// }
- /// class C extends B {
- /// m() => super.field++;
- /// }
- ///
- R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a super [getter] and
- /// writing to a super [field].
- ///
- /// For instance:
- ///
- /// class A {
- /// var field;
- /// }
- /// class B extends A {
- /// get field => 0;
- /// }
- /// class C extends B {
- /// m() => super.field++;
- /// }
- ///
- R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a super [method], that is,
- /// closurizing [method], and writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m() => super.o++;
- /// }
- ///
- R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] reading from a super [method], that is,
- /// closurizing [method], and writing to an unresolved super.
- ///
- /// For instance:
- ///
- /// class B {
- /// o() {}
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m() => super.o++;
- /// }
- ///
- R visitSuperMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from an unresolved super getter
- /// and writing to a super [setter].
- ///
- /// For instance:
- ///
- /// class B {
- /// set o(_) {}
- /// }
- /// class C extends B {
- /// m() => super.o++;
- /// }
- ///
- ///
- R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix expression with [operator] reading from a super [getter] and
- /// writing to an unresolved super setter.
- ///
- /// For instance:
- ///
- /// class B {
- /// get o => 42
- /// }
- /// class C extends B {
- /// m() => super.o++;
- /// }
- ///
- ///
- R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a type literal for a class
- /// [element].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m() => C++;
- ///
- R visitClassTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a type literal for a typedef
- /// [element].
- ///
- /// For instance:
- ///
- /// typedef F();
- /// m() => F++;
- ///
- R visitTypedefTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on a type literal for a type variable
- /// [element].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// m() => T++;
- /// }
- ///
- R visitTypeVariableTypeLiteralPostfix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg);
-
- /// Postfix expression with [operator] on the type literal for `dynamic`.
- ///
- /// For instance:
- ///
- /// m() => dynamic++;
- ///
- R visitDynamicTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
- /// Read of the [constant].
- ///
- /// For instance:
- ///
- /// const c = c;
- /// m() => c;
- ///
- R visitConstantGet(Send node, ConstantExpression constant, A arg);
-
- /// Invocation of the [constant] with [arguments].
- ///
- /// For instance:
- ///
- /// const c = null;
- /// m() => c(null, 42);
- ///
- R visitConstantInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// Read of the unresolved [element].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m1() => unresolved;
- /// m2() => prefix.unresolved;
- /// m3() => Unresolved.foo;
- /// m4() => unresolved.foo;
- /// m5() => unresolved.Foo.bar;
- /// m6() => C.unresolved;
- /// m7() => prefix.C.unresolved;
- /// m8() => prefix?.unresolved;
- /// m9() => Unresolved?.foo;
- /// m10() => unresolved?.foo;
- /// m11() => unresolved?.Foo?.bar;
- ///
- // TODO(johnniwinther): Split the cases in which a prefix is resolved.
- R visitUnresolvedGet(Send node, Element element, A arg);
-
- /// Read of the unresolved super [element].
- ///
- /// For instance:
- ///
- /// class B {}
- /// class C {
- /// m() => super.foo;
- /// }
- ///
- R visitUnresolvedSuperGet(Send node, Element element, A arg);
-
- /// Assignment of [rhs] to the unresolved [element].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m1() => unresolved = 42;
- /// m2() => prefix.unresolved = 42;
- /// m3() => Unresolved.foo = 42;
- /// m4() => unresolved.foo = 42;
- /// m5() => unresolved.Foo.bar = 42;
- /// m6() => C.unresolved = 42;
- /// m7() => prefix.C.unresolved = 42;
- /// m8() => prefix?.unresolved = 42;
- /// m9() => Unresolved?.foo = 42;
- /// m10() => unresolved?.foo = 42;
- /// m11() => unresolved?.Foo?.bar = 42;
- ///
- // TODO(johnniwinther): Split the cases in which a prefix is resolved.
- R visitUnresolvedSet(SendSet node, Element element, Node rhs, A arg);
-
- /// Assignment of [rhs] to the unresolved super [element].
- ///
- /// For instance:
- ///
- /// class B {}
- /// class C {
- /// m() => super.foo = 42;
- /// }
- ///
- R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg);
-
- /// Invocation of the unresolved [element] with [arguments].
- ///
- /// For instance:
- ///
- /// class C {}
- /// m1() => unresolved(null, 42);
- /// m2() => prefix.unresolved(null, 42);
- /// m3() => Unresolved.foo(null, 42);
- /// m4() => unresolved.foo(null, 42);
- /// m5() => unresolved.Foo.bar(null, 42);
- /// m6() => C.unresolved(null, 42);
- /// m7() => prefix.C.unresolved(null, 42);
- /// m8() => prefix?.unresolved(null, 42);
- /// m9() => Unresolved?.foo(null, 42);
- /// m10() => unresolved?.foo(null, 42);
- /// m11() => unresolved?.Foo?.bar(null, 42);
- ///
- // TODO(johnniwinther): Split the cases in which a prefix is resolved.
- R visitUnresolvedInvoke(
- Send node, Element element, NodeList arguments, Selector selector, A arg);
-
- /// Invocation of the unresolved super [element] with [arguments].
- ///
- /// For instance:
- ///
- /// class B {}
- /// class C extends B {
- /// m() => super.foo();
- /// }
- ///
- R visitUnresolvedSuperInvoke(
- Send node, Element element, NodeList arguments, Selector selector, A arg);
-
- /// Compound assignment of [rhs] with [operator] reading from the
- /// non-existing static getter and writing to the static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// set foo(_) {}
- /// }
- /// m1() => C.foo += 42;
- ///
- R visitUnresolvedStaticGetterCompound(Send node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment of [rhs] with [operator] reading from the
- /// non-existing top level getter and writing to the top level [setter].
- ///
- /// For instance:
- ///
- /// set foo(_) {}
- /// m1() => foo += 42;
- ///
- R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment of [rhs] with [operator] reading from the static
- /// [getter] and writing to the non-existing static setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// get foo => 42;
- /// }
- /// m1() => C.foo += 42;
- ///
- R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment of [rhs] with [operator] reading from the top level
- /// [getter] and writing to the non-existing top level setter.
- ///
- /// For instance:
- ///
- /// get foo => 42;
- /// m1() => foo += 42;
- ///
- R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment of [rhs] with [operator] reading the closurized static
- /// [method] and trying to invoke the non-existing setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// foo() {}
- /// }
- /// m1() => C.foo += 42;
- ///
- R visitStaticMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Compound assignment of [rhs] where both getter and setter are unresolved.
- ///
- /// For instance:
- ///
- /// class C {}
- /// m1() => unresolved += 42;
- /// m2() => prefix.unresolved += 42;
- /// m3() => Unresolved.foo += 42;
- /// m4() => unresolved.foo += 42;
- /// m5() => unresolved.Foo.bar += 42;
- /// m6() => C.unresolved += 42;
- /// m7() => prefix.C.unresolved += 42;
- /// m8() => prefix?.unresolved += 42;
- /// m9() => Unresolved?.foo += 42;
- /// m10() => unresolved?.foo += 42;
- /// m11() => unresolved?.Foo?.bar += 42;
- ///
- // TODO(johnniwinther): Split the cases in which a prefix is resolved.
- R visitUnresolvedCompound(Send node, ErroneousElement element,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Prefix operation of [operator] reading from the non-existing static getter
- /// and writing to the static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// set foo(_) {}
- /// }
- /// m1() => ++C.foo;
- ///
- R visitUnresolvedStaticGetterPrefix(Send node, Element element,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix operation of [operator] reading from the non-existing top level
- /// getter and writing to the top level [setter].
- ///
- /// For instance:
- ///
- /// set foo(_) {}
- /// m1() => ++foo;
- ///
- R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Prefix operation of [operator] reading from the static [getter] and
- /// writing to the non-existing static setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// get foo => 42;
- /// }
- /// m1() => ++C.foo;
- ///
- R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg);
-
- /// Postfix operation of [operator] reading from the top level [getter] and
- /// writing to the non-existing top level setter.
- ///
- /// For instance:
- ///
- /// get foo => 42;
- /// m1() => ++foo;
- ///
- R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg);
-
- /// Prefix operation of [operator] reading the closurized static [method] and
- /// trying to invoke the non-existing setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// foo() {}
- /// }
- /// m1() => ++C.foo;
- ///
- R visitStaticMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg);
-
- /// Prefix operation of [operator] reading the closurized top level [method]
- /// and trying to invoke the non-existing setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// foo() {}
- /// }
- /// m1() => ++C.foo;
- ///
- R visitTopLevelMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg);
-
- /// Prefix operation where both getter and setter are unresolved.
- ///
- /// For instance:
- ///
- /// class C {}
- /// m1() => ++unresolved;
- /// m2() => ++prefix.unresolved;
- /// m3() => ++Unresolved.foo;
- /// m4() => ++unresolved.foo;
- /// m5() => ++unresolved.Foo.bar;
- /// m6() => ++C.unresolved;
- /// m7() => ++prefix.C.unresolved;
- /// m8() => ++prefix?.unresolved;
- /// m9() => ++Unresolved?.foo;
- /// m10() => ++unresolved?.foo;
- /// m11() => ++unresolved?.Foo?.bar;
- ///
- // TODO(johnniwinther): Split the cases in which a prefix is resolved.
- R visitUnresolvedPrefix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg);
-
- /// Postfix operation of [operator] reading from the non-existing static
- /// getter and writing to the static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// set foo(_) {}
- /// }
- /// m1() => C.foo++;
- ///
- R visitUnresolvedStaticGetterPostfix(Send node, Element element,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix operation of [operator] reading from the non-existing top level
- /// getter and writing to the top level [setter].
- ///
- /// For instance:
- ///
- /// set foo(_) {}
- /// m1() => foo++;
- ///
- R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
- SetterElement setter, IncDecOperator operator, A arg);
-
- /// Postfix operation of [operator] reading from the static [getter] and
- /// writing to the non-existing static setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// get foo => 42;
- /// }
- /// m1() => C.foo++;
- ///
- R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg);
-
- /// Postfix operation of [operator] reading from the top level [getter] and
- /// writing to the non-existing top level setter.
- ///
- /// For instance:
- ///
- /// get foo => 42;
- /// m1() => foo++;
- ///
- R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg);
-
- /// Postfix operation of [operator] reading the closurized static [method] and
- /// trying to invoke the non-existing setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// foo() {}
- /// }
- /// m1() => C.foo++;
- ///
- R visitStaticMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg);
-
- /// Postfix operation of [operator] reading the closurized top level [method]
- /// and trying to invoke the non-existing setter.
- ///
- /// For instance:
- ///
- /// class C {
- /// foo() {}
- /// }
- /// m1() => C.foo++;
- ///
- R visitTopLevelMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg);
-
- /// Postfix operation where both getter and setter are unresolved.
- ///
- /// For instance:
- ///
- /// class C {}
- /// m1() => unresolved++;
- /// m2() => prefix.unresolved++;
- /// m3() => Unresolved.foo++;
- /// m4() => unresolved.foo++;
- /// m5() => unresolved.Foo.bar++;
- /// m6() => C.unresolved++;
- /// m7() => prefix.C.unresolved++;
- /// m8() => prefix?.unresolved++;
- /// m9() => Unresolved?.foo++;
- /// m10() => unresolved?.foo++;
- /// m11() => unresolved?.Foo?.bar++;
- ///
- // TODO(johnniwinther): Split the cases in which a prefix is resolved.
- R visitUnresolvedPostfix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg);
-
- /// Invocation of an undefined unary [operator] on [expression].
- R errorUndefinedUnaryExpression(
- Send node, Operator operator, Node expression, A arg);
-
- /// Invocation of an undefined unary [operator] with operands
- /// [left] and [right].
- R errorUndefinedBinaryExpression(
- Send node, Node left, Operator operator, Node right, A arg);
-
- /// Const invocation of a [constant] constructor.
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// const C(a, b);
- /// }
- /// m() => const C<int>(true, 42);
- ///
- R visitConstConstructorInvoke(
- NewExpression node, ConstructedConstantExpression constant, A arg);
-
- /// Const invocation of the `bool.fromEnvironment` constructor.
- ///
- /// For instance:
- ///
- /// m() => const bool.fromEnvironment('foo', defaultValue: false);
- ///
- R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
- BoolFromEnvironmentConstantExpression constant, A arg);
-
- /// Const invocation of the `int.fromEnvironment` constructor.
- ///
- /// For instance:
- ///
- /// m() => const int.fromEnvironment('foo', defaultValue: 42);
- ///
- R visitIntFromEnvironmentConstructorInvoke(
- NewExpression node, IntFromEnvironmentConstantExpression constant, A arg);
-
- /// Const invocation of the `String.fromEnvironment` constructor.
- ///
- /// For instance:
- ///
- /// m() => const String.fromEnvironment('foo', defaultValue: 'bar');
- ///
- R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
- StringFromEnvironmentConstantExpression constant, A arg);
-
- /// Invocation of a generative [constructor] on [type] with [arguments].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// C(a, b);
- /// }
- /// m() => new C<int>(true, 42);
- ///
- /// where [type] is `C<int>`.
- ///
- R visitGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Invocation of a redirecting generative [constructor] on [type] with
- /// [arguments].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// C(a, b) : this._(b, a);
- /// C._(b, a);
- /// }
- /// m() => new C<int>(true, 42);
- ///
- /// where [type] is `C<int>`.
- ///
- R visitRedirectingGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Invocation of a factory [constructor] on [type] with [arguments].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// factory C(a, b) => new C<T>._(b, a);
- /// C._(b, a);
- /// }
- /// m() => new C<int>(true, 42);
- ///
- /// where [type] is `C<int>`.
- ///
- R visitFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Invocation of a factory [constructor] on [type] with [arguments] where
- /// [effectiveTarget] and [effectiveTargetType] are the constructor effective
- /// invoked and its type, respectively.
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// factory C(a, b) = C<int>.a;
- /// factory C.a(a, b) = C<C<T>>.b;
- /// C.b(a, b);
- /// }
- /// m() => new C<double>(true, 42);
- ///
- /// where [type] is `C<double>`, [effectiveTarget] is `C.b` and
- /// [effectiveTargetType] is `C<C<int>>`.
- ///
- R visitRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- ConstructorElement effectiveTarget,
- ResolutionInterfaceType effectiveTargetType,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Invocation of an unresolved [constructor] on [type] with [arguments].
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// C();
- /// }
- /// m() => new C<int>.unresolved(true, 42);
- ///
- /// where [type] is `C<int>`.
- ///
- // TODO(johnniwinther): Change [type] to [InterfaceType] when is it not
- // `dynamic`.
- R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
- ResolutionDartType type, NodeList arguments, Selector selector, A arg);
-
- /// Invocation of a constructor on an unresolved [type] with [arguments].
- ///
- /// For instance:
- ///
- /// m() => new Unresolved(true, 42);
- ///
- /// where [type] is the malformed type `Unresolved`.
- ///
- // TODO(johnniwinther): Change [type] to [MalformedType] when is it not
- // `dynamic`.
- R visitUnresolvedClassConstructorInvoke(
- NewExpression node,
- ErroneousElement element,
- ResolutionDartType type,
- NodeList arguments,
- Selector selector,
- A arg);
-
- /// Constant invocation of a non-constant constructor.
- ///
- /// For instance:
- ///
- /// class C {
- /// C(a, b);
- /// }
- /// m() => const C(true, 42);
- ///
- R errorNonConstantConstructorInvoke(
- NewExpression node,
- Element element,
- ResolutionDartType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Invocation of a constructor on an abstract [type] with [arguments].
- ///
- /// For instance:
- ///
- /// m() => new Unresolved(true, 42);
- ///
- /// where [type] is the malformed type `Unresolved`.
- ///
- R visitAbstractClassConstructorInvoke(
- NewExpression node,
- ConstructorElement element,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Invocation of a factory [constructor] on [type] with [arguments] where
- /// [effectiveTarget] and [effectiveTargetType] are the constructor effective
- /// invoked and its type, respectively.
- ///
- /// For instance:
- ///
- /// class C {
- /// factory C(a, b) = Unresolved;
- /// factory C.a(a, b) = C.unresolved;
- /// }
- /// m1() => new C(true, 42);
- /// m2() => new C.a(true, 42);
- ///
- R visitUnresolvedRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Invocation of [constructor] on [type] with incompatible [arguments].
- ///
- /// For instance:
- ///
- /// class C {
- /// C(a);
- /// }
- /// m() => C(true, 42);
- ///
- R visitConstructorIncompatibleInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// Read access of an invalid expression.
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m() => p;
- ///
- R errorInvalidGet(Send node, ErroneousElement error, A arg);
-
- /// Invocation of an invalid expression with [arguments].
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m() => p(null, 42);
- ///
- R errorInvalidInvoke(Send node, ErroneousElement error, NodeList arguments,
- Selector selector, A arg);
-
- /// Assignment of [rhs] to an invalid expression.
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m() { p = 42; }
- ///
- R errorInvalidSet(Send node, ErroneousElement error, Node rhs, A arg);
-
- /// Prefix operation on an invalid expression.
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m() => ++p;
- ///
- R errorInvalidPrefix(
- Send node, ErroneousElement error, IncDecOperator operator, A arg);
-
- /// Postfix operation on an invalid expression.
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m() => p--;
- ///
- R errorInvalidPostfix(
- Send node, ErroneousElement error, IncDecOperator operator, A arg);
-
- /// Compound assignment of [operator] with [rhs] on an invalid expression.
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m() => p += 42;
- ///
- R errorInvalidCompound(Send node, ErroneousElement error,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// If-null assignment expression of [rhs] to [index] on the index operators
- /// of an invalid expression.
- ///
- /// For instance:
- ///
- /// import 'foo.dart' as p;
- ///
- /// m(index, rhs) => p[index] ??= rhs;
- ///
- R errorInvalidIndexSetIfNull(
- SendSet node, ErroneousElement error, Node index, Node rhs, A arg);
-
- /// Unary operation with [operator] on an invalid expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => ~super;
- /// }
- ///
- R errorInvalidUnary(
- Send node, UnaryOperator operator, ErroneousElement error, A arg);
-
- /// Equals operation on an invalid left expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => super == null;
- /// }
- ///
- R errorInvalidEquals(Send node, ErroneousElement error, Node right, A arg);
-
- /// Not equals operation on an invalid left expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => super != null;
- /// }
- ///
- R errorInvalidNotEquals(Send node, ErroneousElement error, Node right, A arg);
-
- /// Binary operation with [operator] on an invalid left expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => super + 0;
- /// }
- ///
- R errorInvalidBinary(Send node, ErroneousElement error,
- BinaryOperator operator, Node right, A arg);
-
- /// Index operation on an invalid expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => super[0];
- /// }
- ///
- R errorInvalidIndex(Send node, ErroneousElement error, Node index, A arg);
-
- /// Index set operation on an invalid expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => super[0] = 42;
- /// }
- ///
- R errorInvalidIndexSet(
- Send node, ErroneousElement error, Node index, Node rhs, A arg);
-
- /// Compound index set operation on an invalid expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => super[0] += 42;
- /// }
- ///
- R errorInvalidCompoundIndexSet(Send node, ErroneousElement error, Node index,
- AssignmentOperator operator, Node rhs, A arg);
-
- /// Prefix index operation on an invalid expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => --super[0];
- /// }
- ///
- R errorInvalidIndexPrefix(Send node, ErroneousElement error, Node index,
- IncDecOperator operator, A arg);
-
- /// Postfix index operation on an invalid expression.
- ///
- /// For instance:
- ///
- /// class C {
- /// static m() => super[0]++;
- /// }
- ///
- R errorInvalidIndexPostfix(Send node, ErroneousElement error, Node index,
- IncDecOperator operator, A arg);
-
- /// Access of library through a deferred [prefix].
- ///
- /// For instance:
- ///
- /// import 'lib.dart' deferred as prefix;
- ///
- /// m() => prefix.foo;
- ///
- /// This visit method is special in that it is called as a pre-step to calling
- /// the visit method for the actual access. Therefore this method cannot
- /// return a result to its caller.
- void previsitDeferredAccess(Send node, PrefixElement prefix, A arg);
-}
-
-abstract class SemanticDeclarationVisitor<R, A> {
- R apply(Node node, A arg);
-
- /// Apply this visitor to the [parameters].
- applyParameters(NodeList parameters, A arg);
-
- /// Apply this visitor to the initializers of [constructor].
- applyInitializers(FunctionExpression constructor, A arg);
-
- /// A declaration of a top level [getter].
- ///
- /// For instance:
- ///
- /// get m => 42;
- ///
- R visitTopLevelGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg);
-
- /// A declaration of a top level [setter].
- ///
- /// For instance:
- ///
- /// set m(a) {}
- ///
- R visitTopLevelSetterDeclaration(FunctionExpression node,
- SetterElement setter, NodeList parameters, Node body, A arg);
-
- /// A declaration of a top level [function].
- ///
- /// For instance:
- ///
- /// m(a) {}
- ///
- R visitTopLevelFunctionDeclaration(FunctionExpression node,
- MethodElement function, NodeList parameters, Node body, A arg);
-
- /// A declaration of a static [getter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static get m => 42;
- /// }
- ///
- R visitStaticGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg);
-
- /// A declaration of a static [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// static set m(a) {}
- /// }
- ///
- R visitStaticSetterDeclaration(FunctionExpression node, SetterElement setter,
- NodeList parameters, Node body, A arg);
-
- /// A declaration of a static [function].
- ///
- /// For instance:
- ///
- /// class C {
- /// static m(a) {}
- /// }
- ///
- R visitStaticFunctionDeclaration(FunctionExpression node,
- MethodElement function, NodeList parameters, Node body, A arg);
-
- /// A declaration of an abstract instance [getter].
- ///
- /// For instance:
- ///
- /// abstract class C {
- /// get m;
- /// }
- ///
- R visitAbstractGetterDeclaration(
- FunctionExpression node, GetterElement getter, A arg);
-
- /// A declaration of an abstract instance [setter].
- ///
- /// For instance:
- ///
- /// abstract class C {
- /// set m(a);
- /// }
- ///
- R visitAbstractSetterDeclaration(FunctionExpression node,
- SetterElement setter, NodeList parameters, A arg);
-
- /// A declaration of an abstract instance [method].
- ///
- /// For instance:
- ///
- /// abstract class C {
- /// m(a);
- /// }
- ///
- R visitAbstractMethodDeclaration(FunctionExpression node,
- MethodElement method, NodeList parameters, A arg);
-
- /// A declaration of an instance [getter].
- ///
- /// For instance:
- ///
- /// class C {
- /// get m => 42;
- /// }
- ///
- R visitInstanceGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg);
-
- /// A declaration of an instance [setter].
- ///
- /// For instance:
- ///
- /// class C {
- /// set m(a) {}
- /// }
- ///
- R visitInstanceSetterDeclaration(FunctionExpression node,
- SetterElement setter, NodeList parameters, Node body, A arg);
-
- /// A declaration of an instance [method].
- ///
- /// For instance:
- ///
- /// class C {
- /// m(a) {}
- /// }
- ///
- R visitInstanceMethodDeclaration(FunctionExpression node,
- MethodElement method, NodeList parameters, Node body, A arg);
-
- /// A declaration of a local [function].
- ///
- /// For instance `local` in:
- ///
- /// m() {
- /// local(a) {}
- /// }
- ///
- R visitLocalFunctionDeclaration(FunctionExpression node,
- LocalFunctionElement function, NodeList parameters, Node body, A arg);
-
- /// A declaration of a [closure].
- ///
- /// For instance `(a) {}` in:
- ///
- /// m() {
- /// var closure = (a) {};
- /// }
- ///
- R visitClosureDeclaration(FunctionExpression node,
- LocalFunctionElement closure, NodeList parameters, Node body, A arg);
-
- /// A declaration of the [index]th [parameter] in a constructor, setter,
- /// method or function.
- ///
- /// For instance `a` in:
- ///
- /// m(a) {}
- ///
- R visitParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, int index, A arg);
-
- /// A declaration of the [index]th optional [parameter] in a constructor,
- /// method or function with the explicit [defaultValue]. If no default value
- /// is declared, [defaultValue] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// m([a = 42]) {}
- ///
- R visitOptionalParameterDeclaration(
- VariableDefinitions node,
- Node definition,
- ParameterElement parameter,
- ConstantExpression defaultValue,
- int index,
- A arg);
-
- /// A declaration of a named [parameter] in a constructor, method or function
- /// with the explicit [defaultValue]. If no default value is declared,
- /// [defaultValue] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// m({a: 42}) {}
- ///
- R visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, ConstantExpression defaultValue, A arg);
-
- /// A declaration of the [index]th [parameter] as an initializing formal in a
- /// constructor.
- ///
- /// For instance `a` in:
- ///
- /// class C {
- /// var a;
- /// C(this.a);
- /// }
- ///
- R visitInitializingFormalDeclaration(VariableDefinitions node,
- Node definition, InitializingFormalElement parameter, int index, A arg);
-
- /// A declaration of the [index]th optional [parameter] as an initializing
- /// formal in a constructor with the explicit [defaultValue]. If no default
- /// value is declared, [defaultValue] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// class C {
- /// var a;
- /// C([this.a = 42]);
- /// }
- ///
- R visitOptionalInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement parameter,
- ConstantExpression defaultValue,
- int index,
- A arg);
-
- /// A declaration of a named [parameter] as an initializing formal in a
- /// constructor with the explicit [defaultValue]. If no default value is
- /// declared, [defaultValue] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// class C {
- /// var a;
- /// C({this.a: 42});
- /// }
- ///
- R visitNamedInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement parameter,
- ConstantExpression defaultValue,
- A arg);
-
- /// A declaration of a local [variable] with the explicit [initializer]. If
- /// no initializer is declared, [initializer] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// m() {
- /// var a = 42;
- /// }
- ///
- R visitLocalVariableDeclaration(VariableDefinitions node, Node definition,
- LocalVariableElement variable, Node initializer, A arg);
-
- /// A declaration of a local constant [variable] initialized to [constant].
- ///
- /// For instance `a` in:
- ///
- /// m() {
- /// const a = 42;
- /// }
- ///
- R visitLocalConstantDeclaration(VariableDefinitions node, Node definition,
- LocalVariableElement variable, ConstantExpression constant, A arg);
-
- /// A declaration of a top level [field] with the explicit [initializer].
- /// If no initializer is declared, [initializer] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// var a = 42;
- ///
- R visitTopLevelFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg);
-
- /// A declaration of a top level constant [field] initialized to [constant].
- ///
- /// For instance `a` in:
- ///
- /// const a = 42;
- ///
- R visitTopLevelConstantDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, ConstantExpression constant, A arg);
-
- /// A declaration of a static [field] with the explicit [initializer].
- /// If no initializer is declared, [initializer] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// class C {
- /// static var a = 42;
- /// }
- ///
- R visitStaticFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg);
-
- /// A declaration of a static constant [field] initialized to [constant].
- ///
- /// For instance `a` in:
- ///
- /// class C {
- /// static const a = 42;
- /// }
- ///
- R visitStaticConstantDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, ConstantExpression constant, A arg);
-
- /// A declaration of an instance [field] with the explicit [initializer].
- /// If no initializer is declared, [initializer] is `null`.
- ///
- /// For instance `a` in:
- ///
- /// class C {
- /// var a = 42;
- /// }
- ///
- R visitInstanceFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg);
-
- /// A declaration of a generative [constructor] with the explicit constructor
- /// [initializers].
- ///
- /// For instance `C` in:
- ///
- /// class C {
- /// var a;
- /// C(a) : this.a = a, super();
- /// }
- ///
- // TODO(johnniwinther): Replace [initializers] with a structure like
- // [InitializersStructure] when computed in resolution.
- R visitGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- Node body,
- A arg);
-
- /// A declaration of a redirecting generative [constructor] with
- /// [initializers] containing the redirecting constructor invocation.
- ///
- /// For instance `C` in:
- ///
- /// class C {
- /// C() : this._();
- /// C._();
- /// }
- ///
- // TODO(johnniwinther): Replace [initializers] with a single
- // [ThisConstructorInvokeStructure] when computed in resolution.
- R visitRedirectingGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- A arg);
-
- /// A declaration of a factory [constructor].
- ///
- /// For instance `C` in:
- ///
- /// class C {
- /// factory C(a) => null;
- /// }
- ///
- R visitFactoryConstructorDeclaration(FunctionExpression node,
- ConstructorElement constructor, NodeList parameters, Node body, A arg);
-
- /// A declaration of a redirecting factory [constructor]. The immediate
- /// redirection target and its type is provided in [redirectionTarget] and
- /// [redirectionType], respectively.
- ///
- /// For instance:
- ///
- /// class C<T> {
- /// factory C() = C<int>.a;
- /// factory C.a() = C<C<T>>.b;
- /// C.b();
- /// }
- /// where `C` has the redirection target `C.a` of type `C<int>` and `C.a` has
- /// the redirection target `C.b` of type `C<C<T>>`.
- ///
- R visitRedirectingFactoryConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- ResolutionInterfaceType redirectionType,
- ConstructorElement redirectionTarget,
- A arg);
-
- /// An initializer of [field] with [initializer] as found in constructor
- /// initializers.
- ///
- /// For instance `this.a = 42` in:
- ///
- /// class C {
- /// var a;
- /// C() : this.a = 42;
- /// }
- ///
- R visitFieldInitializer(
- SendSet node, FieldElement field, Node initializer, A arg);
-
- /// An initializer of an unresolved field with [initializer] as found in
- /// generative constructor initializers.
- ///
- /// For instance `this.a = 42` in:
- ///
- /// class C {
- /// C() : this.a = 42;
- /// }
- ///
- R errorUnresolvedFieldInitializer(
- SendSet node, Element element, Node initializer, A arg);
-
- /// An super constructor invocation of [superConstructor] with [arguments] as
- /// found in generative constructor initializers.
- ///
- /// For instance `super(42)` in:
- ///
- /// class B {
- /// B(a);
- /// }
- /// class C extends B {
- /// C() : super(42);
- /// }
- ///
- R visitSuperConstructorInvoke(
- Send node,
- ConstructorElement superConstructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- /// An implicit super constructor invocation of [superConstructor] from
- /// generative constructor initializers.
- ///
- /// For instance `super(42)` in:
- ///
- /// class B {
- /// B();
- /// }
- /// class C extends B {
- /// C(); // Implicit super call of B().
- /// }
- ///
- R visitImplicitSuperConstructorInvoke(FunctionExpression node,
- ConstructorElement superConstructor, ResolutionInterfaceType type, A arg);
-
- /// An super constructor invocation of an unresolved with [arguments] as
- /// found in generative constructor initializers.
- ///
- /// For instance `super(42)` in:
- ///
- /// class B {
- /// B(a);
- /// }
- /// class C extends B {
- /// C() : super.unresolved(42);
- /// }
- ///
- R errorUnresolvedSuperConstructorInvoke(
- Send node, Element element, NodeList arguments, Selector selector, A arg);
-
- /// An this constructor invocation of [thisConstructor] with [arguments] as
- /// found in a redirecting generative constructors initializer.
- ///
- /// For instance `this._(42)` in:
- ///
- /// class C {
- /// C() : this._(42);
- /// C._(a);
- /// }
- ///
- R visitThisConstructorInvoke(Send node, ConstructorElement thisConstructor,
- NodeList arguments, CallStructure callStructure, A arg);
-
- /// An this constructor invocation of an unresolved constructor with
- /// [arguments] as found in a redirecting generative constructors initializer.
- ///
- /// For instance `this._(42)` in:
- ///
- /// class C {
- /// C() : this._(42);
- /// }
- ///
- R errorUnresolvedThisConstructorInvoke(
- Send node, Element element, NodeList arguments, Selector selector, A arg);
-}
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
deleted file mode 100644
index 7f6d668..0000000
--- a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
+++ /dev/null
@@ -1,8337 +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.
-
-part of dart2js.semantics_visitor;
-
-/// Interface for bulk handling of a [Node] in a semantic visitor.
-abstract class BulkHandle<R, A> {
- /// Handle [node] either regardless of semantics or to report that [node] is
- /// unhandled. [message] contains a message template for the latter case:
- /// Replace '#' in [message] by `node.toString()` to create a message for the
- /// error.
- R bulkHandleNode(Node node, String message, A arg);
-}
-
-/// Mixin that implements all `errorX` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `errorX` methods.
-abstract class ErrorBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- // TODO(johnniwinther): Ensure that all error methods have an
- // [ErroneousElement].
- R bulkHandleError(Node node, ErroneousElement error, A arg) {
- return bulkHandleNode(node, "Error expression `#` unhandled.", arg);
- }
-
- @override
- R errorNonConstantConstructorInvoke(
- NewExpression node,
- Element element,
- ResolutionDartType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleError(node, null, arg);
- }
-
- @override
- R errorUndefinedUnaryExpression(
- Send node, Operator operator, Node expression, A arg) {
- return bulkHandleError(node, null, arg);
- }
-
- @override
- R errorUndefinedBinaryExpression(
- Send node, Node left, Operator operator, Node right, A arg) {
- return bulkHandleError(node, null, arg);
- }
-
- @override
- R errorInvalidCompound(Send node, ErroneousElement error,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidGet(Send node, ErroneousElement error, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidInvoke(Send node, ErroneousElement error, NodeList arguments,
- Selector selector, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidPostfix(
- Send node, ErroneousElement error, IncDecOperator operator, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidPrefix(
- Send node, ErroneousElement error, IncDecOperator operator, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidSet(Send node, ErroneousElement error, Node rhs, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidUnary(
- Send node, UnaryOperator operator, ErroneousElement error, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidEquals(Send node, ErroneousElement error, Node right, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidNotEquals(
- Send node, ErroneousElement error, Node right, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidBinary(Send node, ErroneousElement error,
- BinaryOperator operator, Node right, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidIndex(Send node, ErroneousElement error, Node index, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidIndexSet(
- Send node, ErroneousElement error, Node index, Node rhs, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidCompoundIndexSet(Send node, ErroneousElement error, Node index,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidIndexSetIfNull(
- SendSet node, ErroneousElement error, Node index, Node rhs, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidIndexPrefix(Send node, ErroneousElement error, Node index,
- IncDecOperator operator, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidIndexPostfix(Send node, ErroneousElement error, Node index,
- IncDecOperator operator, A arg) {
- return bulkHandleError(node, error, arg);
- }
-
- @override
- R errorInvalidSetIfNull(Send node, ErroneousElement error, Node rhs, A arg) {
- return bulkHandleError(node, error, arg);
- }
-}
-
-/// Mixin that implements all `visitXPrefix` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXPrefix`
-/// methods.
-abstract class PrefixBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandlePrefix(SendSet node, A arg) {
- return bulkHandleNode(node, "Prefix expression `#` unhandled.", arg);
- }
-
- @override
- R visitDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- R visitIfNotNullDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitIndexPrefix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperFieldPrefix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperIndexPrefix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPrefix(SendSet node, MethodElement getter,
- Element element, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperIndexPrefix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitThisPropertyPrefix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitClassTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitDynamicTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
- IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralPrefix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitTypedefTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedStaticGetterPrefix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitStaticMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitTopLevelMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedPrefix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitFinalParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitFinalStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitFinalSuperFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitSuperMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitFinalTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperPrefix(
- SendSet node, Element element, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return bulkHandlePrefix(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXPostfix` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXPostfix`
-/// methods.
-abstract class PostfixBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandlePostfix(SendSet node, A arg) {
- return bulkHandleNode(node, "Postfix expression `#` unhandled.", arg);
- }
-
- @override
- R visitDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- R visitIndexPostfix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperFieldPostfix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperIndexPostfix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPostfix(SendSet node, MethodElement getter,
- Element element, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperIndexPostfix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitThisPropertyPostfix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitClassTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitDynamicTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
- IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralPostfix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitTypedefTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedStaticGetterPostfix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitStaticMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- R visitToplevelMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedPostfix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitFinalParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitFinalStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitFinalSuperFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitSuperMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitFinalTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitTopLevelMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperPostfix(
- SendSet node, Element element, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return bulkHandlePostfix(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXCompound` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `xCompound`
-/// methods.
-abstract class CompoundBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleCompound(SendSet node, A arg) {
- return bulkHandleNode(node, "Compound assignment `#` unhandled.", arg);
- }
-
- @override
- R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitStaticGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitStaticMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitSuperFieldSetterCompound(Send node, FieldElement field,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitSuperGetterFieldCompound(Send node, GetterElement getter,
- FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitSuperGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitSuperMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitThisPropertyCompound(
- Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitFinalParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitFinalStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitFinalSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedStaticGetterCompound(Send node, Element element,
- MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
- MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitStaticMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitTopLevelMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedCompound(Send node, ErroneousElement element,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitSuperFieldFieldCompound(Send node, FieldElement readField,
- FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitSuperMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedSuperCompound(Send node, Element element,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleCompound(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXSetIfNull` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `xSetIfNull`
-/// methods.
-abstract class SetIfNullBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleSetIfNull(SendSet node, A arg) {
- return bulkHandleNode(node, "If null assignment `#` unhandled.", arg);
- }
-
- @override
- R visitClassTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitDynamicTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitFinalLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitFinalParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitFinalStaticFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitFinalSuperFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitFinalTopLevelFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitLocalFunctionSetIfNull(
- Send node, LocalFunctionElement function, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitStaticGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitStaticMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitStaticMethodSetterSetIfNull(
- Send node, MethodElement method, MethodElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
- FieldElement writtenField, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperFieldSetterSetIfNull(
- Send node, FieldElement field, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperGetterFieldSetIfNull(
- Send node, GetterElement getter, FieldElement field, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
- SetterElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitTopLevelFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitTopLevelGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitTopLevelMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
- SetterElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralSetIfNull(
- Send node, TypeVariableElement element, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitTypedefTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedStaticGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedStaticSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitIndexSetIfNull(
- SendSet node, Node receiver, Node index, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
- MethodElement setter, Node index, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexSetIfNull(SendSet node, Element element,
- MethodElement setter, Node index, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexSetIfNull(SendSet node, MethodElement getter,
- Element element, Node index, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-
- @override
- R visitUnresolvedSuperIndexSetIfNull(
- Send node, Element element, Node index, Node rhs, A arg) {
- return bulkHandleSetIfNull(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXInvoke` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXInvoke`
-/// methods.
-abstract class InvokeBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleInvoke(Send node, A arg) {
- return bulkHandleNode(node, "Invocation `#` unhandled.", arg);
- }
-
- @override
- R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitExpressionInvoke(Send node, Node expression, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitLocalFunctionIncompatibleInvoke(
- Send node,
- LocalFunctionElement function,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitParameterInvoke(Send node, ParameterElement parameter,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitStaticFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitThisInvoke(
- Send node, NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitThisPropertyInvoke(
- Send node, NodeList arguments, Selector selector, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitTopLevelFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitTopLevelGetterInvoke(Send node, GetterElement getter,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralInvoke(Send node, TypeVariableElement element,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitConstantInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitUnresolvedInvoke(Send node, Element element, NodeList arguments,
- Selector selector, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
- Selector selector, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitSuperSetterInvoke(Send node, SetterElement setter, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-
- @override
- R visitTopLevelSetterInvoke(Send node, SetterElement setter,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInvoke(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXGet` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXGet`
-/// methods.
-abstract class GetBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleGet(Node node, A arg) {
- return bulkHandleNode(node, "Read `#` unhandled.", arg);
- }
-
- @override
- R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyGet(
- Send node, Node receiver, Name name, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitParameterGet(Send node, ParameterElement parameter, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitStaticFieldGet(Send node, FieldElement field, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitStaticFunctionGet(Send node, MethodElement function, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitStaticGetterGet(Send node, GetterElement getter, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitSuperFieldGet(Send node, FieldElement field, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitSuperGetterGet(Send node, GetterElement getter, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitSuperMethodGet(Send node, MethodElement method, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitThisGet(Identifier node, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitThisPropertyGet(Send node, Name name, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitTopLevelFieldGet(Send node, FieldElement field, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitTopLevelFunctionGet(Send node, MethodElement function, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitTopLevelGetterGet(Send node, GetterElement getter, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralGet(
- Send node, TypeVariableElement element, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitConstantGet(Send node, ConstantExpression constant, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitUnresolvedGet(Send node, Element element, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGet(Send node, Element element, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitStaticSetterGet(Send node, SetterElement setter, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitSuperSetterGet(Send node, SetterElement setter, A arg) {
- return bulkHandleGet(node, arg);
- }
-
- @override
- R visitTopLevelSetterGet(Send node, SetterElement setter, A arg) {
- return bulkHandleGet(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXSet` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXSet`
-/// methods.
-abstract class SetBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleSet(SendSet node, A arg) {
- return bulkHandleNode(node, "Assignment `#` unhandled.", arg);
- }
-
- @override
- R visitDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitTopLevelSetterSet(
- SendSet node, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitClassTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitDynamicTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitFinalLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitFinalParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitFinalStaticFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitFinalSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitFinalTopLevelFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitLocalFunctionSet(
- SendSet node, LocalFunctionElement function, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitStaticFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitSuperGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitSuperMethodSet(SendSet node, MethodElement method, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitTopLevelFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitTopLevelGetterSet(
- SendSet node, GetterElement getter, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralSet(
- SendSet node, TypeVariableElement element, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitTypedefTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitUnresolvedSet(SendSet node, Element element, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg) {
- return bulkHandleSet(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXIndexSet` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXIndexSet`
-/// methods.
-abstract class IndexSetBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleIndexSet(Send node, A arg) {
- return bulkHandleNode(node, "Index set expression `#` unhandled.", arg);
- }
-
- @override
- R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-
- @override
- R visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-
- @override
- R visitSuperCompoundIndexSet(
- SendSet node,
- MethodElement getter,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterCompoundIndexSet(
- SendSet node,
- Element element,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterCompoundIndexSet(
- SendSet node,
- MethodElement getter,
- Element element,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-
- @override
- R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
- Node index, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-
- @override
- R visitSuperIndexSet(
- SendSet node, FunctionElement function, Node index, Node rhs, A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-
- @override
- R visitUnresolvedSuperIndexSet(
- SendSet node, ErroneousElement element, Node index, Node rhs, A arg) {
- return bulkHandleIndexSet(node, arg);
- }
-}
-
-/// Mixin that implements all binary visitor methods in [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all binary visitor
-/// methods.
-abstract class BinaryBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleBinary(Send node, A arg) {
- return bulkHandleNode(node, "Binary expression `#` unhandled.", arg);
- }
-
- @override
- R visitBinary(
- Send node, Node left, BinaryOperator operator, Node right, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitEquals(Send node, Node left, Node right, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitNotEquals(Send node, Node left, Node right, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitIndex(Send node, Node receiver, Node index, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
- Node argument, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitSuperEquals(Send node, MethodElement function, Node argument, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitSuperNotEquals(
- Send node, MethodElement function, Node argument, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitSuperIndex(Send node, MethodElement function, Node index, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitUnresolvedSuperBinary(Send node, Element function,
- BinaryOperator operator, Node argument, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
- Selector selector, A arg) {
- return bulkHandleBinary(node, arg);
- }
-
- @override
- R visitUnresolvedSuperIndex(Send node, Element function, Node index, A arg) {
- return bulkHandleBinary(node, arg);
- }
-}
-
-/// Mixin that implements all unary visitor methods in [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all unary visitor
-/// methods.
-abstract class UnaryBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleUnary(Send node, A arg) {
- return bulkHandleNode(node, "Unary expression `#` unhandled.", arg);
- }
-
- @override
- R visitNot(Send node, Node expression, A arg) {
- return bulkHandleUnary(node, arg);
- }
-
- @override
- R visitSuperUnary(
- Send node, UnaryOperator operator, MethodElement function, A arg) {
- return bulkHandleUnary(node, arg);
- }
-
- @override
- R visitUnary(Send node, UnaryOperator operator, Node expression, A arg) {
- return bulkHandleUnary(node, arg);
- }
-
- @override
- R visitUnresolvedSuperUnary(
- Send node, UnaryOperator operator, Element function, A arg) {
- return bulkHandleUnary(node, arg);
- }
-}
-
-/// Mixin that implements all purely structural visitor methods in
-/// [SemanticSendVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all purely structural
-/// visitor methods.
-abstract class BaseBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- @override
- R visitAs(Send node, Node expression, ResolutionDartType type, A arg) {
- return bulkHandleNode(node, 'As cast `#` unhandled.', arg);
- }
-
- @override
- R visitIs(Send node, Node expression, ResolutionDartType type, A arg) {
- return bulkHandleNode(node, 'Is test `#` unhandled.', arg);
- }
-
- @override
- R visitIsNot(Send node, Node expression, ResolutionDartType type, A arg) {
- return bulkHandleNode(node, 'Is not test `#` unhandled.', arg);
- }
-
- @override
- R visitIfNull(Send node, Node left, Node right, A arg) {
- return bulkHandleNode(node, 'If-null (Lazy ?? `#`) unhandled.', arg);
- }
-
- @override
- R visitLogicalAnd(Send node, Node left, Node right, A arg) {
- return bulkHandleNode(node, 'Lazy and `#` unhandled.', arg);
- }
-
- @override
- R visitLogicalOr(Send node, Node left, Node right, A arg) {
- return bulkHandleNode(node, 'Lazy or `#` unhandled.', arg);
- }
-
- @override
- void previsitDeferredAccess(Send node, PrefixElement prefix, A arg) {
- bulkHandleNode(node, 'Deferred access `#` unhandled.', arg);
- }
-}
-
-/// Mixin that implements all visitor methods for `super` calls in
-/// [SemanticSendVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for `super` calls
-/// visitor methods.
-abstract class SuperBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleSuper(Send node, A arg) {
- return bulkHandleNode(node, "Super call `#` unhandled.", arg);
- }
-
- @override
- R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
- Node argument, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperCompoundIndexSet(
- SendSet node,
- MethodElement getter,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperEquals(Send node, MethodElement function, Node argument, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldGet(Send node, FieldElement field, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldPostfix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldPrefix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldSetterCompound(Send node, FieldElement field,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterFieldCompound(Send node, GetterElement getter,
- FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterGet(Send node, GetterElement getter, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperIndexSet(
- SendSet node, FunctionElement function, Node index, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperMethodGet(Send node, MethodElement method, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
- CallStructure callStructure, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperNotEquals(
- Send node, MethodElement function, Node argument, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitSuperUnary(
- Send node, UnaryOperator operator, MethodElement function, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitUnresolvedSuperBinary(Send node, Element element,
- BinaryOperator operator, Node argument, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitUnresolvedSuperGet(Send node, Element element, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
- Selector selector, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitUnresolvedSuperIndex(Send node, Element function, Node index, A arg) {
- return bulkHandleSuper(node, arg);
- }
-
- @override
- R visitUnresolvedSuperUnary(
- Send node, UnaryOperator operator, Element element, A arg) {
- return bulkHandleSuper(node, arg);
- }
-}
-
-abstract class NewBulkMixin<R, A>
- implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleNew(NewExpression node, A arg) {
- return bulkHandleNode(node, "Constructor invocation `#` unhandled.", arg);
- }
-
- @override
- R visitAbstractClassConstructorInvoke(
- NewExpression node,
- ConstructorElement element,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitConstConstructorInvoke(
- NewExpression node, ConstructedConstantExpression constant, A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
- BoolFromEnvironmentConstantExpression constant, A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitIntFromEnvironmentConstructorInvoke(NewExpression node,
- IntFromEnvironmentConstantExpression constant, A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
- StringFromEnvironmentConstantExpression constant, A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitConstructorIncompatibleInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitRedirectingGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- ConstructorElement effectiveTarget,
- ResolutionInterfaceType effectiveTargetType,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitUnresolvedClassConstructorInvoke(
- NewExpression node,
- ErroneousElement element,
- ResolutionDartType type,
- NodeList arguments,
- Selector selector,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
- ResolutionDartType type, NodeList arguments, Selector selector, A arg) {
- return bulkHandleNew(node, arg);
- }
-
- @override
- R visitUnresolvedRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleNew(node, arg);
- }
-}
-
-/// Visitor that implements [SemanticSendVisitor] by the use of `BulkX` mixins.
-///
-/// This class is useful in itself, but shows how to use the `BulkX` mixins and
-/// tests that the union of the `BulkX` mixins implement all `visit` and `error`
-/// methods of [SemanticSendVisitor].
-class BulkSendVisitor<R, A> extends SemanticSendVisitor<R, A>
- with
- GetBulkMixin<R, A>,
- SetBulkMixin<R, A>,
- ErrorBulkMixin<R, A>,
- InvokeBulkMixin<R, A>,
- IndexSetBulkMixin<R, A>,
- CompoundBulkMixin<R, A>,
- SetIfNullBulkMixin<R, A>,
- UnaryBulkMixin<R, A>,
- BaseBulkMixin<R, A>,
- BinaryBulkMixin<R, A>,
- PrefixBulkMixin<R, A>,
- PostfixBulkMixin<R, A>,
- NewBulkMixin<R, A> {
- @override
- R apply(Node node, A arg) {
- throw new UnimplementedError("BulkSendVisitor.apply unimplemented");
- }
-
- @override
- R bulkHandleNode(Node node, String message, A arg) {
- throw new UnimplementedError(
- "BulkSendVisitor.bulkHandleNode unimplemented");
- }
-}
-
-/// Mixin that implements all `visitXParameterDecl` and
-/// `visitXInitializingFormalDecl` methods of [SemanticDeclarationVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class ParameterBulkMixin<R, A>
- implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleParameterDeclaration(VariableDefinitions node, A arg) {
- return bulkHandleNode(node, "Parameter declaration `#` unhandled.", arg);
- }
-
- @override
- R visitInitializingFormalDeclaration(VariableDefinitions node,
- Node definition, InitializingFormalElement parameter, int index, A arg) {
- return bulkHandleParameterDeclaration(node, arg);
- }
-
- @override
- R visitNamedInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement parameter,
- ConstantExpression defaultValue,
- A arg) {
- return bulkHandleParameterDeclaration(node, arg);
- }
-
- @override
- R visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, ConstantExpression defaultValue, A arg) {
- return bulkHandleParameterDeclaration(node, arg);
- }
-
- @override
- R visitOptionalInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement parameter,
- ConstantExpression defaultValue,
- int index,
- A arg) {
- return bulkHandleParameterDeclaration(node, arg);
- }
-
- @override
- R visitOptionalParameterDeclaration(
- VariableDefinitions node,
- Node definition,
- ParameterElement parameter,
- ConstantExpression defaultValue,
- int index,
- A arg) {
- return bulkHandleParameterDeclaration(node, arg);
- }
-
- @override
- R visitParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, int index, A arg) {
- return bulkHandleParameterDeclaration(node, arg);
- }
-}
-
-/// Mixin that implements all `visitXConstructorDecl` methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class ConstructorBulkMixin<R, A>
- implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleConstructorDeclaration(FunctionExpression node, A arg) {
- return bulkHandleNode(node, "Constructor declaration `#` unhandled.", arg);
- }
-
- @override
- R visitFactoryConstructorDeclaration(FunctionExpression node,
- ConstructorElement constructor, NodeList parameters, Node body, A arg) {
- return bulkHandleConstructorDeclaration(node, arg);
- }
-
- @override
- R visitGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- Node body,
- A arg) {
- return bulkHandleConstructorDeclaration(node, arg);
- }
-
- @override
- R visitRedirectingFactoryConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- ResolutionInterfaceType redirectionType,
- ConstructorElement redirectionTarget,
- A arg) {
- return bulkHandleConstructorDeclaration(node, arg);
- }
-
- @override
- R visitRedirectingGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- A arg) {
- return bulkHandleConstructorDeclaration(node, arg);
- }
-}
-
-/// Mixin that implements all constructor initializer visitor methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class InitializerBulkMixin<R, A>
- implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleInitializer(Node node, A arg) {
- return bulkHandleNode(node, "Initializer `#` unhandled.", arg);
- }
-
- @override
- R errorUnresolvedFieldInitializer(
- SendSet node, Element element, Node initializer, A arg) {
- return bulkHandleInitializer(node, arg);
- }
-
- @override
- R errorUnresolvedSuperConstructorInvoke(Send node, Element element,
- NodeList arguments, Selector selector, A arg) {
- return bulkHandleInitializer(node, arg);
- }
-
- @override
- R errorUnresolvedThisConstructorInvoke(Send node, Element element,
- NodeList arguments, Selector selector, A arg) {
- return bulkHandleInitializer(node, arg);
- }
-
- @override
- R visitFieldInitializer(
- SendSet node, FieldElement field, Node initializer, A arg) {
- return bulkHandleInitializer(node, arg);
- }
-
- @override
- R visitSuperConstructorInvoke(
- Send node,
- ConstructorElement superConstructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return bulkHandleInitializer(node, arg);
- }
-
- @override
- R visitImplicitSuperConstructorInvoke(
- FunctionExpression node,
- ConstructorElement superConstructor,
- ResolutionInterfaceType type,
- A arg) {
- return bulkHandleInitializer(node, arg);
- }
-
- @override
- R visitThisConstructorInvoke(Send node, ConstructorElement thisConstructor,
- NodeList arguments, CallStructure callStructure, A arg) {
- return bulkHandleInitializer(node, arg);
- }
-}
-
-/// Mixin that implements all function declaration visitor methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class FunctionBulkMixin<R, A>
- implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleFunctionDeclaration(FunctionExpression node, A arg) {
- return bulkHandleNode(node, "Function declaration `#` unhandled.", arg);
- }
-
- @override
- R visitAbstractGetterDeclaration(
- FunctionExpression node, GetterElement getter, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitAbstractMethodDeclaration(FunctionExpression node,
- MethodElement method, NodeList parameters, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitAbstractSetterDeclaration(FunctionExpression node,
- MethodElement setter, NodeList parameters, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitClosureDeclaration(FunctionExpression node,
- LocalFunctionElement closure, NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitInstanceGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitInstanceMethodDeclaration(FunctionExpression node,
- MethodElement method, NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitInstanceSetterDeclaration(FunctionExpression node,
- MethodElement setter, NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitLocalFunctionDeclaration(FunctionExpression node,
- LocalFunctionElement function, NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitStaticFunctionDeclaration(FunctionExpression node,
- MethodElement function, NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitStaticGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitStaticSetterDeclaration(FunctionExpression node, MethodElement setter,
- NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitTopLevelFunctionDeclaration(FunctionExpression node,
- MethodElement function, NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitTopLevelGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-
- @override
- R visitTopLevelSetterDeclaration(FunctionExpression node,
- MethodElement setter, NodeList parameters, Node body, A arg) {
- return bulkHandleFunctionDeclaration(node, arg);
- }
-}
-
-/// Mixin that implements all variable/field declaration visitor methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class VariableBulkMixin<R, A>
- implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
- R bulkHandleVariableDeclaration(VariableDefinitions node, A arg) {
- return bulkHandleNode(node, "Variable declaration `#` unhandled.", arg);
- }
-
- @override
- R visitInstanceFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg) {
- return bulkHandleVariableDeclaration(node, arg);
- }
-
- @override
- R visitLocalConstantDeclaration(VariableDefinitions node, Node definition,
- LocalVariableElement variable, ConstantExpression constant, A arg) {
- return bulkHandleVariableDeclaration(node, arg);
- }
-
- @override
- R visitLocalVariableDeclaration(VariableDefinitions node, Node definition,
- LocalVariableElement variable, Node initializer, A arg) {
- return bulkHandleVariableDeclaration(node, arg);
- }
-
- @override
- R visitStaticConstantDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, ConstantExpression constant, A arg) {
- return bulkHandleVariableDeclaration(node, arg);
- }
-
- @override
- R visitStaticFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg) {
- return bulkHandleVariableDeclaration(node, arg);
- }
-
- @override
- R visitTopLevelConstantDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, ConstantExpression constant, A arg) {
- return bulkHandleVariableDeclaration(node, arg);
- }
-
- @override
- R visitTopLevelFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg) {
- return bulkHandleVariableDeclaration(node, arg);
- }
-}
-
-/// Visitor that implements [SemanticDeclarationVisitor] by the use of `BulkX`
-/// mixins.
-///
-/// This class is useful in itself, but shows how to use the `BulkX` mixins and
-/// tests that the union of the `BulkX` mixins implement all `visit` and `error`
-/// methods of [SemanticDeclarationVisitor].
-class BulkDeclarationVisitor<R, A> extends SemanticDeclarationVisitor<R, A>
- with
- ConstructorBulkMixin<R, A>,
- FunctionBulkMixin<R, A>,
- VariableBulkMixin<R, A>,
- ParameterBulkMixin<R, A>,
- InitializerBulkMixin<R, A> {
- @override
- R apply(Node node, A arg) {
- throw new UnimplementedError("BulkDeclVisitor.apply unimplemented");
- }
-
- @override
- R bulkHandleNode(Node node, String message, A arg) {
- throw new UnimplementedError(
- "BulkDeclVisitor.bulkHandleNode unimplemented");
- }
-
- @override
- applyInitializers(FunctionExpression constructor, A arg) {
- throw new UnimplementedError(
- "BulkDeclVisitor.applyInitializers unimplemented");
- }
-
- @override
- applyParameters(NodeList parameters, A arg) {
- throw new UnimplementedError(
- "BulkDeclVisitor.applyParameters unimplemented");
- }
-}
-
-/// [SemanticSendVisitor] that visits subnodes.
-class TraversalSendMixin<R, A> implements SemanticSendVisitor<R, A> {
- @override
- R apply(Node node, A arg) {
- throw new UnimplementedError("TraversalMixin.apply unimplemented");
- }
-
- @override
- void previsitDeferredAccess(Send node, PrefixElement prefix, A arg) {}
-
- @override
- R errorInvalidCompound(Send node, ErroneousElement error,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R errorInvalidGet(Send node, ErroneousElement error, A arg) {
- return null;
- }
-
- @override
- R errorInvalidInvoke(Send node, ErroneousElement error, NodeList arguments,
- Selector selector, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R errorInvalidPostfix(
- Send node, ErroneousElement error, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R errorInvalidPrefix(
- Send node, ErroneousElement error, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R errorInvalidSet(Send node, ErroneousElement error, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R errorInvalidUnary(
- Send node, UnaryOperator operator, ErroneousElement error, A arg) {
- return null;
- }
-
- @override
- R errorInvalidEquals(Send node, ErroneousElement error, Node right, A arg) {
- apply(right, arg);
- return null;
- }
-
- @override
- R errorInvalidNotEquals(
- Send node, ErroneousElement error, Node right, A arg) {
- apply(right, arg);
- return null;
- }
-
- @override
- R errorInvalidBinary(Send node, ErroneousElement error,
- BinaryOperator operator, Node right, A arg) {
- apply(right, arg);
- return null;
- }
-
- @override
- R errorInvalidIndex(Send node, ErroneousElement error, Node index, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R errorInvalidIndexSet(
- Send node, ErroneousElement error, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R errorInvalidCompoundIndexSet(Send node, ErroneousElement error, Node index,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R errorInvalidIndexPrefix(Send node, ErroneousElement error, Node index,
- IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R errorInvalidIndexPostfix(Send node, ErroneousElement error, Node index,
- IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitClassTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitDynamicTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalStaticFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalTopLevelFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
- IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
- IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitLocalFunctionSet(
- SendSet node, LocalFunctionElement function, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticSetterGet(Send node, SetterElement setter, A arg) {
- return null;
- }
-
- @override
- R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitSuperGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperMethodSet(SendSet node, MethodElement method, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperSetterGet(Send node, SetterElement setter, A arg) {
- return null;
- }
-
- @override
- R visitSuperSetterInvoke(Send node, SetterElement setter, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTopLevelFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelGetterSet(
- SendSet node, GetterElement getter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelSetterGet(Send node, SetterElement setter, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelSetterInvoke(Send node, SetterElement setter,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTypeVariableTypeLiteralSet(
- SendSet node, TypeVariableElement element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTypedefTypeLiteralSet(
- SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperIndex(Send node, Element function, Node index, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperGet(Send node, Element element, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
- Selector selector, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitAs(Send node, Node expression, ResolutionDartType type, A arg) {
- apply(expression, arg);
- return null;
- }
-
- @override
- R visitBinary(
- Send node, Node left, BinaryOperator operator, Node right, A arg) {
- apply(left, arg);
- apply(right, arg);
- return null;
- }
-
- @override
- R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitClassTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitClassTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(receiver, arg);
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitConstantGet(Send node, ConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitConstantInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(receiver, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(receiver, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg) {
- apply(receiver, arg);
- return null;
- }
-
- @override
- R visitIfNotNullDynamicPropertyGet(
- Send node, Node receiver, Name name, A arg) {
- apply(receiver, arg);
- return null;
- }
-
- @override
- R visitDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
- apply(receiver, arg);
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitIfNotNullDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
- apply(receiver, arg);
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- apply(receiver, arg);
- return null;
- }
-
- @override
- R visitIfNotNullDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- apply(receiver, arg);
- return null;
- }
-
- @override
- R visitDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- apply(receiver, arg);
- return null;
- }
-
- @override
- R visitIfNotNullDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- apply(receiver, arg);
- return null;
- }
-
- @override
- R visitDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg) {
- apply(receiver, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitIfNotNullDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg) {
- apply(receiver, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitDynamicTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitDynamicTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitEquals(Send node, Node left, Node right, A arg) {
- apply(left, arg);
- apply(right, arg);
- return null;
- }
-
- @override
- R visitExpressionInvoke(Send node, Node expression, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(expression, arg);
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitIndex(Send node, Node receiver, Node index, A arg) {
- apply(receiver, arg);
- apply(index, arg);
- return null;
- }
-
- @override
- R visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, A arg) {
- apply(receiver, arg);
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitIs(Send node, Node expression, ResolutionDartType type, A arg) {
- apply(expression, arg);
- return null;
- }
-
- @override
- R visitIsNot(Send node, Node expression, ResolutionDartType type, A arg) {
- apply(expression, arg);
- return null;
- }
-
- @override
- R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg) {
- return null;
- }
-
- @override
- R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitLocalFunctionIncompatibleInvoke(
- Send node,
- LocalFunctionElement function,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg) {
- return null;
- }
-
- @override
- R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitIfNull(Send node, Node left, Node right, A arg) {
- apply(left, arg);
- apply(right, arg);
- return null;
- }
-
- @override
- R visitLogicalAnd(Send node, Node left, Node right, A arg) {
- apply(left, arg);
- apply(right, arg);
- return null;
- }
-
- @override
- R visitLogicalOr(Send node, Node left, Node right, A arg) {
- apply(left, arg);
- apply(right, arg);
- return null;
- }
-
- @override
- R visitNot(Send node, Node expression, A arg) {
- apply(expression, arg);
- return null;
- }
-
- @override
- R visitNotEquals(Send node, Node left, Node right, A arg) {
- apply(left, arg);
- apply(right, arg);
- return null;
- }
-
- @override
- R visitParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitParameterGet(Send node, ParameterElement parameter, A arg) {
- return null;
- }
-
- @override
- R visitParameterInvoke(Send node, ParameterElement parameter,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticFieldGet(Send node, FieldElement field, A arg) {
- return null;
- }
-
- @override
- R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticFunctionGet(Send node, MethodElement function, A arg) {
- return null;
- }
-
- @override
- R visitStaticFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitStaticGetterGet(Send node, GetterElement getter, A arg) {
- return null;
- }
-
- @override
- R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitStaticGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
- Node argument, A arg) {
- apply(argument, arg);
- return null;
- }
-
- @override
- R visitSuperCompoundIndexSet(
- SendSet node,
- MethodElement getter,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperEquals(Send node, MethodElement function, Node argument, A arg) {
- apply(argument, arg);
- return null;
- }
-
- @override
- R visitSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperFieldGet(Send node, FieldElement field, A arg) {
- return null;
- }
-
- @override
- R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitSuperFieldPostfix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperFieldPrefix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperFieldSetterCompound(Send node, FieldElement field,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperGetterFieldCompound(Send node, GetterElement getter,
- FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperGetterGet(Send node, GetterElement getter, A arg) {
- return null;
- }
-
- @override
- R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitSuperGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperIndex(Send node, MethodElement function, Node index, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitSuperIndexSet(
- SendSet node, FunctionElement function, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperMethodGet(Send node, MethodElement method, A arg) {
- return null;
- }
-
- @override
- R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitSuperMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperNotEquals(
- Send node, MethodElement function, Node argument, A arg) {
- apply(argument, arg);
- return null;
- }
-
- @override
- R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperUnary(
- Send node, UnaryOperator operator, MethodElement function, A arg) {
- return null;
- }
-
- @override
- R visitThisGet(Identifier node, A arg) {
- return null;
- }
-
- @override
- R visitThisInvoke(
- Send node, NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitThisPropertyCompound(
- Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitThisPropertyGet(Send node, Name name, A arg) {
- return null;
- }
-
- @override
- R visitThisPropertyInvoke(
- Send node, NodeList arguments, Selector selector, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitThisPropertyPostfix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitThisPropertyPrefix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelFieldGet(Send node, FieldElement field, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelFunctionGet(Send node, MethodElement function, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTopLevelGetterGet(Send node, GetterElement getter, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelGetterInvoke(Send node, GetterElement getter,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelSetterSet(
- SendSet node, SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTypeVariableTypeLiteralGet(
- Send node, TypeVariableElement element, A arg) {
- return null;
- }
-
- @override
- R visitTypeVariableTypeLiteralInvoke(Send node, TypeVariableElement element,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTypeVariableTypeLiteralPostfix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTypeVariableTypeLiteralPrefix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTypedefTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTypedefTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnary(Send node, UnaryOperator operator, Node expression, A arg) {
- apply(expression, arg);
- return null;
- }
-
- @override
- R visitUnresolvedCompound(Send node, ErroneousElement element,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedGet(Send node, Element element, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedInvoke(Send node, Element element, NodeList arguments,
- Selector selector, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitUnresolvedPostfix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedPrefix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSet(SendSet node, Element element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R errorUndefinedBinaryExpression(
- Send node, Node left, Operator operator, Node right, A arg) {
- apply(left, arg);
- apply(right, arg);
- return null;
- }
-
- @override
- R errorUndefinedUnaryExpression(
- Send node, Operator operator, Node expression, A arg) {
- apply(expression, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperIndexSet(
- SendSet node, ErroneousElement element, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterCompoundIndexSet(
- SendSet node,
- Element element,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterCompoundIndexSet(
- SendSet node,
- MethodElement getter,
- Element element,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
- Node index, AssignmentOperator operator, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperBinary(Send node, Element element,
- BinaryOperator operator, Node argument, A arg) {
- apply(argument, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperUnary(
- Send node, UnaryOperator operator, Element element, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPostfix(SendSet node, MethodElement getter,
- Element element, Node index, IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperIndexPostfix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPrefix(SendSet node, MethodElement getter,
- Element element, Node index, IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperIndexPrefix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitIndexPostfix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- apply(receiver, arg);
- apply(index, arg);
- return null;
- }
-
- @override
- R visitIndexPrefix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- apply(receiver, arg);
- apply(index, arg);
- return null;
- }
-
- @override
- R visitSuperIndexPostfix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R visitSuperIndexPrefix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- apply(index, arg);
- return null;
- }
-
- @override
- R errorInvalidSetIfNull(Send node, ErroneousElement error, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitClassTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg) {
- apply(receiver, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitDynamicTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalStaticFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalSuperFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalTopLevelFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitIfNotNullDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg) {
- apply(receiver, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitLocalFunctionSetIfNull(
- Send node, LocalFunctionElement function, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticMethodSetterSetIfNull(
- Send node, MethodElement method, MethodElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
- FieldElement writtenField, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperFieldSetterSetIfNull(
- Send node, FieldElement field, SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperGetterFieldSetIfNull(
- Send node, GetterElement getter, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
- SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
- SetterElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTypeVariableTypeLiteralSetIfNull(
- Send node, TypeVariableElement element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitTypedefTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedStaticGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedStaticSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitConstConstructorInvoke(
- NewExpression node, ConstructedConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
- BoolFromEnvironmentConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitIntFromEnvironmentConstructorInvoke(NewExpression node,
- IntFromEnvironmentConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
- StringFromEnvironmentConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitConstructorIncompatibleInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitUnresolvedClassConstructorInvoke(
- NewExpression node,
- ErroneousElement constructor,
- ResolutionDartType type,
- NodeList arguments,
- Selector selector,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
- ResolutionDartType type, NodeList arguments, Selector selector, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- ConstructorElement effectiveTarget,
- ResolutionInterfaceType effectiveTargetType,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitRedirectingGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitAbstractClassConstructorInvoke(
- NewExpression node,
- ConstructorElement element,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitUnresolvedRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R errorNonConstantConstructorInvoke(
- NewExpression node,
- Element element,
- ResolutionDartType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitUnresolvedStaticGetterCompound(Send node, Element element,
- MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
- MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitStaticMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedStaticGetterPrefix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedStaticGetterPostfix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitStaticMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperFieldFieldCompound(Send node, FieldElement readField,
- FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitFinalSuperFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalSuperFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitSuperMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitFinalTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperCompound(Send node, Element element,
- AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperPostfix(
- SendSet node, Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSuperPrefix(
- SendSet node, Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return null;
- }
-
- @override
- R visitIndexSetIfNull(
- SendSet node, Node receiver, Node index, Node rhs, A arg) {
- apply(receiver, arg);
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
- MethodElement setter, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperGetterIndexSetIfNull(SendSet node, Element element,
- MethodElement setter, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperSetterIndexSetIfNull(SendSet node, MethodElement getter,
- Element element, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R visitUnresolvedSuperIndexSetIfNull(
- Send node, Element element, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-
- @override
- R errorInvalidIndexSetIfNull(
- SendSet node, ErroneousElement error, Node index, Node rhs, A arg) {
- apply(index, arg);
- apply(rhs, arg);
- return null;
- }
-}
-
-/// [SemanticDeclarationVisitor] that visits subnodes.
-class TraversalDeclarationMixin<R, A>
- implements SemanticDeclarationVisitor<R, A> {
- @override
- R apply(Node node, A arg) {
- throw new UnimplementedError("TraversalMixin.apply unimplemented");
- }
-
- @override
- applyInitializers(FunctionExpression constructor, A arg) {
- throw new UnimplementedError(
- "TraversalMixin.applyInitializers unimplemented");
- }
-
- @override
- applyParameters(NodeList parameters, A arg) {
- throw new UnimplementedError(
- "TraversalMixin.applyParameters unimplemented");
- }
-
- @override
- R visitAbstractMethodDeclaration(FunctionExpression node,
- MethodElement method, NodeList parameters, A arg) {
- applyParameters(parameters, arg);
- return null;
- }
-
- @override
- R visitClosureDeclaration(FunctionExpression node,
- LocalFunctionElement function, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitFactoryConstructorDeclaration(FunctionExpression node,
- ConstructorElement constructor, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitFieldInitializer(
- SendSet node, FieldElement field, Node initializer, A arg) {
- apply(initializer, arg);
- return null;
- }
-
- @override
- R visitGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- Node body,
- A arg) {
- applyParameters(parameters, arg);
- applyInitializers(node, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitInstanceMethodDeclaration(FunctionExpression node,
- MethodElement method, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitLocalFunctionDeclaration(FunctionExpression node,
- LocalFunctionElement function, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitRedirectingFactoryConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- ResolutionInterfaceType redirectionType,
- ConstructorElement redirectionTarget,
- A arg) {
- applyParameters(parameters, arg);
- return null;
- }
-
- @override
- R visitRedirectingGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- A arg) {
- applyParameters(parameters, arg);
- applyInitializers(node, arg);
- return null;
- }
-
- @override
- R visitStaticFunctionDeclaration(FunctionExpression node,
- MethodElement function, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitSuperConstructorInvoke(
- Send node,
- ConstructorElement superConstructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitImplicitSuperConstructorInvoke(
- FunctionExpression node,
- ConstructorElement superConstructor,
- ResolutionInterfaceType type,
- A arg) {
- return null;
- }
-
- @override
- R visitThisConstructorInvoke(Send node, ConstructorElement thisConstructor,
- NodeList arguments, CallStructure callStructure, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitTopLevelFunctionDeclaration(FunctionExpression node,
- MethodElement function, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R errorUnresolvedFieldInitializer(
- SendSet node, Element element, Node initializer, A arg) {
- apply(initializer, arg);
- return null;
- }
-
- @override
- R errorUnresolvedSuperConstructorInvoke(Send node, Element element,
- NodeList arguments, Selector selector, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R errorUnresolvedThisConstructorInvoke(Send node, Element element,
- NodeList arguments, Selector selector, A arg) {
- apply(arguments, arg);
- return null;
- }
-
- @override
- R visitLocalVariableDeclaration(VariableDefinitions node, Node definition,
- LocalVariableElement variable, Node initializer, A arg) {
- if (initializer != null) {
- apply(initializer, arg);
- }
- return null;
- }
-
- @override
- R visitOptionalParameterDeclaration(
- VariableDefinitions node,
- Node definition,
- ParameterElement parameter,
- ConstantExpression defaultValue,
- int index,
- A arg) {
- return null;
- }
-
- @override
- R visitParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, int index, A arg) {
- return null;
- }
-
- @override
- R visitInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement initializingFormal,
- int index,
- A arg) {
- return null;
- }
-
- @override
- R visitLocalConstantDeclaration(VariableDefinitions node, Node definition,
- LocalVariableElement variable, ConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitNamedInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement initializingFormal,
- ConstantExpression defaultValue,
- A arg) {
- return null;
- }
-
- @override
- R visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
- ParameterElement parameter, ConstantExpression defaultValue, A arg) {
- return null;
- }
-
- @override
- R visitOptionalInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement initializingFormal,
- ConstantExpression defaultValue,
- int index,
- A arg) {
- return null;
- }
-
- @override
- R visitInstanceFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg) {
- if (initializer != null) {
- apply(initializer, arg);
- }
- return null;
- }
-
- @override
- R visitStaticConstantDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, ConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitStaticFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg) {
- if (initializer != null) {
- apply(initializer, arg);
- }
- return null;
- }
-
- @override
- R visitTopLevelConstantDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, ConstantExpression constant, A arg) {
- return null;
- }
-
- @override
- R visitTopLevelFieldDeclaration(VariableDefinitions node, Node definition,
- FieldElement field, Node initializer, A arg) {
- if (initializer != null) {
- apply(initializer, arg);
- }
- return null;
- }
-
- @override
- R visitAbstractGetterDeclaration(
- FunctionExpression node, GetterElement getter, A arg) {
- return null;
- }
-
- @override
- R visitAbstractSetterDeclaration(FunctionExpression node,
- MethodElement setter, NodeList parameters, A arg) {
- applyParameters(parameters, arg);
- return null;
- }
-
- @override
- R visitInstanceGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg) {
- apply(body, arg);
- return null;
- }
-
- @override
- R visitInstanceSetterDeclaration(FunctionExpression node,
- MethodElement setter, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitStaticGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg) {
- apply(body, arg);
- return null;
- }
-
- @override
- R visitStaticSetterDeclaration(FunctionExpression node, MethodElement setter,
- NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-
- @override
- R visitTopLevelGetterDeclaration(
- FunctionExpression node, GetterElement getter, Node body, A arg) {
- apply(body, arg);
- return null;
- }
-
- @override
- R visitTopLevelSetterDeclaration(FunctionExpression node,
- MethodElement setter, NodeList parameters, Node body, A arg) {
- applyParameters(parameters, arg);
- apply(body, arg);
- return null;
- }
-}
-
-/// AST visitor that visits all normal [Send] and [SendSet] nodes using the
-/// [SemanticVisitor].
-class TraversalVisitor<R, A> extends SemanticVisitor<R, A>
- with TraversalSendMixin<R, A>, TraversalDeclarationMixin<R, A> {
- TraversalVisitor(TreeElements elements) : super(elements);
-
- SemanticSendVisitor<R, A> get sendVisitor => this;
-
- SemanticDeclarationVisitor<R, A> get declVisitor => this;
-
- R apply(Node node, A arg) {
- node.accept(this);
- return null;
- }
-
- @override
- applyInitializers(FunctionExpression constructor, A arg) {
- visitInitializers(constructor, arg);
- }
-
- @override
- applyParameters(NodeList parameters, A arg) {
- visitParameters(parameters, arg);
- }
-
- @override
- internalError(Spannable spannable, String message) {
- failedAt(spannable, message);
- }
-
- @override
- R visitNode(Node node) {
- node.visitChildren(this);
- return null;
- }
-
- @override
- R visitTypeAnnotation(TypeAnnotation node) {
- // Skip [Send] contained in type annotations, like `prefix.Type`.
- return null;
- }
-}
-
-/// Mixin that groups all non-compound `visitStaticX` and `visitTopLevelX`
-/// method by delegating calls to `handleStaticX` methods.
-///
-/// This mixin is useful for the cases where both top level members and static
-/// class members are handled uniformly.
-abstract class BaseImplementationOfStaticsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleStaticFieldGet(Send node, FieldElement field, A arg);
-
- R handleStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg);
-
- R handleStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
- R handleStaticFunctionGet(Send node, MethodElement function, A arg);
-
- R handleStaticFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg);
-
- R handleStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg);
-
- R handleStaticGetterGet(Send node, GetterElement getter, A arg);
-
- R handleStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
- R handleStaticGetterInvoke(Send node, GetterElement getter,
- NodeList arguments, CallStructure callStructure, A arg);
-
- R handleStaticSetterGet(SendSet node, SetterElement setter, A arg);
-
- R handleStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
- R handleStaticSetterInvoke(Send node, SetterElement setter,
- NodeList arguments, CallStructure callStructure, A arg);
-
- R handleFinalStaticFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg);
-
- R handleStaticFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg);
-
- @override
- R visitStaticFieldGet(Send node, FieldElement field, A arg) {
- return handleStaticFieldGet(node, field, arg);
- }
-
- @override
- R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- return handleStaticFieldInvoke(node, field, arguments, callStructure, arg);
- }
-
- @override
- R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- return handleStaticFieldSet(node, field, rhs, arg);
- }
-
- @override
- R visitStaticFunctionGet(Send node, MethodElement function, A arg) {
- return handleStaticFunctionGet(node, function, arg);
- }
-
- @override
- R visitStaticFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleStaticFunctionInvoke(
- node, function, arguments, callStructure, arg);
- }
-
- @override
- R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleStaticFunctionIncompatibleInvoke(
- node, function, arguments, callStructure, arg);
- }
-
- @override
- R visitStaticGetterGet(Send node, GetterElement getter, A arg) {
- return handleStaticGetterGet(node, getter, arg);
- }
-
- @override
- R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
- CallStructure callStructure, A arg) {
- return handleStaticGetterInvoke(
- node, getter, arguments, callStructure, arg);
- }
-
- @override
- R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
- return handleStaticSetterSet(node, setter, rhs, arg);
- }
-
- @override
- R visitTopLevelFieldGet(Send node, FieldElement field, A arg) {
- return handleStaticFieldGet(node, field, arg);
- }
-
- @override
- R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
- CallStructure callStructure, A arg) {
- return handleStaticFieldInvoke(node, field, arguments, callStructure, arg);
- }
-
- @override
- R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
- return handleStaticFieldSet(node, field, rhs, arg);
- }
-
- @override
- R visitTopLevelFunctionGet(Send node, MethodElement function, A arg) {
- return handleStaticFunctionGet(node, function, arg);
- }
-
- @override
- R visitTopLevelFunctionInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleStaticFunctionInvoke(
- node, function, arguments, callStructure, arg);
- }
-
- @override
- R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleStaticFunctionIncompatibleInvoke(
- node, function, arguments, callStructure, arg);
- }
-
- @override
- R visitTopLevelGetterGet(Send node, GetterElement getter, A arg) {
- return handleStaticGetterGet(node, getter, arg);
- }
-
- @override
- R visitTopLevelGetterSet(
- SendSet node, GetterElement getter, Node rhs, A arg) {
- return handleStaticGetterSet(node, getter, rhs, arg);
- }
-
- @override
- R visitTopLevelGetterInvoke(Send node, GetterElement getter,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleStaticGetterInvoke(
- node, getter, arguments, callStructure, arg);
- }
-
- @override
- R visitTopLevelSetterSet(
- SendSet node, SetterElement setter, Node rhs, A arg) {
- return handleStaticSetterSet(node, setter, rhs, arg);
- }
-
- @override
- R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
- CallStructure callStructure, A arg) {
- return handleStaticSetterInvoke(
- node, setter, arguments, callStructure, arg);
- }
-
- @override
- R visitTopLevelSetterInvoke(Send node, SetterElement setter,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleStaticSetterInvoke(
- node, setter, arguments, callStructure, arg);
- }
-
- @override
- R visitStaticSetterGet(Send node, SetterElement setter, A arg) {
- return handleStaticSetterGet(node, setter, arg);
- }
-
- @override
- R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
- return handleStaticGetterSet(node, getter, rhs, arg);
- }
-
- @override
- R visitTopLevelSetterGet(Send node, SetterElement setter, A arg) {
- return handleStaticSetterGet(node, setter, arg);
- }
-
- @override
- R visitFinalStaticFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg) {
- return handleFinalStaticFieldSet(node, field, rhs, arg);
- }
-
- @override
- R visitFinalTopLevelFieldSet(
- SendSet node, FieldElement field, Node rhs, A arg) {
- return handleFinalStaticFieldSet(node, field, rhs, arg);
- }
-
- @override
- R visitStaticFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg) {
- return handleStaticFunctionSet(node, function, rhs, arg);
- }
-
- @override
- R visitTopLevelFunctionSet(
- SendSet node, MethodElement function, Node rhs, A arg) {
- return handleStaticFunctionSet(node, function, rhs, arg);
- }
-}
-
-/// Mixin that groups all compounds visitors `visitStaticX` and `visitTopLevelX`
-/// method by delegating calls to `handleStaticX` methods.
-///
-/// This mixin is useful for the cases where both top level members and static
-/// class members are handled uniformly.
-abstract class BaseImplementationOfStaticCompoundsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- R handleStaticFieldPostfixPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleStaticGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- R handleStaticGetterSetterPostfixPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleStaticMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- R handleStaticMethodSetterPostfixPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleFinalStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg);
-
- R handleFinalStaticFieldPostfixPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleStaticMethodCompound(Send node, FunctionElement method,
- AssignmentOperator operator, Node rhs, A arg);
-
- R handleStaticMethodPostfixPrefix(
- Send node, FunctionElement method, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleUnresolvedStaticGetterCompound(Send node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
- R handleUnresolvedStaticGetterPostfixPrefix(Send node, Element element,
- SetterElement setter, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleUnresolvedStaticSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg);
-
- R handleUnresolvedStaticSetterPostfixPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- @override
- R visitStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticFieldCompound(node, field, operator, rhs, arg);
- }
-
- @override
- R visitStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitStaticGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticGetterSetterCompound(
- node, getter, setter, operator, rhs, arg);
- }
-
- @override
- R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticGetterSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticGetterSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitStaticMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticMethodSetterCompound(
- node, method, setter, operator, rhs, arg);
- }
-
- @override
- R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticMethodSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticMethodSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticFieldCompound(node, field, operator, rhs, arg);
- }
-
- @override
- R visitTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticGetterSetterCompound(
- node, getter, setter, operator, rhs, arg);
- }
-
- @override
- R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticGetterSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticGetterSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticMethodSetterCompound(
- node, method, setter, operator, rhs, arg);
- }
-
- @override
- R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticMethodSetterPostfixPrefix(
- node, method, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticMethodSetterPostfixPrefix(
- node, method, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitFinalStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleFinalStaticFieldCompound(node, field, operator, rhs, arg);
- }
-
- @override
- R visitFinalStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleFinalStaticFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitFinalStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleFinalStaticFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitStaticMethodCompound(Send node, FunctionElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticMethodCompound(node, method, operator, rhs, arg);
- }
-
- @override
- R visitStaticMethodPostfix(
- Send node, FunctionElement method, IncDecOperator operator, A arg) {
- return handleStaticMethodPostfixPrefix(node, method, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitStaticMethodPrefix(
- Send node, FunctionElement method, IncDecOperator operator, A arg) {
- return handleStaticMethodPostfixPrefix(node, method, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedStaticGetterCompound(Send node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleUnresolvedStaticGetterCompound(
- node, element, setter, operator, rhs, arg);
- }
-
- @override
- R visitUnresolvedStaticGetterPostfix(Send node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleUnresolvedStaticGetterPostfixPrefix(
- node, element, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedStaticGetterPrefix(Send node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleUnresolvedStaticGetterPostfixPrefix(
- node, element, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- return handleUnresolvedStaticSetterCompound(
- node, getter, element, operator, rhs, arg);
- }
-
- @override
- R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleUnresolvedStaticSetterPostfixPrefix(
- node, getter, element, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleUnresolvedStaticSetterPostfixPrefix(
- node, getter, element, operator, arg,
- isPrefix: true);
- }
-}
-
-/// Mixin that groups all non-compound `visitLocalX` and `visitParameterX`
-/// methods by delegating calls to `handleLocalX` methods.
-///
-/// This mixin is useful for the cases where both parameters, local variables,
-/// and local functions, captured or not, are handled uniformly.
-abstract class BaseImplementationOfLocalsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleLocalGet(Send node, LocalElement element, A arg);
-
- R handleLocalInvoke(Send node, LocalElement element, NodeList arguments,
- CallStructure callStructure, A arg);
-
- R handleLocalSet(SendSet node, LocalElement element, Node rhs, A arg);
-
- R handleImmutableLocalSet(
- SendSet node, LocalElement element, Node rhs, A arg);
-
- @override
- R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg) {
- return handleLocalGet(node, function, arg);
- }
-
- @override
- R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleLocalInvoke(node, function, arguments, callStructure, arg);
- }
-
- @override
- R visitLocalFunctionIncompatibleInvoke(
- Send node,
- LocalFunctionElement function,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return handleLocalInvoke(node, function, arguments, callStructure, arg);
- }
-
- @override
- R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg) {
- return handleLocalGet(node, variable, arg);
- }
-
- @override
- R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleLocalInvoke(node, variable, arguments, callStructure, arg);
- }
-
- @override
- R visitLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg) {
- return handleLocalSet(node, variable, rhs, arg);
- }
-
- @override
- R visitParameterGet(Send node, ParameterElement parameter, A arg) {
- return handleLocalGet(node, parameter, arg);
- }
-
- @override
- R visitParameterInvoke(Send node, ParameterElement parameter,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleLocalInvoke(node, parameter, arguments, callStructure, arg);
- }
-
- @override
- R visitParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg) {
- return handleLocalSet(node, parameter, rhs, arg);
- }
-
- @override
- R visitFinalLocalVariableSet(
- SendSet node, LocalVariableElement variable, Node rhs, A arg) {
- return handleImmutableLocalSet(node, variable, rhs, arg);
- }
-
- @override
- R visitFinalParameterSet(
- SendSet node, ParameterElement parameter, Node rhs, A arg) {
- return handleImmutableLocalSet(node, parameter, rhs, arg);
- }
-
- @override
- R visitLocalFunctionSet(
- SendSet node, LocalFunctionElement function, Node rhs, A arg) {
- return handleImmutableLocalSet(node, function, rhs, arg);
- }
-}
-
-/// Mixin that groups all compound `visitLocalX` and `visitParameterX` methods
-/// by delegating calls to `handleLocalX` methods.
-///
-/// This mixin is useful for the cases where both parameters, local variables,
-/// and local functions, captured or not, are handled uniformly.
-abstract class BaseImplementationOfLocalCompoundsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleLocalCompound(Send node, LocalElement element,
- AssignmentOperator operator, Node rhs, A arg);
-
- R handleLocalPostfixPrefix(
- Send node, LocalElement element, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- @override
- R visitLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleLocalCompound(node, variable, operator, rhs, arg);
- }
-
- @override
- R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return handleLocalPostfixPrefix(node, variable, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return handleLocalPostfixPrefix(node, variable, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleLocalCompound(node, parameter, operator, rhs, arg);
- }
-
- @override
- R visitParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return handleLocalPostfixPrefix(node, parameter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return handleLocalPostfixPrefix(node, parameter, operator, arg,
- isPrefix: true);
- }
-}
-
-/// Mixin that groups all `visitConstantX` and `visitXTypeLiteralY` methods for
-/// constant type literals by delegating calls to `handleConstantX` methods.
-///
-/// This mixin is useful for the cases where expressions on constants are
-/// handled uniformly.
-abstract class BaseImplementationOfConstantsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleConstantGet(Node node, ConstantExpression constant, A arg);
-
- R handleConstantInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg);
-
- @override
- R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleConstantInvoke(node, constant, arguments, callStructure, arg);
- }
-
- @override
- R visitConstConstructorInvoke(
- NewExpression node, ConstructedConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
- BoolFromEnvironmentConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitIntFromEnvironmentConstructorInvoke(NewExpression node,
- IntFromEnvironmentConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
- StringFromEnvironmentConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitConstantGet(Send node, ConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitConstantInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleConstantInvoke(node, constant, arguments, callStructure, arg);
- }
-
- @override
- R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleConstantInvoke(node, constant, arguments, callStructure, arg);
- }
-
- @override
- R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
- return handleConstantGet(node, constant, arg);
- }
-
- @override
- R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
- NodeList arguments, CallStructure callStructure, A arg) {
- return handleConstantInvoke(node, constant, arguments, callStructure, arg);
- }
-}
-
-/// Mixin that groups all non-compound `visitDynamicPropertyX` and
-/// `visitThisPropertyY` methods for by delegating calls to `handleDynamicX`
-/// methods, providing `null` as the receiver for the this properties.
-///
-/// This mixin is useful for the cases where dynamic and this properties are
-/// handled uniformly.
-abstract class BaseImplementationOfDynamicsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleDynamicGet(Send node, Node receiver, Name name, A arg);
-
- R handleDynamicInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg);
-
- R handleDynamicSet(SendSet node, Node receiver, Name name, Node rhs, A arg);
-
- @override
- R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg) {
- return handleDynamicGet(node, receiver, name, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyGet(
- Send node, Node receiver, Name name, A arg) {
- // TODO(johnniwinther): should these redirect to handleDynamicX?
- return handleDynamicGet(node, receiver, name, arg);
- }
-
- @override
- R visitDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
- return handleDynamicInvoke(node, receiver, arguments, selector, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyInvoke(
- Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
- return handleDynamicInvoke(node, receiver, arguments, selector, arg);
- }
-
- @override
- R visitDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg) {
- return handleDynamicSet(node, receiver, name, rhs, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertySet(
- SendSet node, Node receiver, Name name, Node rhs, A arg) {
- return handleDynamicSet(node, receiver, name, rhs, arg);
- }
-
- @override
- R visitThisPropertyGet(Send node, Name name, A arg) {
- return handleDynamicGet(node, null, name, arg);
- }
-
- @override
- R visitThisPropertyInvoke(
- Send node, NodeList arguments, Selector selector, A arg) {
- return handleDynamicInvoke(node, null, arguments, selector, arg);
- }
-
- @override
- R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg) {
- return handleDynamicSet(node, null, name, rhs, arg);
- }
-}
-
-/// Mixin that groups all compounds of `visitDynamicPropertyX` and
-/// `visitThisPropertyY` methods for by delegating calls to `handleDynamicX`
-/// methods, providing `null` as the receiver for the this properties.
-///
-/// This mixin is useful for the cases where dynamic and this properties are
-/// handled uniformly.
-abstract class BaseImplementationOfDynamicCompoundsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleDynamicCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg);
-
- R handleDynamicPostfixPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleDynamicIndexPostfixPrefix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- @override
- R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleDynamicCompound(node, receiver, name, operator, rhs, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleDynamicCompound(node, receiver, name, operator, rhs, arg);
- }
-
- @override
- R visitDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitIfNotNullDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitIfNotNullDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitThisPropertyCompound(
- Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
- return handleDynamicCompound(node, null, name, operator, rhs, arg);
- }
-
- @override
- R visitThisPropertyPostfix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return handleDynamicPostfixPrefix(node, null, name, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitThisPropertyPrefix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return handleDynamicPostfixPrefix(node, null, name, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitIndexPostfix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- return handleDynamicIndexPostfixPrefix(node, receiver, index, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitIndexPrefix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- return handleDynamicIndexPostfixPrefix(node, receiver, index, operator, arg,
- isPrefix: true);
- }
-}
-
-/// The getter kind for statically resolved compound expressions.
-enum CompoundGetter {
- /// The compound reads from a field.
- FIELD,
-
- /// The compound reads from a getter.
- GETTER,
-
- /// The compound reads (closurizes) a method.
- METHOD,
-
- /// The getter is unresolved. The accompanied element is an erroneous element.
- UNRESOLVED,
-}
-
-/// The setter kind for statically resolved compound expressions.
-enum CompoundSetter {
- /// The compound writes to a field.
- FIELD,
-
- /// The compound writes to a setter.
- SETTER,
-
- /// The setter is unresolved or unassignable. The accompanied element may be
- /// `null`, and erroneous element, or the unassignable element.
- INVALID,
-}
-
-/// The kind of a [CompoundRhs].
-enum CompoundKind {
- /// A prefix expression, like `--a`.
- PREFIX,
-
- /// A postfix expression, like `a++`.
- POSTFIX,
-
- /// A compound assignment, like `a *= b`.
- ASSIGNMENT,
-}
-
-/// The right-hand side of a compound expression.
-abstract class CompoundRhs {
- /// The kind of compound.
- CompoundKind get kind;
-
- /// The binary operator implied by the compound operator.
- BinaryOperator get operator;
-
- /// The explicit right hand side in case of a compound assignment, `null`
- /// otherwise.
- Node get rhs;
-}
-
-/// A prefix or postfix of [incDecOperator].
-class IncDecCompound implements CompoundRhs {
- final CompoundKind kind;
- final IncDecOperator incDecOperator;
-
- IncDecCompound(this.kind, this.incDecOperator);
-
- BinaryOperator get operator => incDecOperator.binaryOperator;
-
- Node get rhs => null;
-}
-
-/// A compound assignment with [assignmentOperator] and [rhs].
-class AssignmentCompound implements CompoundRhs {
- final AssignmentOperator assignmentOperator;
- final Node rhs;
-
- AssignmentCompound(this.assignmentOperator, this.rhs);
-
- CompoundKind get kind => CompoundKind.ASSIGNMENT;
-
- BinaryOperator get operator => assignmentOperator.binaryOperator;
-}
-
-/// Simplified handling of compound assignments and prefix/postfix expressions.
-abstract class BaseImplementationOfCompoundsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- /// Handle a super compounds, like `super.foo += 42` or `--super.bar`.
- R handleSuperCompounds(
- SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- CompoundRhs rhs,
- A arg);
-
- /// Handle a static or top level compounds, like `foo += 42` or `--bar`.
- R handleStaticCompounds(
- SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- CompoundRhs rhs,
- A arg);
-
- /// Handle a local compounds, like `foo += 42` or `--bar`. If [isSetterValid]
- /// is false [local] is unassignable.
- R handleLocalCompounds(
- SendSet node, LocalElement local, CompoundRhs rhs, A arg,
- {bool isSetterValid});
-
- /// Handle a compounds on a type literal constant, like `Object += 42` or
- /// `--Object`.
- R handleTypeLiteralConstantCompounds(
- SendSet node, ConstantExpression constant, CompoundRhs rhs, A arg);
-
- /// Handle a compounds on a type variable type literal, like `T += 42` or
- /// `--T`.
- R handleTypeVariableTypeLiteralCompounds(
- SendSet node, TypeVariableElement typeVariable, CompoundRhs rhs, A arg);
-
- /// Handle a dynamic compounds, like `o.foo += 42` or `--o.foo`. [receiver] is
- /// `null` for properties on `this`, like `--this.foo` or `--foo`.
- R handleDynamicCompounds(
- Send node, Node receiver, Name name, CompoundRhs rhs, A arg);
-
- R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleDynamicCompounds(
- node, receiver, name, new AssignmentCompound(operator, rhs), arg);
- }
-
- R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleDynamicCompounds(
- node, receiver, name, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitThisPropertyCompound(
- Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
- return handleDynamicCompounds(
- node, null, name, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleLocalCompounds(
- node, parameter, new AssignmentCompound(operator, rhs), arg,
- isSetterValid: true);
- }
-
- @override
- R visitFinalParameterCompound(Send node, ParameterElement parameter,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleLocalCompounds(
- node, parameter, new AssignmentCompound(operator, rhs), arg,
- isSetterValid: false);
- }
-
- @override
- R visitLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleLocalCompounds(
- node, variable, new AssignmentCompound(operator, rhs), arg,
- isSetterValid: true);
- }
-
- @override
- R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleLocalCompounds(
- node, variable, new AssignmentCompound(operator, rhs), arg,
- isSetterValid: false);
- }
-
- @override
- R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleLocalCompounds(
- node, function, new AssignmentCompound(operator, rhs), arg,
- isSetterValid: false);
- }
-
- @override
- R visitStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitFinalStaticFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, field, CompoundGetter.FIELD, null,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitStaticGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, getter, CompoundGetter.GETTER, setter,
- CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitStaticMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, method, CompoundGetter.METHOD, setter,
- CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, field, CompoundGetter.FIELD, null,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, getter, CompoundGetter.GETTER, setter,
- CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, method, CompoundGetter.METHOD, setter,
- CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitFinalSuperFieldCompound(Send node, FieldElement field,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitSuperGetterSetterCompound(Send node, GetterElement getter,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, getter, CompoundGetter.GETTER, setter,
- CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitSuperMethodSetterCompound(Send node, FunctionElement method,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, method, CompoundGetter.METHOD, setter,
- CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitSuperFieldSetterCompound(Send node, FieldElement field,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, field, CompoundGetter.FIELD, setter,
- CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitSuperGetterFieldCompound(Send node, GetterElement getter,
- FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, getter, CompoundGetter.GETTER, field,
- CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleTypeLiteralConstantCompounds(
- node, constant, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleTypeLiteralConstantCompounds(
- node, constant, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleTypeVariableTypeLiteralCompounds(
- node, element, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleTypeLiteralConstantCompounds(
- node, constant, new AssignmentCompound(operator, rhs), arg);
- }
-
- R visitDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicCompounds(node, receiver, name,
- new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-
- R visitIfNotNullDynamicPropertyPrefix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicCompounds(node, receiver, name,
- new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-
- @override
- R visitParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, parameter, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isSetterValid: true);
- }
-
- @override
- R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, variable, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isSetterValid: true);
- }
-
- @override
- R visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
- IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, function, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isSetterValid: false);
- }
-
- R visitThisPropertyPrefix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return handleDynamicCompounds(node, null, name,
- new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-
- @override
- R visitStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.METHOD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperFieldPrefix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- readField,
- CompoundGetter.FIELD,
- writtenField,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitClassTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return handleTypeLiteralConstantCompounds(
- node, constant, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-
- @override
- R visitTypedefTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return handleTypeLiteralConstantCompounds(
- node, constant, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralPrefix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
- return handleTypeVariableTypeLiteralCompounds(
- node, element, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-
- @override
- R visitDynamicTypeLiteralPrefix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return handleTypeLiteralConstantCompounds(
- node, constant, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-
- @override
- R visitDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicCompounds(node, receiver, name,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertyPostfix(
- Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
- return handleDynamicCompounds(node, receiver, name,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return handleLocalCompounds(node, parameter,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isSetterValid: true);
- }
-
- @override
- R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, variable, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isSetterValid: true);
- }
-
- @override
- R visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
- IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, function, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isSetterValid: false);
- }
-
- R visitThisPropertyPostfix(
- Send node, Name name, IncDecOperator operator, A arg) {
- return handleDynamicCompounds(node, null, name,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.METHOD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitSuperFieldPostfix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- readField,
- CompoundGetter.FIELD,
- writtenField,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- field,
- CompoundSetter.FIELD,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitClassTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return handleTypeLiteralConstantCompounds(node, constant,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitTypedefTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return handleTypeLiteralConstantCompounds(node, constant,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitTypeVariableTypeLiteralPostfix(
- Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
- return handleTypeVariableTypeLiteralCompounds(
- node, element, new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitDynamicTypeLiteralPostfix(
- Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
- return handleTypeLiteralConstantCompounds(node, constant,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitUnresolvedStaticGetterPostfix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitStaticMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- method,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- method,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedPostfix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedStaticGetterPrefix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitStaticMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- method,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitTopLevelMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- method,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedPrefix(
- Send node, ErroneousElement element, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedStaticGetterCompound(Send node, Element element,
- MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new AssignmentCompound(operator, rhs),
- arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
- MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new AssignmentCompound(operator, rhs),
- arg);
- }
-
- @override
- R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, getter, CompoundGetter.GETTER, element,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, getter, CompoundGetter.GETTER, element,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitStaticMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, method, CompoundGetter.METHOD, method,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitTopLevelMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(node, method, CompoundGetter.METHOD, method,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitUnresolvedCompound(Send node, ErroneousElement element,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleStaticCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- element,
- CompoundSetter.INVALID,
- new AssignmentCompound(operator, rhs),
- arg);
- }
-
- @override
- R visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, variable, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isSetterValid: false);
- }
-
- @override
- R visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
- IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, variable, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isSetterValid: false);
- }
-
- @override
- R visitFinalParameterPostfix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return handleLocalCompounds(node, parameter,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isSetterValid: false);
- }
-
- @override
- R visitFinalParameterPrefix(
- Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
- return handleLocalCompounds(
- node, parameter, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isSetterValid: false);
- }
-
- @override
- R visitFinalStaticFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitFinalStaticFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperFieldFieldCompound(Send node, FieldElement readField,
- FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(
- node,
- readField,
- CompoundGetter.FIELD,
- writtenField,
- CompoundSetter.FIELD,
- new AssignmentCompound(operator, rhs),
- arg);
- }
-
- @override
- R visitFinalSuperFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitFinalSuperFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitSuperMethodCompound(Send node, MethodElement method,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, method, CompoundGetter.METHOD, method,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitSuperMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- method,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitSuperMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- method,
- CompoundGetter.METHOD,
- method,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitFinalTopLevelFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitFinalTopLevelFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleStaticCompounds(
- node,
- field,
- CompoundGetter.FIELD,
- field,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedSuperCompound(Send node, Element element,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- element,
- CompoundSetter.INVALID,
- new AssignmentCompound(operator, rhs),
- arg);
- }
-
- @override
- R visitUnresolvedSuperPostfix(
- SendSet node, Element element, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedSuperPrefix(
- SendSet node, Element element, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
- SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new AssignmentCompound(operator, rhs),
- arg);
- }
-
- @override
- R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- element,
- CompoundGetter.UNRESOLVED,
- setter,
- CompoundSetter.SETTER,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
- Element element, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperCompounds(node, getter, CompoundGetter.GETTER, element,
- CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.POSTFIX, operator),
- arg);
- }
-
- @override
- R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleSuperCompounds(
- node,
- getter,
- CompoundGetter.GETTER,
- element,
- CompoundSetter.INVALID,
- new IncDecCompound(CompoundKind.PREFIX, operator),
- arg);
- }
-}
-
-/// Simplified handling of if-null assignments.
-abstract class BaseImplementationOfSetIfNullsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- /// Handle a super if-null assignments, like `super.foo ??= 42`.
- R handleSuperSetIfNulls(
- SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- Node rhs,
- A arg);
-
- /// Handle a static or top level if-null assignments, like `foo ??= 42`.
- R handleStaticSetIfNulls(
- SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- Node rhs,
- A arg);
-
- /// Handle a local if-null assignments, like `foo ??= 42`. If [isSetterValid]
- /// is false [local] is unassignable.
- R handleLocalSetIfNulls(SendSet node, LocalElement local, Node rhs, A arg,
- {bool isSetterValid});
-
- /// Handle a if-null assignments on a type literal constant, like
- /// `Object ??= 42`.
- R handleTypeLiteralConstantSetIfNulls(
- SendSet node, ConstantExpression constant, Node rhs, A arg);
-
- /// Handle a dynamic if-null assignments, like `o.foo ??= 42`. [receiver] is
- /// `null` for properties on `this`, like `this.foo ??= 42` or `foo ??= 42`.
- R handleDynamicSetIfNulls(
- Send node, Node receiver, Name name, Node rhs, A arg);
-
- @override
- R visitClassTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- return handleTypeLiteralConstantSetIfNulls(node, constant, rhs, arg);
- }
-
- @override
- R visitDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg) {
- return handleDynamicSetIfNulls(node, receiver, name, rhs, arg);
- }
-
- @override
- R visitDynamicTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- return handleTypeLiteralConstantSetIfNulls(node, constant, rhs, arg);
- }
-
- @override
- R visitFinalLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg) {
- return handleLocalSetIfNulls(node, variable, rhs, arg,
- isSetterValid: false);
- }
-
- @override
- R visitFinalParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg) {
- return handleLocalSetIfNulls(node, parameter, rhs, arg,
- isSetterValid: false);
- }
-
- @override
- R visitFinalStaticFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitFinalSuperFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitFinalTopLevelFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitIfNotNullDynamicPropertySetIfNull(
- Send node, Node receiver, Name name, Node rhs, A arg) {
- return handleDynamicSetIfNulls(node, receiver, name, rhs, arg);
- }
-
- @override
- R visitLocalFunctionSetIfNull(
- Send node, LocalFunctionElement function, Node rhs, A arg) {
- return handleLocalSetIfNulls(node, function, rhs, arg,
- isSetterValid: false);
- }
-
- @override
- R visitLocalVariableSetIfNull(
- Send node, LocalVariableElement variable, Node rhs, A arg) {
- return handleLocalSetIfNulls(node, variable, rhs, arg, isSetterValid: true);
- }
-
- @override
- R visitParameterSetIfNull(
- Send node, ParameterElement parameter, Node rhs, A arg) {
- return handleLocalSetIfNulls(node, parameter, rhs, arg,
- isSetterValid: true);
- }
-
- @override
- R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.FIELD, rhs, arg);
- }
-
- @override
- R visitStaticGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, setter,
- CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitStaticMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, method,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitStaticMethodSetterSetIfNull(
- Send node, MethodElement method, MethodElement setter, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, setter,
- CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
- FieldElement writtenField, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, readField, CompoundGetter.FIELD,
- writtenField, CompoundSetter.FIELD, rhs, arg);
- }
-
- @override
- R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.FIELD, rhs, arg);
- }
-
- @override
- R visitSuperFieldSetterSetIfNull(
- Send node, FieldElement field, SetterElement setter, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, field, CompoundGetter.FIELD, setter,
- CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitSuperGetterFieldSetIfNull(
- Send node, GetterElement getter, FieldElement field, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, getter, CompoundGetter.GETTER, field,
- CompoundSetter.FIELD, rhs, arg);
- }
-
- @override
- R visitSuperGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, getter, CompoundGetter.GETTER, setter,
- CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitSuperMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, method, CompoundGetter.METHOD, method,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
- SetterElement setter, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, method, CompoundGetter.METHOD, setter,
- CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg) {
- return handleDynamicSetIfNulls(node, null, name, rhs, arg);
- }
-
- @override
- R visitTopLevelFieldSetIfNull(
- Send node, FieldElement field, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
- CompoundSetter.FIELD, rhs, arg);
- }
-
- @override
- R visitTopLevelGetterSetterSetIfNull(
- Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, setter,
- CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitTopLevelMethodSetIfNull(
- Send node, FunctionElement method, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, method,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
- SetterElement setter, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, setter,
- CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitTypedefTypeLiteralSetIfNull(
- Send node, ConstantExpression constant, Node rhs, A arg) {
- return handleTypeLiteralConstantSetIfNulls(node, constant, rhs, arg);
- }
-
- @override
- R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
- element, CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitUnresolvedStaticGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
- setter, CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitUnresolvedStaticSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, element,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitUnresolvedSuperGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
- setter, CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
- element, CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitUnresolvedSuperSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- return handleSuperSetIfNulls(node, getter, CompoundGetter.GETTER, element,
- CompoundSetter.INVALID, rhs, arg);
- }
-
- @override
- R visitUnresolvedTopLevelGetterSetIfNull(
- Send node, Element element, MethodElement setter, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
- setter, CompoundSetter.SETTER, rhs, arg);
- }
-
- @override
- R visitUnresolvedTopLevelSetterSetIfNull(
- Send node, GetterElement getter, Element element, Node rhs, A arg) {
- return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, element,
- CompoundSetter.INVALID, rhs, arg);
- }
-}
-
-/// Simplified handling of indexed compound assignments and prefix/postfix
-/// expressions.
-abstract class BaseImplementationOfIndexCompoundsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- /// Handle a dynamic index compounds, like `receiver[index] += rhs` or
- /// `--receiver[index]`.
- R handleIndexCompounds(
- SendSet node, Node receiver, Node index, CompoundRhs rhs, A arg);
-
- /// Handle a super index compounds, like `super[index] += rhs` or
- /// `--super[index]`.
- R handleSuperIndexCompounds(SendSet node, Element indexFunction,
- Element indexSetFunction, Node index, CompoundRhs rhs, A arg,
- {bool isGetterValid, bool isSetterValid});
-
- @override
- R visitSuperCompoundIndexSet(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
- index, new AssignmentCompound(operator, rhs), arg,
- isGetterValid: true, isSetterValid: true);
- }
-
- @override
- R visitSuperIndexPostfix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
- index, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isGetterValid: true, isSetterValid: true);
- }
-
- @override
- R visitSuperIndexPrefix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
- index, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isGetterValid: true, isSetterValid: true);
- }
-
- @override
- R visitUnresolvedSuperGetterCompoundIndexSet(
- SendSet node,
- Element indexFunction,
- FunctionElement indexSetFunction,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
- index, new AssignmentCompound(operator, rhs), arg,
- isGetterValid: false, isSetterValid: true);
- }
-
- @override
- R visitUnresolvedSuperSetterCompoundIndexSet(
- SendSet node,
- MethodElement indexFunction,
- Element indexSetFunction,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- A arg) {
- return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
- index, new AssignmentCompound(operator, rhs), arg,
- isGetterValid: true, isSetterValid: false);
- }
-
- @override
- R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
- Node index, AssignmentOperator operator, Node rhs, A arg) {
- return handleSuperIndexCompounds(node, element, element, index,
- new AssignmentCompound(operator, rhs), arg,
- isGetterValid: false, isSetterValid: false);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPostfix(
- SendSet node,
- Element element,
- FunctionElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexCompounds(node, element, indexSetFunction, index,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isGetterValid: false, isSetterValid: true);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPrefix(
- SendSet node,
- Element element,
- FunctionElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexCompounds(node, element, indexSetFunction, index,
- new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isGetterValid: false, isSetterValid: true);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPostfix(
- SendSet node,
- MethodElement indexFunction,
- Element element,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexCompounds(node, indexFunction, element, index,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isGetterValid: true, isSetterValid: false);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPrefix(
- SendSet node,
- MethodElement indexFunction,
- Element element,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexCompounds(node, indexFunction, element, index,
- new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isGetterValid: true, isSetterValid: false);
- }
-
- @override
- R visitUnresolvedSuperIndexPostfix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- return handleSuperIndexCompounds(node, element, element, index,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
- isGetterValid: false, isSetterValid: false);
- }
-
- @override
- R visitUnresolvedSuperIndexPrefix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- return handleSuperIndexCompounds(node, element, element, index,
- new IncDecCompound(CompoundKind.PREFIX, operator), arg,
- isGetterValid: false, isSetterValid: false);
- }
-
- @override
- R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
- AssignmentOperator operator, Node rhs, A arg) {
- return handleIndexCompounds(
- node, receiver, index, new AssignmentCompound(operator, rhs), arg);
- }
-
- @override
- R visitIndexPostfix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- return handleIndexCompounds(node, receiver, index,
- new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
- }
-
- @override
- R visitIndexPrefix(
- Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
- return handleIndexCompounds(node, receiver, index,
- new IncDecCompound(CompoundKind.PREFIX, operator), arg);
- }
-}
-
-/// Simplified handling of super if-null assignments.
-abstract class BaseImplementationOfSuperIndexSetIfNullMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- /// Handle a super index if-null assignments, like `super[index] ??= rhs`.
- R handleSuperIndexSetIfNull(SendSet node, Element indexFunction,
- Element indexSetFunction, Node index, Node rhs, A arg,
- {bool isGetterValid, bool isSetterValid});
-
- @override
- R visitSuperIndexSetIfNull(Send node, FunctionElement indexFunction,
- FunctionElement indexSetFunction, Node index, Node rhs, A arg) {
- return handleSuperIndexSetIfNull(
- node, indexFunction, indexSetFunction, index, rhs, arg,
- isGetterValid: true, isSetterValid: true);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexSetIfNull(
- SendSet node,
- Element indexFunction,
- FunctionElement indexSetFunction,
- Node index,
- Node rhs,
- A arg) {
- return handleSuperIndexSetIfNull(
- node, indexFunction, indexSetFunction, index, rhs, arg,
- isGetterValid: false, isSetterValid: true);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexSetIfNull(
- SendSet node,
- MethodElement indexFunction,
- Element indexSetFunction,
- Node index,
- Node rhs,
- A arg) {
- return handleSuperIndexSetIfNull(
- node, indexFunction, indexSetFunction, index, rhs, arg,
- isGetterValid: true, isSetterValid: false);
- }
-
- @override
- R visitUnresolvedSuperIndexSetIfNull(
- Send node, Element element, Node index, Node rhs, A arg) {
- return handleSuperIndexSetIfNull(node, element, element, index, rhs, arg,
- isGetterValid: false, isSetterValid: false);
- }
-}
-
-/// Mixin that groups all `visitSuperXPrefix`, `visitSuperXPostfix` methods by
-/// delegating calls to `handleSuperXPostfixPrefix` methods.
-///
-/// This mixin is useful for the cases where super prefix/postfix expression are
-/// handled uniformly.
-abstract class BaseImplementationOfSuperIncDecsMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleSuperFieldFieldPostfixPrefix(Send node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleSuperFieldSetterPostfixPrefix(Send node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleSuperGetterFieldPostfixPrefix(Send node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleSuperGetterSetterPostfixPrefix(Send node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleSuperMethodSetterPostfixPrefix(Send node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleSuperIndexPostfixPrefix(
- Send node,
- FunctionElement indexFunction,
- FunctionElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg,
- {bool isPrefix});
-
- R handleUnresolvedSuperGetterIndexPostfixPrefix(Send node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleUnresolvedSuperSetterIndexPostfixPrefix(
- Send node,
- FunctionElement indexFunction,
- Element element,
- Node index,
- IncDecOperator operator,
- A arg,
- {bool isPrefix});
-
- R handleUnresolvedSuperIndexPostfixPrefix(
- Send node, Element element, Node index, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleFinalSuperFieldPostfixPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleSuperMethodPostfixPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleUnresolvedSuperPostfixPrefix(
- Send node, Element element, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleUnresolvedSuperGetterPostfixPrefix(Send node, Element element,
- MethodElement setter, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- R handleUnresolvedSuperSetterPostfixPrefix(Send node, GetterElement getter,
- Element element, IncDecOperator operator, A arg,
- {bool isPrefix});
-
- @override
- R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return handleSuperFieldFieldPostfixPrefix(
- node, readField, writtenField, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
- FieldElement writtenField, IncDecOperator operator, A arg) {
- return handleSuperFieldFieldPostfixPrefix(
- node, readField, writtenField, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitSuperFieldPostfix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperFieldFieldPostfixPrefix(node, field, field, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperFieldPrefix(
- SendSet node, FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperFieldFieldPostfixPrefix(node, field, field, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperFieldSetterPostfixPrefix(
- node, field, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperFieldSetterPostfixPrefix(
- node, field, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperGetterFieldPostfixPrefix(
- node, getter, field, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
- FieldElement field, IncDecOperator operator, A arg) {
- return handleSuperGetterFieldPostfixPrefix(
- node, getter, field, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperGetterSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperGetterSetterPostfixPrefix(
- node, getter, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperMethodSetterPostfixPrefix(
- node, method, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleSuperMethodSetterPostfixPrefix(
- node, method, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitSuperIndexPostfix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexPostfixPrefix(
- node, indexFunction, indexSetFunction, index, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperIndexPrefix(
- Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleSuperIndexPostfixPrefix(
- node, indexFunction, indexSetFunction, index, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperGetterIndexPostfixPrefix(
- node, element, setter, index, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
- MethodElement setter, Node index, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperGetterIndexPostfixPrefix(
- node, element, setter, index, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPostfix(
- SendSet node,
- MethodElement indexFunction,
- Element element,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleUnresolvedSuperSetterIndexPostfixPrefix(
- node, indexFunction, element, index, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedSuperSetterIndexPrefix(
- SendSet node,
- MethodElement indexFunction,
- Element element,
- Node index,
- IncDecOperator operator,
- A arg) {
- return handleUnresolvedSuperSetterIndexPostfixPrefix(
- node, indexFunction, element, index, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedSuperIndexPostfix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperIndexPostfixPrefix(
- node, element, index, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedSuperIndexPrefix(
- Send node, Element element, Node index, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperIndexPostfixPrefix(
- node, element, index, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitFinalSuperFieldPostfix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleFinalSuperFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitFinalSuperFieldPrefix(
- Send node, FieldElement field, IncDecOperator operator, A arg) {
- return handleFinalSuperFieldPostfixPrefix(node, field, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitSuperMethodPostfix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleSuperMethodPostfixPrefix(node, method, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitSuperMethodPrefix(
- Send node, MethodElement method, IncDecOperator operator, A arg) {
- return handleSuperMethodPostfixPrefix(node, method, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedSuperPostfix(
- SendSet node, Element element, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperPostfixPrefix(node, element, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedSuperPrefix(
- Send node, Element element, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperPostfixPrefix(node, element, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperGetterPostfixPrefix(
- node, element, setter, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
- SetterElement setter, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperGetterPostfixPrefix(
- node, element, setter, operator, arg,
- isPrefix: true);
- }
-
- @override
- R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperSetterPostfixPrefix(
- node, getter, element, operator, arg,
- isPrefix: false);
- }
-
- @override
- R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
- Element element, IncDecOperator operator, A arg) {
- return handleUnresolvedSuperSetterPostfixPrefix(
- node, getter, element, operator, arg,
- isPrefix: true);
- }
-}
-
-/// Mixin that groups the non-constant `visitXConstructorInvoke` methods by
-/// delegating calls to the `handleConstructorInvoke` method.
-///
-/// This mixin is useful for the cases where all constructor invocations are
-/// handled uniformly.
-abstract class BaseImplementationOfNewMixin<R, A>
- implements SemanticSendVisitor<R, A> {
- R handleConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionDartType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg);
-
- R visitGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return handleConstructorInvoke(
- node, constructor, type, arguments, callStructure, arg);
- }
-
- @override
- R visitRedirectingGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return handleConstructorInvoke(
- node, constructor, type, arguments, callStructure, arg);
- }
-
- @override
- R visitFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return handleConstructorInvoke(
- node, constructor, type, arguments, callStructure, arg);
- }
-
- @override
- R visitRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- ConstructorElement effectiveTarget,
- ResolutionInterfaceType effectiveTargetType,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return handleConstructorInvoke(
- node, constructor, type, arguments, callStructure, arg);
- }
-
- @override
- R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
- ResolutionDartType type, NodeList arguments, Selector selector, A arg) {
- return handleConstructorInvoke(
- node, constructor, type, arguments, selector.callStructure, arg);
- }
-
- @override
- R visitUnresolvedClassConstructorInvoke(
- NewExpression node,
- ErroneousElement element,
- ResolutionDartType type,
- NodeList arguments,
- Selector selector,
- A arg) {
- return handleConstructorInvoke(
- node, element, type, arguments, selector.callStructure, arg);
- }
-
- @override
- R visitAbstractClassConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return handleConstructorInvoke(
- node, constructor, type, arguments, callStructure, arg);
- }
-
- @override
- R visitUnresolvedRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- ResolutionInterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- A arg) {
- return handleConstructorInvoke(
- node, constructor, type, arguments, callStructure, arg);
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
deleted file mode 100644
index f9e8cf0..0000000
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.semantics_visitor.resolver;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../tree/tree.dart';
-import 'semantic_visitor.dart';
-import 'send_structure.dart';
-import 'tree_elements.dart';
-
-abstract class DeclStructure<R, A> {
- final FunctionElement element;
-
- DeclStructure(this.element);
-
- /// Calls the matching visit method on [visitor] with [node] and [arg].
- R dispatch(
- SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node, A arg);
-}
-
-enum ConstructorKind {
- GENERATIVE,
- REDIRECTING_GENERATIVE,
- FACTORY,
- REDIRECTING_FACTORY,
-}
-
-class ConstructorDeclStructure<R, A> extends DeclStructure<R, A> {
- final ConstructorKind kind;
-
- ConstructorDeclStructure(this.kind, ConstructorElement constructor)
- : super(constructor);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node,
- A arg) {
- switch (kind) {
- case ConstructorKind.GENERATIVE:
- return visitor.visitGenerativeConstructorDeclaration(
- node, element, node.parameters, node.initializers, node.body, arg);
- case ConstructorKind.REDIRECTING_GENERATIVE:
- return visitor.visitRedirectingGenerativeConstructorDeclaration(
- node, element, node.parameters, node.initializers, arg);
- case ConstructorKind.FACTORY:
- return visitor.visitFactoryConstructorDeclaration(
- node, element, node.parameters, node.body, arg);
- default:
- break;
- }
- throw failedAt(node, "Unhandled constructor declaration kind: ${kind}");
- }
-}
-
-class RedirectingFactoryConstructorDeclStructure<R, A>
- extends DeclStructure<R, A> {
- ResolutionInterfaceType redirectionTargetType;
- ConstructorElement redirectionTarget;
-
- RedirectingFactoryConstructorDeclStructure(ConstructorElement constructor,
- this.redirectionTargetType, this.redirectionTarget)
- : super(constructor);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node,
- A arg) {
- return visitor.visitRedirectingFactoryConstructorDeclaration(node, element,
- node.parameters, redirectionTargetType, redirectionTarget, arg);
- }
-}
-
-enum FunctionKind {
- TOP_LEVEL_GETTER,
- TOP_LEVEL_SETTER,
- TOP_LEVEL_FUNCTION,
- STATIC_GETTER,
- STATIC_SETTER,
- STATIC_FUNCTION,
- ABSTRACT_GETTER,
- ABSTRACT_SETTER,
- ABSTRACT_METHOD,
- INSTANCE_GETTER,
- INSTANCE_SETTER,
- INSTANCE_METHOD,
- LOCAL_FUNCTION,
- CLOSURE,
-}
-
-class FunctionDeclStructure<R, A> extends DeclStructure<R, A> {
- final FunctionKind kind;
-
- FunctionDeclStructure(this.kind, FunctionElement function) : super(function);
-
- // ignore: MISSING_RETURN
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node,
- A arg) {
- switch (kind) {
- case FunctionKind.TOP_LEVEL_GETTER:
- return visitor.visitTopLevelGetterDeclaration(
- node, element, node.body, arg);
- case FunctionKind.TOP_LEVEL_SETTER:
- return visitor.visitTopLevelSetterDeclaration(
- node, element, node.parameters, node.body, arg);
- case FunctionKind.TOP_LEVEL_FUNCTION:
- return visitor.visitTopLevelFunctionDeclaration(
- node, element, node.parameters, node.body, arg);
- case FunctionKind.STATIC_GETTER:
- return visitor.visitStaticGetterDeclaration(
- node, element, node.body, arg);
- case FunctionKind.STATIC_SETTER:
- return visitor.visitStaticSetterDeclaration(
- node, element, node.parameters, node.body, arg);
- case FunctionKind.STATIC_FUNCTION:
- return visitor.visitStaticFunctionDeclaration(
- node, element, node.parameters, node.body, arg);
- case FunctionKind.ABSTRACT_GETTER:
- return visitor.visitAbstractGetterDeclaration(node, element, arg);
- case FunctionKind.ABSTRACT_SETTER:
- return visitor.visitAbstractSetterDeclaration(
- node, element, node.parameters, arg);
- case FunctionKind.ABSTRACT_METHOD:
- return visitor.visitAbstractMethodDeclaration(
- node, element, node.parameters, arg);
- case FunctionKind.INSTANCE_GETTER:
- return visitor.visitInstanceGetterDeclaration(
- node, element, node.body, arg);
- case FunctionKind.INSTANCE_SETTER:
- return visitor.visitInstanceSetterDeclaration(
- node, element, node.parameters, node.body, arg);
- case FunctionKind.INSTANCE_METHOD:
- return visitor.visitInstanceMethodDeclaration(
- node, element, node.parameters, node.body, arg);
- case FunctionKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionDeclaration(
- node, element, node.parameters, node.body, arg);
- case FunctionKind.CLOSURE:
- return visitor.visitClosureDeclaration(
- node, element, node.parameters, node.body, arg);
- }
- }
-}
-
-abstract class DeclarationResolverMixin {
- TreeElements get elements;
-
- internalError(Spannable spannable, String message);
-
- ConstructorKind computeConstructorKind(ConstructorElement constructor) {
- if (constructor.isRedirectingFactory) {
- return ConstructorKind.REDIRECTING_FACTORY;
- } else if (constructor.isFactoryConstructor) {
- return ConstructorKind.FACTORY;
- } else if (constructor.isRedirectingGenerative) {
- return ConstructorKind.REDIRECTING_GENERATIVE;
- } else {
- return ConstructorKind.GENERATIVE;
- }
- }
-
- DeclStructure computeFunctionStructure(FunctionExpression node) {
- FunctionElement element = elements.getFunctionDefinition(node);
- if (element.isConstructor) {
- ConstructorElement constructor = element;
- ConstructorKind kind = computeConstructorKind(constructor);
- if (kind == ConstructorKind.REDIRECTING_FACTORY) {
- return new RedirectingFactoryConstructorDeclStructure(
- constructor,
- elements.getType(node.body),
- constructor.immediateRedirectionTarget);
- } else {
- return new ConstructorDeclStructure(kind, element);
- }
- } else {
- FunctionKind kind;
- if (element.isLocal) {
- if (element.name.isEmpty) {
- kind = FunctionKind.CLOSURE;
- } else {
- kind = FunctionKind.LOCAL_FUNCTION;
- }
- } else if (element.isInstanceMember) {
- if (element.isGetter) {
- kind = element.isAbstract
- ? FunctionKind.ABSTRACT_GETTER
- : FunctionKind.INSTANCE_GETTER;
- } else if (element.isSetter) {
- kind = element.isAbstract
- ? FunctionKind.ABSTRACT_SETTER
- : FunctionKind.INSTANCE_SETTER;
- } else {
- kind = element.isAbstract
- ? FunctionKind.ABSTRACT_METHOD
- : FunctionKind.INSTANCE_METHOD;
- }
- } else if (element.isStatic) {
- if (element.isGetter) {
- kind = FunctionKind.STATIC_GETTER;
- } else if (element.isSetter) {
- kind = FunctionKind.STATIC_SETTER;
- } else {
- kind = FunctionKind.STATIC_FUNCTION;
- }
- } else if (element.isTopLevel) {
- if (element.isGetter) {
- kind = FunctionKind.TOP_LEVEL_GETTER;
- } else if (element.isSetter) {
- kind = FunctionKind.TOP_LEVEL_SETTER;
- } else {
- kind = FunctionKind.TOP_LEVEL_FUNCTION;
- }
- } else {
- return internalError(node, "Unhandled function expression.");
- }
- return new FunctionDeclStructure(kind, element);
- }
- }
-
- InitializersStructure computeInitializersStructure(FunctionExpression node) {
- List<InitializerStructure> initializers = <InitializerStructure>[];
- NodeList list = node.initializers;
- bool constructorInvocationSeen = false;
- if (list != null) {
- for (Node initializer in list) {
- InitializerStructure structure =
- computeInitializerStructure(initializer);
- if (structure.isConstructorInvoke) {
- constructorInvocationSeen = true;
- }
- initializers.add(structure);
- }
- }
- if (!constructorInvocationSeen) {
- ConstructorElement currentConstructor = elements[node];
- ClassElement currentClass = currentConstructor.enclosingClass;
- ResolutionInterfaceType supertype = currentClass.supertype;
- if (supertype != null) {
- ClassElement superclass = supertype.element;
- ConstructorElement superConstructor =
- superclass.lookupDefaultConstructor();
- initializers.add(new ImplicitSuperConstructorInvokeStructure(
- node, superConstructor, supertype));
- }
- }
- return new InitializersStructure(initializers);
- }
-
- InitializerStructure computeInitializerStructure(Send node) {
- Element element = elements[node];
- if (node.asSendSet() != null) {
- return new FieldInitializerStructure(node, element);
- } else if (Initializers.isConstructorRedirect(node)) {
- return new ThisConstructorInvokeStructure(
- node, element, elements.getSelector(node).callStructure);
- } else if (Initializers.isSuperConstructorCall(node)) {
- return new SuperConstructorInvokeStructure(
- node,
- element,
- elements.analyzedElement.enclosingClass.supertype,
- elements.getSelector(node).callStructure);
- }
- return internalError(node, "Unhandled initializer.");
- }
-
- List<ParameterStructure> computeParameterStructures(NodeList parameters) {
- List<ParameterStructure> list = <ParameterStructure>[];
- int index = 0;
- for (Node node in parameters) {
- NodeList optionalParameters = node.asNodeList();
- if (optionalParameters != null) {
- bool isNamed = optionalParameters.beginToken.stringValue == '{';
- for (Node node in optionalParameters) {
- list.add(computeParameterStructure(node, index++,
- isRequired: false, isNamed: isNamed));
- }
- } else {
- list.add(computeParameterStructure(node, index++));
- }
- }
- return list;
- }
-
- ParameterStructure computeParameterStructure(
- VariableDefinitions definitions, int index,
- {bool isRequired: true, bool isNamed: false}) {
- Node node = definitions.definitions.nodes.single;
- ParameterElement element = elements[node];
- if (element == null) {
- throw failedAt(node, "No parameter structure for $node.");
- }
- if (isRequired) {
- return new RequiredParameterStructure(definitions, node, element, index);
- } else {
- // TODO(johnniwinther): Should we differentiate between implicit (null)
- // and explicit values? What about optional parameters on redirecting
- // factories?
- if (isNamed) {
- return new NamedParameterStructure(
- definitions, node, element, element.constant);
- } else {
- return new OptionalParameterStructure(
- definitions, node, element, element.constant, index);
- }
- }
- }
-
- void computeVariableStructures(VariableDefinitions definitions,
- void callback(Node node, VariableStructure structure)) {
- for (Node node in definitions.definitions) {
- callback(definitions, computeVariableStructure(node));
- }
- }
-
- VariableStructure computeVariableStructure(Node node) {
- VariableElement element = elements[node];
- VariableKind kind;
- if (element.isLocal) {
- kind = VariableKind.LOCAL_VARIABLE;
- } else if (element.isInstanceMember) {
- kind = VariableKind.INSTANCE_FIELD;
- } else if (element.isStatic) {
- kind = VariableKind.STATIC_FIELD;
- } else if (element.isTopLevel) {
- kind = VariableKind.TOP_LEVEL_FIELD;
- } else {
- return internalError(node, "Unexpected variable $element.");
- }
- if (element.isConst) {
- ConstantExpression constant = elements.getConstant(element.initializer);
- return new ConstantVariableStructure(kind, node, element, constant);
- } else {
- return new NonConstantVariableStructure(kind, node, element);
- }
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
deleted file mode 100644
index 0c22657..0000000
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ /dev/null
@@ -1,2512 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.send_structure;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import 'access_semantics.dart';
-import 'semantic_visitor.dart';
-
-/// Interface for the structure of the semantics of a [Send] or [NewExpression]
-/// node.
-abstract class SemanticSendStructure<R, A> {
- /// Calls the matching visit method on [visitor] with [node] and [arg].
- R dispatch(SemanticSendVisitor<R, A> visitor, covariant Node node, A arg);
-}
-
-enum SendStructureKind {
- IF_NULL,
- LOGICAL_AND,
- LOGICAL_OR,
- IS,
- IS_NOT,
- AS,
- INVOKE,
- INCOMPATIBLE_INVOKE,
- GET,
- SET,
- NOT,
- UNARY,
- INVALID_UNARY,
- INDEX,
- EQUALS,
- NOT_EQUALS,
- BINARY,
- INVALID_BINARY,
- INDEX_SET,
- INDEX_PREFIX,
- INDEX_POSTFIX,
- COMPOUND,
- SET_IF_NULL,
- COMPOUND_INDEX_SET,
- INDEX_SET_IF_NULL,
- PREFIX,
- POSTFIX,
- DEFERRED_PREFIX,
-}
-
-/// Interface for the structure of the semantics of a [Send] node.
-///
-/// Subclasses handle each of the [Send] variations; `assert(e)`, `a && b`,
-/// `a.b`, `a.b(c)`, etc.
-abstract class SendStructure<R, A> extends SemanticSendStructure<R, A> {
- /// Calls the matching visit method on [visitor] with [send] and [arg].
- R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg);
-
- SendStructureKind get kind;
-}
-
-/// The structure for a [Send] of the form `a ?? b`.
-class IfNullStructure<R, A> implements SendStructure<R, A> {
- const IfNullStructure();
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.visitIfNull(node, node.receiver, node.arguments.single, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.IF_NULL;
-
- String toString() => '??';
-}
-
-/// The structure for a [Send] of the form `a && b`.
-class LogicalAndStructure<R, A> implements SendStructure<R, A> {
- const LogicalAndStructure();
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.visitLogicalAnd(
- node, node.receiver, node.arguments.single, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.LOGICAL_AND;
-
- String toString() => '&&';
-}
-
-/// The structure for a [Send] of the form `a || b`.
-class LogicalOrStructure<R, A> implements SendStructure<R, A> {
- const LogicalOrStructure();
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.visitLogicalOr(
- node, node.receiver, node.arguments.single, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.LOGICAL_OR;
-
- String toString() => '||';
-}
-
-/// The structure for a [Send] of the form `a is T`.
-class IsStructure<R, A> implements SendStructure<R, A> {
- /// The type that the expression is tested against.
- final ResolutionDartType type;
-
- IsStructure(this.type);
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.visitIs(node, node.receiver, type, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.IS;
-
- String toString() => 'is $type';
-}
-
-/// The structure for a [Send] of the form `a is! T`.
-class IsNotStructure<R, A> implements SendStructure<R, A> {
- /// The type that the expression is tested against.
- final ResolutionDartType type;
-
- IsNotStructure(this.type);
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.visitIsNot(node, node.receiver, type, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.IS_NOT;
-
- String toString() => 'is! $type';
-}
-
-/// The structure for a [Send] of the form `a as T`.
-class AsStructure<R, A> implements SendStructure<R, A> {
- /// The type that the expression is cast to.
- final ResolutionDartType type;
-
- AsStructure(this.type);
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.visitAs(node, node.receiver, type, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.AS;
-
- String toString() => 'as $type';
-}
-
-/// The structure for a [Send] that is an invocation.
-class InvokeStructure<R, A> implements SendStructure<R, A> {
- /// The target of the invocation.
- final AccessSemantics semantics;
-
- /// The [Selector] for the invocation.
- // TODO(johnniwinther): Store this only for dynamic invocations.
- final Selector selector;
-
- /// The [CallStructure] of the invocation.
- // TODO(johnniwinther): Store this directly for static invocations.
- CallStructure get callStructure => selector.callStructure;
-
- InvokeStructure(this.semantics, this.selector);
-
- @override
- SendStructureKind get kind => SendStructureKind.INVOKE;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return visitor.visitIfNotNullDynamicPropertyInvoke(
- node, node.receiver, node.argumentsNode, selector, arg);
- case AccessKind.DYNAMIC_PROPERTY:
- return visitor.visitDynamicPropertyInvoke(
- node, node.receiver, node.argumentsNode, selector, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionInvoke(
- node,
- semantics.element,
- node.argumentsNode,
- // TODO(johnniwinther): Store the call selector instead of the
- // selector using the name of the function.
- callStructure,
- arg);
- case AccessKind.LOCAL_VARIABLE:
- case AccessKind.FINAL_LOCAL_VARIABLE:
- return visitor.visitLocalVariableInvoke(
- node,
- semantics.element,
- node.argumentsNode,
- // TODO(johnniwinther): Store the call selector instead of the
- // selector using the name of the variable.
- callStructure,
- arg);
- case AccessKind.PARAMETER:
- case AccessKind.FINAL_PARAMETER:
- return visitor.visitParameterInvoke(
- node,
- semantics.element,
- node.argumentsNode,
- // TODO(johnniwinther): Store the call selector instead of the
- // selector using the name of the parameter.
- callStructure,
- arg);
- case AccessKind.STATIC_FIELD:
- case AccessKind.FINAL_STATIC_FIELD:
- return visitor.visitStaticFieldInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticFunctionInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.STATIC_GETTER:
- return visitor.visitStaticGetterInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.STATIC_SETTER:
- return visitor.visitStaticSetterInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.TOPLEVEL_FIELD:
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- return visitor.visitTopLevelFieldInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelFunctionInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.TOPLEVEL_GETTER:
- return visitor.visitTopLevelGetterInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.TOPLEVEL_SETTER:
- return visitor.visitTopLevelSetterInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.CLASS_TYPE_LITERAL:
- return visitor.visitClassTypeLiteralInvoke(
- node, semantics.constant, node.argumentsNode, callStructure, arg);
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- return visitor.visitTypedefTypeLiteralInvoke(
- node, semantics.constant, node.argumentsNode, callStructure, arg);
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return visitor.visitDynamicTypeLiteralInvoke(
- node, semantics.constant, node.argumentsNode, callStructure, arg);
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- return visitor.visitTypeVariableTypeLiteralInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.EXPRESSION:
- return visitor.visitExpressionInvoke(
- node, node.selector, node.argumentsNode, callStructure, arg);
- case AccessKind.THIS:
- return visitor.visitThisInvoke(
- node, node.argumentsNode, callStructure, arg);
- case AccessKind.THIS_PROPERTY:
- return visitor.visitThisPropertyInvoke(
- node, node.argumentsNode, selector, arg);
- case AccessKind.SUPER_FIELD:
- case AccessKind.SUPER_FINAL_FIELD:
- return visitor.visitSuperFieldInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.SUPER_GETTER:
- return visitor.visitSuperGetterInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.SUPER_SETTER:
- return visitor.visitSuperSetterInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.CONSTANT:
- return visitor.visitConstantInvoke(
- node, semantics.constant, node.argumentsNode, callStructure, arg);
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedInvoke(
- node, semantics.element, node.argumentsNode, selector, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperInvoke(
- node, semantics.element, node.argumentsNode, selector, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidInvoke(
- node, semantics.element, node.argumentsNode, selector, arg);
- case AccessKind.COMPOUND:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid invoke: ${semantics}");
- }
-
- String toString() => 'invoke($selector, $semantics)';
-}
-
-/// The structure for a [Send] that is an incompatible invocation, i.e. an
-/// invocation of a known target where the call structure does not match.
-class IncompatibleInvokeStructure<R, A> implements SendStructure<R, A> {
- /// The target of the invocation.
- final AccessSemantics semantics;
-
- /// The [Selector] for the invocation.
- // TODO(johnniwinther): Store this only for dynamic invocations.
- final Selector selector;
-
- /// The [CallStructure] of the invocation.
- // TODO(johnniwinther): Store this directly for static invocations.
- CallStructure get callStructure => selector.callStructure;
-
- IncompatibleInvokeStructure(this.semantics, this.selector);
-
- @override
- SendStructureKind get kind => SendStructureKind.INCOMPATIBLE_INVOKE;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticFunctionIncompatibleInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodIncompatibleInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelFunctionIncompatibleInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionIncompatibleInvoke(
- node, semantics.element, node.argumentsNode, callStructure, arg);
- default:
- // TODO(johnniwinther): Support more variants of this invoke structure.
- break;
- }
- throw failedAt(node, "Invalid incompatible invoke: ${semantics}");
- }
-
- String toString() => 'incompatible-invoke($selector, $semantics)';
-}
-
-/// The structure for a [Send] that is a read access.
-class GetStructure<R, A> implements SendStructure<R, A> {
- /// The target of the read access.
- final AccessSemantics semantics;
-
- GetStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.GET;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return visitor.visitIfNotNullDynamicPropertyGet(
- node, node.receiver, semantics.name, arg);
- case AccessKind.DYNAMIC_PROPERTY:
- return visitor.visitDynamicPropertyGet(
- node, node.receiver, semantics.name, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionGet(node, semantics.element, arg);
- case AccessKind.LOCAL_VARIABLE:
- case AccessKind.FINAL_LOCAL_VARIABLE:
- return visitor.visitLocalVariableGet(node, semantics.element, arg);
- case AccessKind.PARAMETER:
- case AccessKind.FINAL_PARAMETER:
- return visitor.visitParameterGet(node, semantics.element, arg);
- case AccessKind.STATIC_FIELD:
- case AccessKind.FINAL_STATIC_FIELD:
- return visitor.visitStaticFieldGet(node, semantics.element, arg);
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticFunctionGet(node, semantics.element, arg);
- case AccessKind.STATIC_GETTER:
- return visitor.visitStaticGetterGet(node, semantics.element, arg);
- case AccessKind.STATIC_SETTER:
- return visitor.visitStaticSetterGet(node, semantics.element, arg);
- case AccessKind.TOPLEVEL_FIELD:
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- return visitor.visitTopLevelFieldGet(node, semantics.element, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelFunctionGet(node, semantics.element, arg);
- case AccessKind.TOPLEVEL_GETTER:
- return visitor.visitTopLevelGetterGet(node, semantics.element, arg);
- case AccessKind.TOPLEVEL_SETTER:
- return visitor.visitTopLevelSetterGet(node, semantics.element, arg);
- case AccessKind.CLASS_TYPE_LITERAL:
- return visitor.visitClassTypeLiteralGet(node, semantics.constant, arg);
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- return visitor.visitTypedefTypeLiteralGet(
- node, semantics.constant, arg);
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return visitor.visitDynamicTypeLiteralGet(
- node, semantics.constant, arg);
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- return visitor.visitTypeVariableTypeLiteralGet(
- node, semantics.element, arg);
- case AccessKind.EXPRESSION:
- // This is not a valid case.
- break;
- case AccessKind.THIS:
- // TODO(johnniwinther): Handle this when `this` is a [Send].
- break;
- case AccessKind.THIS_PROPERTY:
- return visitor.visitThisPropertyGet(node, semantics.name, arg);
- case AccessKind.SUPER_FIELD:
- case AccessKind.SUPER_FINAL_FIELD:
- return visitor.visitSuperFieldGet(node, semantics.element, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodGet(node, semantics.element, arg);
- case AccessKind.SUPER_GETTER:
- return visitor.visitSuperGetterGet(node, semantics.element, arg);
- case AccessKind.SUPER_SETTER:
- return visitor.visitSuperSetterGet(node, semantics.element, arg);
- case AccessKind.CONSTANT:
- return visitor.visitConstantGet(node, semantics.constant, arg);
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedGet(node, semantics.element, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperGet(node, semantics.element, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidGet(node, semantics.element, arg);
- case AccessKind.COMPOUND:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid getter: ${semantics}");
- }
-
- String toString() => 'get($semantics)';
-}
-
-/// The structure for a [Send] that is an assignment.
-class SetStructure<R, A> implements SendStructure<R, A> {
- /// The target of the assignment.
- final AccessSemantics semantics;
-
- SetStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.SET;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return visitor.visitIfNotNullDynamicPropertySet(
- node, node.receiver, semantics.name, node.arguments.single, arg);
- case AccessKind.DYNAMIC_PROPERTY:
- return visitor.visitDynamicPropertySet(
- node, node.receiver, semantics.name, node.arguments.single, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.LOCAL_VARIABLE:
- return visitor.visitLocalVariableSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_LOCAL_VARIABLE:
- return visitor.visitFinalLocalVariableSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.PARAMETER:
- return visitor.visitParameterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_PARAMETER:
- return visitor.visitFinalParameterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.STATIC_FIELD:
- return visitor.visitStaticFieldSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_STATIC_FIELD:
- return visitor.visitFinalStaticFieldSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticFunctionSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.STATIC_GETTER:
- return visitor.visitStaticGetterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.STATIC_SETTER:
- return visitor.visitStaticSetterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_FIELD:
- return visitor.visitTopLevelFieldSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- return visitor.visitFinalTopLevelFieldSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelFunctionSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_GETTER:
- return visitor.visitTopLevelGetterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_SETTER:
- return visitor.visitTopLevelSetterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.CLASS_TYPE_LITERAL:
- return visitor.visitClassTypeLiteralSet(
- node, semantics.constant, node.arguments.single, arg);
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- return visitor.visitTypedefTypeLiteralSet(
- node, semantics.constant, node.arguments.single, arg);
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return visitor.visitDynamicTypeLiteralSet(
- node, semantics.constant, node.arguments.single, arg);
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- return visitor.visitTypeVariableTypeLiteralSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.EXPRESSION:
- // This is not a valid case.
- break;
- case AccessKind.THIS:
- // This is not a valid case.
- break;
- case AccessKind.THIS_PROPERTY:
- return visitor.visitThisPropertySet(
- node, semantics.name, node.arguments.single, arg);
- case AccessKind.SUPER_FIELD:
- return visitor.visitSuperFieldSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.SUPER_FINAL_FIELD:
- return visitor.visitFinalSuperFieldSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.SUPER_GETTER:
- return visitor.visitSuperGetterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.SUPER_SETTER:
- return visitor.visitSuperSetterSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.CONSTANT:
- // TODO(johnniwinther): Should this be a valid case?
- break;
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidSet(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.COMPOUND:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid setter: ${semantics}");
- }
-
- String toString() => 'set($semantics)';
-}
-
-/// The structure for a [Send] that is a negation, i.e. of the form `!e`.
-class NotStructure<R, A> implements SendStructure<R, A> {
- const NotStructure();
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.visitNot(node, node.receiver, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.NOT;
-
- String toString() => 'not()';
-}
-
-/// The structure for a [Send] that is an invocation of a user definable unary
-/// operator.
-class UnaryStructure<R, A> implements SendStructure<R, A> {
- /// The target of the unary operation.
- final AccessSemantics semantics;
-
- /// The user definable unary operator.
- final UnaryOperator operator;
-
- UnaryStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.UNARY;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitUnary(node, operator, node.receiver, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperUnary(node, operator, semantics.element, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperUnary(
- node, operator, semantics.element, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidUnary(
- node, operator, semantics.element, arg);
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid setter: ${semantics}");
- }
-
- String toString() => 'unary($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is an invocation of a undefined unary
-/// operator.
-class InvalidUnaryStructure<R, A> implements SendStructure<R, A> {
- const InvalidUnaryStructure();
-
- @override
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.errorUndefinedUnaryExpression(
- node, node.selector, node.receiver, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.INVALID_UNARY;
-
- String toString() => 'invalid unary';
-}
-
-/// The structure for a [Send] that is an index expression, i.e. of the form
-/// `a[b]`.
-class IndexStructure<R, A> implements SendStructure<R, A> {
- /// The target of the left operand.
- final AccessSemantics semantics;
-
- IndexStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.INDEX;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitIndex(
- node, node.receiver, node.arguments.single, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperIndex(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperIndex(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidIndex(
- node, semantics.element, node.arguments.single, arg);
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid index: ${semantics}");
- }
-}
-
-/// The structure for a [Send] that is an equals test, i.e. of the form
-/// `a == b`.
-class EqualsStructure<R, A> implements SendStructure<R, A> {
- /// The target of the left operand.
- final AccessSemantics semantics;
-
- EqualsStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.EQUALS;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitEquals(
- node, node.receiver, node.arguments.single, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperEquals(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidEquals(
- node, semantics.element, node.arguments.single, arg);
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid equals: ${semantics}");
- }
-
- String toString() => '==($semantics)';
-}
-
-/// The structure for a [Send] that is a not-equals test, i.e. of the form
-/// `a != b`.
-class NotEqualsStructure<R, A> implements SendStructure<R, A> {
- /// The target of the left operand.
- final AccessSemantics semantics;
-
- NotEqualsStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.NOT_EQUALS;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitNotEquals(
- node, node.receiver, node.arguments.single, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperNotEquals(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidNotEquals(
- node, semantics.element, node.arguments.single, arg);
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid not equals: ${semantics}");
- }
-
- String toString() => '!=($semantics)';
-}
-
-/// The structure for a [Send] that is an invocation of a user-definable binary
-/// operator.
-class BinaryStructure<R, A> implements SendStructure<R, A> {
- /// The target of the left operand.
- final AccessSemantics semantics;
-
- /// The user definable binary operator.
- final BinaryOperator operator;
-
- BinaryStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.BINARY;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitBinary(
- node, node.receiver, operator, node.arguments.single, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperBinary(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperBinary(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidBinary(
- node, semantics.element, operator, node.arguments.single, arg);
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid binary: ${semantics}");
- }
-
- String toString() => 'binary($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is an invocation of a undefined binary
-/// operator.
-class InvalidBinaryStructure<R, A> implements SendStructure<R, A> {
- const InvalidBinaryStructure();
-
- @override
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- return visitor.errorUndefinedBinaryExpression(
- node, node.receiver, node.selector, node.arguments.single, arg);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.INVALID_BINARY;
-
- String toString() => 'invalid binary';
-}
-
-/// The structure for a [Send] that is of the form `a[b] = c`.
-class IndexSetStructure<R, A> implements SendStructure<R, A> {
- /// The target of the index set operation.
- final AccessSemantics semantics;
-
- IndexSetStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.INDEX_SET;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitIndexSet(node, node.receiver, node.arguments.first,
- node.arguments.tail.head, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperIndexSet(node, semantics.element,
- node.arguments.first, node.arguments.tail.head, arg);
- case AccessKind.UNRESOLVED_SUPER:
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedSuperIndexSet(node, semantics.element,
- node.arguments.first, node.arguments.tail.head, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidIndexSet(node, semantics.element,
- node.arguments.first, node.arguments.tail.head, arg);
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid index set: ${semantics}");
- }
-
- String toString() => '[]=($semantics)';
-}
-
-/// The structure for a [Send] that is an prefix operation on an index
-/// expression, i.e. of the form `--a[b]`.
-class IndexPrefixStructure<R, A> implements SendStructure<R, A> {
- /// The target of the left operand.
- final AccessSemantics semantics;
-
- /// The `++` or `--` operator used in the operation.
- final IncDecOperator operator;
-
- IndexPrefixStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.INDEX_PREFIX;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitIndexPrefix(
- node, node.receiver, node.arguments.single, operator, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperIndexPrefix(
- node, semantics.element, node.arguments.single, operator, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidIndexPrefix(
- node, semantics.element, node.arguments.single, operator, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperIndexPrefix(node, compoundSemantics.getter,
- compoundSemantics.setter, node.arguments.single, operator, arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterIndexPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterIndexPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- operator,
- arg);
- default:
- // This is not a valid case.
- break;
- }
- break;
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid index prefix: ${semantics}");
- }
-}
-
-/// The structure for a [Send] that is an postfix operation on an index
-/// expression, i.e. of the form `a[b]++`.
-class IndexPostfixStructure<R, A> implements SendStructure<R, A> {
- /// The target of the left operand.
- final AccessSemantics semantics;
-
- /// The `++` or `--` operator used in the operation.
- final IncDecOperator operator;
-
- IndexPostfixStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.INDEX_POSTFIX;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitIndexPostfix(
- node, node.receiver, node.arguments.single, operator, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperIndexPostfix(
- node, semantics.element, node.arguments.single, operator, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidIndexPostfix(
- node, semantics.element, node.arguments.single, operator, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperIndexPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterIndexPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterIndexPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- operator,
- arg);
- default:
- // This is not a valid case.
- break;
- }
- break;
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid index postfix: ${semantics}");
- }
-}
-
-/// The structure for a [Send] that is a compound assignment. For instance
-/// `a += b`.
-class CompoundStructure<R, A> implements SendStructure<R, A> {
- /// The target of the compound assignment, i.e. the left-hand side.
- final AccessSemantics semantics;
-
- /// The assignment operator used in the compound assignment.
- final AssignmentOperator operator;
-
- CompoundStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.COMPOUND;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return visitor.visitIfNotNullDynamicPropertyCompound(
- node,
- node.receiver,
- semantics.name,
- operator,
- node.arguments.single,
- arg);
- case AccessKind.DYNAMIC_PROPERTY:
- return visitor.visitDynamicPropertyCompound(node, node.receiver,
- semantics.name, operator, node.arguments.single, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.LOCAL_VARIABLE:
- return visitor.visitLocalVariableCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.FINAL_LOCAL_VARIABLE:
- return visitor.visitFinalLocalVariableCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.PARAMETER:
- return visitor.visitParameterCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.FINAL_PARAMETER:
- return visitor.visitFinalParameterCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.STATIC_FIELD:
- return visitor.visitStaticFieldCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.FINAL_STATIC_FIELD:
- return visitor.visitFinalStaticFieldCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticMethodCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.STATIC_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.STATIC_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_FIELD:
- return visitor.visitTopLevelFieldCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- return visitor.visitFinalTopLevelFieldCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelMethodCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CLASS_TYPE_LITERAL:
- return visitor.visitClassTypeLiteralCompound(
- node, semantics.constant, operator, node.arguments.single, arg);
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- return visitor.visitTypedefTypeLiteralCompound(
- node, semantics.constant, operator, node.arguments.single, arg);
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return visitor.visitDynamicTypeLiteralCompound(
- node, semantics.constant, operator, node.arguments.single, arg);
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- return visitor.visitTypeVariableTypeLiteralCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.EXPRESSION:
- // This is not a valid case.
- break;
- case AccessKind.THIS:
- // This is not a valid case.
- break;
- case AccessKind.THIS_PROPERTY:
- return visitor.visitThisPropertyCompound(
- node, semantics.name, operator, node.arguments.single, arg);
- case AccessKind.SUPER_FIELD:
- return visitor.visitSuperFieldCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.SUPER_FINAL_FIELD:
- return visitor.visitFinalSuperFieldCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.SUPER_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.SUPER_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CONSTANT:
- // TODO(johnniwinther): Should this be a valid case?
- break;
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidCompound(
- node, semantics.element, operator, node.arguments.single, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.STATIC_GETTER_SETTER:
- return visitor.visitStaticGetterSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.STATIC_METHOD_SETTER:
- return visitor.visitStaticMethodSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
- return visitor.visitUnresolvedStaticGetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
- return visitor.visitUnresolvedStaticSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
- return visitor.visitTopLevelGetterSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
- return visitor.visitTopLevelMethodSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
- return visitor.visitUnresolvedTopLevelGetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
- return visitor.visitUnresolvedTopLevelSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_FIELD_FIELD:
- return visitor.visitSuperFieldFieldCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperGetterSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_GETTER_FIELD:
- return visitor.visitSuperGetterFieldCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_METHOD_SETTER:
- return visitor.visitSuperMethodSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_FIELD_SETTER:
- return visitor.visitSuperFieldSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterCompound(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- node.arguments.single,
- arg);
- }
- break;
- }
- throw failedAt(node, "Invalid compound assigment: ${semantics}");
- }
-
- String toString() => 'compound($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is an if-null assignment. For instance
-/// `a ??= b`.
-class SetIfNullStructure<R, A> implements SendStructure<R, A> {
- /// The target of the if-null assignment, i.e. the left-hand side.
- final AccessSemantics semantics;
-
- SetIfNullStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.SET_IF_NULL;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return visitor.visitIfNotNullDynamicPropertySetIfNull(
- node, node.receiver, semantics.name, node.arguments.single, arg);
- case AccessKind.DYNAMIC_PROPERTY:
- return visitor.visitDynamicPropertySetIfNull(
- node, node.receiver, semantics.name, node.arguments.single, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.LOCAL_VARIABLE:
- return visitor.visitLocalVariableSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_LOCAL_VARIABLE:
- return visitor.visitFinalLocalVariableSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.PARAMETER:
- return visitor.visitParameterSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_PARAMETER:
- return visitor.visitFinalParameterSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.STATIC_FIELD:
- return visitor.visitStaticFieldSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_STATIC_FIELD:
- return visitor.visitFinalStaticFieldSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticMethodSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.STATIC_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.STATIC_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_FIELD:
- return visitor.visitTopLevelFieldSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- return visitor.visitFinalTopLevelFieldSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelMethodSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.TOPLEVEL_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CLASS_TYPE_LITERAL:
- return visitor.visitClassTypeLiteralSetIfNull(
- node, semantics.constant, node.arguments.single, arg);
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- return visitor.visitTypedefTypeLiteralSetIfNull(
- node, semantics.constant, node.arguments.single, arg);
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return visitor.visitDynamicTypeLiteralSetIfNull(
- node, semantics.constant, node.arguments.single, arg);
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- return visitor.visitTypeVariableTypeLiteralSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.EXPRESSION:
- // This is not a valid case.
- break;
- case AccessKind.THIS:
- // This is not a valid case.
- break;
- case AccessKind.THIS_PROPERTY:
- return visitor.visitThisPropertySetIfNull(
- node, semantics.name, node.arguments.single, arg);
- case AccessKind.SUPER_FIELD:
- return visitor.visitSuperFieldSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.SUPER_FINAL_FIELD:
- return visitor.visitFinalSuperFieldSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.SUPER_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.SUPER_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CONSTANT:
- // TODO(johnniwinther): Should this be a valid case?
- break;
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidSetIfNull(
- node, semantics.element, node.arguments.single, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.STATIC_GETTER_SETTER:
- return visitor.visitStaticGetterSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.STATIC_METHOD_SETTER:
- return visitor.visitStaticMethodSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
- return visitor.visitUnresolvedStaticGetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
- return visitor.visitUnresolvedStaticSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
- return visitor.visitTopLevelGetterSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
- return visitor.visitTopLevelMethodSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
- return visitor.visitUnresolvedTopLevelGetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
- return visitor.visitUnresolvedTopLevelSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_FIELD_FIELD:
- return visitor.visitSuperFieldFieldSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperGetterSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_GETTER_FIELD:
- return visitor.visitSuperGetterFieldSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_METHOD_SETTER:
- return visitor.visitSuperMethodSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.SUPER_FIELD_SETTER:
- return visitor.visitSuperFieldSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.single,
- arg);
- }
- break;
- }
- throw failedAt(node, "Invalid if-null assigment: ${semantics}");
- }
-
- String toString() => 'ifNull($semantics)';
-}
-
-/// The structure for a [Send] that is a compound assignment on the index
-/// operator. For instance `a[b] += c`.
-class CompoundIndexSetStructure<R, A> implements SendStructure<R, A> {
- /// The target of the index operations.
- final AccessSemantics semantics;
-
- /// The assignment operator used in the compound assignment.
- final AssignmentOperator operator;
-
- CompoundIndexSetStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.COMPOUND_INDEX_SET;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitCompoundIndexSet(node, node.receiver,
- node.arguments.first, operator, node.arguments.tail.head, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperCompoundIndexSet(
- node,
- semantics.element,
- node.arguments.first,
- operator,
- node.arguments.tail.head,
- arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidCompoundIndexSet(node, semantics.element,
- node.arguments.first, operator, node.arguments.tail.head, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperCompoundIndexSet(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.first,
- operator,
- node.arguments.tail.head,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterCompoundIndexSet(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.first,
- operator,
- node.arguments.tail.head,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterCompoundIndexSet(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.first,
- operator,
- node.arguments.tail.head,
- arg);
- default:
- // This is not a valid case.
- break;
- }
- break;
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid compound index set: ${semantics}");
- }
-
- String toString() => 'compound []=($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is a if-null assignment on the index
-/// operator. For instance `a[b] ??= c`.
-class IndexSetIfNullStructure<R, A> implements SendStructure<R, A> {
- /// The target of the index operations.
- final AccessSemantics semantics;
-
- IndexSetIfNullStructure(this.semantics);
-
- @override
- SendStructureKind get kind => SendStructureKind.INDEX_SET_IF_NULL;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- return visitor.visitIndexSetIfNull(node, node.receiver,
- node.arguments.first, node.arguments.tail.head, arg);
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperIndexSetIfNull(
- node,
- semantics.element,
- node.arguments.first,
- node.arguments.tail.head,
- arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidIndexSetIfNull(node, semantics.element,
- node.arguments.first, node.arguments.tail.head, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperIndexSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.first,
- node.arguments.tail.head,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterIndexSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.first,
- node.arguments.tail.head,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterIndexSetIfNull(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- node.arguments.first,
- node.arguments.tail.head,
- arg);
- default:
- // This is not a valid case.
- break;
- }
- break;
- default:
- // This is not a valid case.
- break;
- }
- throw failedAt(node, "Invalid index set if-null: ${semantics}");
- }
-
- String toString() => 'index set if-null []??=($semantics)';
-}
-
-/// The structure for a [Send] that is a prefix operations. For instance
-/// `++a`.
-class PrefixStructure<R, A> implements SendStructure<R, A> {
- /// The target of the prefix operation.
- final AccessSemantics semantics;
-
- /// The `++` or `--` operator used in the operation.
- final IncDecOperator operator;
-
- PrefixStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.PREFIX;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return visitor.visitIfNotNullDynamicPropertyPrefix(
- node, node.receiver, semantics.name, operator, arg);
- case AccessKind.DYNAMIC_PROPERTY:
- return visitor.visitDynamicPropertyPrefix(
- node, node.receiver, semantics.name, operator, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.LOCAL_VARIABLE:
- return visitor.visitLocalVariablePrefix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_LOCAL_VARIABLE:
- return visitor.visitFinalLocalVariablePrefix(
- node, semantics.element, operator, arg);
- case AccessKind.PARAMETER:
- return visitor.visitParameterPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_PARAMETER:
- return visitor.visitFinalParameterPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.STATIC_FIELD:
- return visitor.visitStaticFieldPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_STATIC_FIELD:
- return visitor.visitFinalStaticFieldPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticMethodPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.STATIC_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.STATIC_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_FIELD:
- return visitor.visitTopLevelFieldPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- return visitor.visitFinalTopLevelFieldPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelMethodPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.TOPLEVEL_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CLASS_TYPE_LITERAL:
- return visitor.visitClassTypeLiteralPrefix(
- node, semantics.constant, operator, arg);
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- return visitor.visitTypedefTypeLiteralPrefix(
- node, semantics.constant, operator, arg);
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return visitor.visitDynamicTypeLiteralPrefix(
- node, semantics.constant, operator, arg);
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- return visitor.visitTypeVariableTypeLiteralPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.EXPRESSION:
- // This is not a valid case.
- break;
- case AccessKind.THIS:
- // This is not a valid case.
- break;
- case AccessKind.THIS_PROPERTY:
- return visitor.visitThisPropertyPrefix(
- node, semantics.name, operator, arg);
- case AccessKind.SUPER_FIELD:
- return visitor.visitSuperFieldPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.SUPER_FINAL_FIELD:
- return visitor.visitFinalSuperFieldPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.SUPER_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.SUPER_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CONSTANT:
- // TODO(johnniwinther): Should this be a valid case?
- break;
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidPrefix(
- node, semantics.element, operator, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.STATIC_GETTER_SETTER:
- return visitor.visitStaticGetterSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.STATIC_METHOD_SETTER:
- return visitor.visitStaticMethodSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
- return visitor.visitUnresolvedStaticGetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
- return visitor.visitUnresolvedStaticSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.STATIC_METHOD_SETTER:
- return visitor.visitStaticMethodSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
- return visitor.visitTopLevelGetterSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
- return visitor.visitTopLevelMethodSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
- return visitor.visitUnresolvedTopLevelGetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
- return visitor.visitUnresolvedTopLevelSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_FIELD_FIELD:
- return visitor.visitSuperFieldFieldPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperGetterSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_GETTER_FIELD:
- return visitor.visitSuperGetterFieldPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_METHOD_SETTER:
- return visitor.visitSuperMethodSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_FIELD_SETTER:
- return visitor.visitSuperFieldSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterPrefix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- }
- }
- throw failedAt(node, "Invalid compound assigment: ${semantics}");
- }
-
- String toString() => 'prefix($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is a postfix operations. For instance
-/// `a++`.
-class PostfixStructure<R, A> implements SendStructure<R, A> {
- /// The target of the postfix operation.
- final AccessSemantics semantics;
-
- /// The `++` or `--` operator used in the operation.
- final IncDecOperator operator;
-
- PostfixStructure(this.semantics, this.operator);
-
- @override
- SendStructureKind get kind => SendStructureKind.POSTFIX;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
- switch (semantics.kind) {
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return visitor.visitIfNotNullDynamicPropertyPostfix(
- node, node.receiver, semantics.name, operator, arg);
- case AccessKind.DYNAMIC_PROPERTY:
- return visitor.visitDynamicPropertyPostfix(
- node, node.receiver, semantics.name, operator, arg);
- case AccessKind.LOCAL_FUNCTION:
- return visitor.visitLocalFunctionPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.LOCAL_VARIABLE:
- return visitor.visitLocalVariablePostfix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_LOCAL_VARIABLE:
- return visitor.visitFinalLocalVariablePostfix(
- node, semantics.element, operator, arg);
- case AccessKind.PARAMETER:
- return visitor.visitParameterPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_PARAMETER:
- return visitor.visitFinalParameterPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.STATIC_FIELD:
- return visitor.visitStaticFieldPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_STATIC_FIELD:
- return visitor.visitFinalStaticFieldPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.STATIC_METHOD:
- return visitor.visitStaticMethodPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.STATIC_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.STATIC_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_FIELD:
- return visitor.visitTopLevelFieldPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- return visitor.visitFinalTopLevelFieldPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.TOPLEVEL_METHOD:
- return visitor.visitTopLevelMethodPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.TOPLEVEL_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.TOPLEVEL_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CLASS_TYPE_LITERAL:
- return visitor.visitClassTypeLiteralPostfix(
- node, semantics.constant, operator, arg);
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- return visitor.visitTypedefTypeLiteralPostfix(
- node, semantics.constant, operator, arg);
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return visitor.visitDynamicTypeLiteralPostfix(
- node, semantics.constant, operator, arg);
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- return visitor.visitTypeVariableTypeLiteralPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.EXPRESSION:
- // This is not a valid case.
- break;
- case AccessKind.THIS:
- // This is not a valid case.
- break;
- case AccessKind.THIS_PROPERTY:
- return visitor.visitThisPropertyPostfix(
- node, semantics.name, operator, arg);
- case AccessKind.SUPER_FIELD:
- return visitor.visitSuperFieldPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.SUPER_FINAL_FIELD:
- return visitor.visitFinalSuperFieldPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.SUPER_METHOD:
- return visitor.visitSuperMethodPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.SUPER_GETTER:
- // This is not a valid case.
- break;
- case AccessKind.SUPER_SETTER:
- // This is not a valid case.
- break;
- case AccessKind.CONSTANT:
- // TODO(johnniwinther): Should this be a valid case?
- break;
- case AccessKind.UNRESOLVED_SUPER:
- return visitor.visitUnresolvedSuperPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.UNRESOLVED:
- return visitor.visitUnresolvedPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.INVALID:
- return visitor.errorInvalidPostfix(
- node, semantics.element, operator, arg);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundSemantics = semantics;
- switch (compoundSemantics.compoundAccessKind) {
- case CompoundAccessKind.STATIC_GETTER_SETTER:
- return visitor.visitStaticGetterSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
- return visitor.visitUnresolvedStaticGetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
- return visitor.visitUnresolvedStaticSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.STATIC_METHOD_SETTER:
- return visitor.visitStaticMethodSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
- return visitor.visitTopLevelGetterSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
- return visitor.visitTopLevelMethodSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
- return visitor.visitUnresolvedTopLevelGetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
- return visitor.visitUnresolvedTopLevelSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_FIELD_FIELD:
- return visitor.visitSuperFieldFieldPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_GETTER_SETTER:
- return visitor.visitSuperGetterSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_GETTER_FIELD:
- return visitor.visitSuperGetterFieldPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_METHOD_SETTER:
- return visitor.visitSuperMethodSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.SUPER_FIELD_SETTER:
- return visitor.visitSuperFieldSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
- return visitor.visitUnresolvedSuperGetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
- return visitor.visitUnresolvedSuperSetterPostfix(
- node,
- compoundSemantics.getter,
- compoundSemantics.setter,
- operator,
- arg);
- }
- }
- throw failedAt(node, "Invalid compound assigment: ${semantics}");
- }
-
- String toString() => 'postfix($operator,$semantics)';
-}
-
-/// The structure for a [Send] whose prefix is a prefix for a deferred library.
-/// For instance `deferred.a` where `deferred` is a deferred prefix.
-class DeferredPrefixStructure<R, A> implements SendStructure<R, A> {
- /// The deferred prefix element.
- final PrefixElement prefix;
-
- /// The send structure for the whole [Send] node. For instance a
- /// [GetStructure] for `deferred.a` where `a` is a top level member of the
- /// deferred library.
- final SendStructure sendStructure;
-
- DeferredPrefixStructure(this.prefix, this.sendStructure) {
- assert(sendStructure != null);
- }
-
- @override
- SendStructureKind get kind => SendStructureKind.DEFERRED_PREFIX;
-
- @override
- R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg) {
- visitor.previsitDeferredAccess(send, prefix, arg);
- return sendStructure.dispatch(visitor, send, arg);
- }
-}
-
-enum NewStructureKind {
- NEW_INVOKE,
- CONST_INVOKE,
- LATE_CONST,
-}
-
-/// The structure for a [NewExpression] of a new invocation.
-abstract class NewStructure<R, A> implements SemanticSendStructure<R, A> {
- /// Calls the matching visit method on [visitor] with [node] and [arg].
- R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg);
-
- NewStructureKind get kind;
-}
-
-/// The structure for a [NewExpression] of a new invocation. For instance
-/// `new C()`.
-class NewInvokeStructure<R, A> extends NewStructure<R, A> {
- final ConstructorAccessSemantics semantics;
- final Selector selector;
-
- NewInvokeStructure(this.semantics, this.selector);
-
- @override
- NewStructureKind get kind => NewStructureKind.NEW_INVOKE;
-
- CallStructure get callStructure => selector.callStructure;
-
- R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
- switch (semantics.kind) {
- case ConstructorAccessKind.GENERATIVE:
- ConstructorElement constructor = semantics.element;
- if (constructor.isRedirectingGenerative) {
- return visitor.visitRedirectingGenerativeConstructorInvoke(
- node,
- constructor,
- semantics.type,
- node.send.argumentsNode,
- callStructure,
- arg);
- }
- return visitor.visitGenerativeConstructorInvoke(node, constructor,
- semantics.type, node.send.argumentsNode, callStructure, arg);
- case ConstructorAccessKind.FACTORY:
- ConstructorElement constructor = semantics.element;
- if (constructor.isRedirectingFactory) {
- if (constructor.isEffectiveTargetMalformed) {
- return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
- node,
- semantics.element,
- semantics.type,
- node.send.argumentsNode,
- callStructure,
- arg);
- }
- ConstructorElement effectiveTarget = constructor.effectiveTarget;
- ResolutionInterfaceType effectiveTargetType =
- constructor.computeEffectiveTargetType(semantics.type);
- if (callStructure
- .signatureApplies(effectiveTarget.parameterStructure)) {
- return visitor.visitRedirectingFactoryConstructorInvoke(
- node,
- semantics.element,
- semantics.type,
- effectiveTarget,
- effectiveTargetType,
- node.send.argumentsNode,
- callStructure,
- arg);
- } else {
- return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
- node,
- semantics.element,
- semantics.type,
- node.send.argumentsNode,
- callStructure,
- arg);
- }
- }
- if (callStructure.signatureApplies(constructor.parameterStructure)) {
- return visitor.visitFactoryConstructorInvoke(node, constructor,
- semantics.type, node.send.argumentsNode, callStructure, arg);
- }
- return visitor.visitConstructorIncompatibleInvoke(node, constructor,
- semantics.type, node.send.argumentsNode, callStructure, arg);
- case ConstructorAccessKind.ABSTRACT:
- return visitor.visitAbstractClassConstructorInvoke(
- node,
- semantics.element,
- semantics.type,
- node.send.argumentsNode,
- callStructure,
- arg);
- case ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR:
- return visitor.visitUnresolvedConstructorInvoke(node, semantics.element,
- semantics.type, node.send.argumentsNode, selector, arg);
- case ConstructorAccessKind.UNRESOLVED_TYPE:
- return visitor.visitUnresolvedClassConstructorInvoke(
- node,
- semantics.element,
- semantics.type,
- node.send.argumentsNode,
- selector,
- arg);
- case ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR:
- return visitor.errorNonConstantConstructorInvoke(
- node,
- semantics.element,
- semantics.type,
- node.send.argumentsNode,
- callStructure,
- arg);
- case ConstructorAccessKind.INCOMPATIBLE:
- return visitor.visitConstructorIncompatibleInvoke(
- node,
- semantics.element,
- semantics.type,
- node.send.argumentsNode,
- callStructure,
- arg);
- }
- throw failedAt(
- node, "Unhandled constructor invocation kind: ${semantics.kind}");
- }
-
- String toString() => 'new($semantics,$selector)';
-}
-
-enum ConstantInvokeKind {
- CONSTRUCTED,
- BOOL_FROM_ENVIRONMENT,
- INT_FROM_ENVIRONMENT,
- STRING_FROM_ENVIRONMENT,
-}
-
-/// The structure for a [NewExpression] of a constant invocation. For instance
-/// `const C()`.
-class ConstInvokeStructure<R, A> extends NewStructure<R, A> {
- final ConstantInvokeKind constantInvokeKind;
- final ConstantExpression constant;
-
- ConstInvokeStructure(this.constantInvokeKind, this.constant);
-
- @override
- NewStructureKind get kind => NewStructureKind.CONST_INVOKE;
-
- // ignore: MISSING_RETURN
- R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
- switch (constantInvokeKind) {
- case ConstantInvokeKind.CONSTRUCTED:
- return visitor.visitConstConstructorInvoke(node, constant, arg);
- case ConstantInvokeKind.BOOL_FROM_ENVIRONMENT:
- return visitor.visitBoolFromEnvironmentConstructorInvoke(
- node, constant, arg);
- case ConstantInvokeKind.INT_FROM_ENVIRONMENT:
- return visitor.visitIntFromEnvironmentConstructorInvoke(
- node, constant, arg);
- case ConstantInvokeKind.STRING_FROM_ENVIRONMENT:
- return visitor.visitStringFromEnvironmentConstructorInvoke(
- node, constant, arg);
- }
- }
-}
-
-/// A constant constructor invocation that couldn't be determined fully during
-/// resolution.
-// TODO(johnniwinther): Remove this when all constants are computed during
-// resolution.
-class LateConstInvokeStructure<R, A> extends NewStructure<R, A> {
- final TreeElements elements;
-
- LateConstInvokeStructure(this.elements);
-
- @override
- NewStructureKind get kind => NewStructureKind.LATE_CONST;
-
- /// Convert this new structure into a regular new structure using the data
- /// available in [elements].
- NewStructure resolve(NewExpression node) {
- Element element = elements[node.send];
- Selector selector = elements.getSelector(node.send);
- ResolutionDartType type = elements.getType(node);
- ConstantExpression constant = elements.getConstant(node);
- if (element.isMalformed ||
- constant == null ||
- constant.kind == ConstantExpressionKind.ERRONEOUS) {
- // This is a non-constant constant constructor invocation, like
- // `const Const(method())`.
- return new NewInvokeStructure(
- new ConstructorAccessSemantics(
- ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type),
- selector);
- } else {
- ConstantInvokeKind kind;
- switch (constant.kind) {
- case ConstantExpressionKind.CONSTRUCTED:
- kind = ConstantInvokeKind.CONSTRUCTED;
- break;
- case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
- kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT;
- break;
- case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
- kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT;
- break;
- case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
- kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT;
- break;
- default:
- throw failedAt(
- node, "Unexpected constant kind $kind: ${constant.toDartText()}");
- }
- return new ConstInvokeStructure(kind, constant);
- }
- }
-
- R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
- Element element = elements[node.send];
- Selector selector = elements.getSelector(node.send);
- ResolutionDartType type = elements.getType(node);
- ConstantExpression constant = elements.getConstant(node);
- if (element.isMalformed ||
- constant == null ||
- constant.kind == ConstantExpressionKind.ERRONEOUS) {
- // This is a non-constant constant constructor invocation, like
- // `const Const(method())`.
- return visitor.errorNonConstantConstructorInvoke(node, element, type,
- node.send.argumentsNode, selector.callStructure, arg);
- } else {
- ConstantInvokeKind kind;
- switch (constant.kind) {
- case ConstantExpressionKind.CONSTRUCTED:
- return visitor.visitConstConstructorInvoke(node, constant, arg);
- case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
- return visitor.visitBoolFromEnvironmentConstructorInvoke(
- node, constant, arg);
- case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
- return visitor.visitIntFromEnvironmentConstructorInvoke(
- node, constant, arg);
- case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
- return visitor.visitStringFromEnvironmentConstructorInvoke(
- node, constant, arg);
- default:
- throw failedAt(
- node, "Unexpected constant kind $kind: ${constant.toDartText()}");
- }
- }
- }
-}
-
-/// The structure of a parameter declaration.
-abstract class ParameterStructure<R, A> {
- final VariableDefinitions definitions;
- final Node node;
- final ParameterElement parameter;
-
- ParameterStructure(this.definitions, this.node, this.parameter);
-
- /// Calls the matching visit method on [visitor] with [definitions] and [arg].
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg);
-}
-
-/// The structure of a required parameter declaration.
-class RequiredParameterStructure<R, A> extends ParameterStructure<R, A> {
- final int index;
-
- RequiredParameterStructure(VariableDefinitions definitions, Node node,
- ParameterElement parameter, this.index)
- : super(definitions, node, parameter);
-
- @override
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
- if (parameter.isInitializingFormal) {
- return visitor.visitInitializingFormalDeclaration(
- definitions, node, parameter, index, arg);
- } else {
- return visitor.visitParameterDeclaration(
- definitions, node, parameter, index, arg);
- }
- }
-}
-
-/// The structure of a optional positional parameter declaration.
-class OptionalParameterStructure<R, A> extends ParameterStructure<R, A> {
- final ConstantExpression defaultValue;
- final int index;
-
- OptionalParameterStructure(VariableDefinitions definitions, Node node,
- ParameterElement parameter, this.defaultValue, this.index)
- : super(definitions, node, parameter);
-
- @override
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
- if (parameter.isInitializingFormal) {
- return visitor.visitOptionalInitializingFormalDeclaration(
- definitions, node, parameter, defaultValue, index, arg);
- } else {
- return visitor.visitOptionalParameterDeclaration(
- definitions, node, parameter, defaultValue, index, arg);
- }
- }
-}
-
-/// The structure of a optional named parameter declaration.
-class NamedParameterStructure<R, A> extends ParameterStructure<R, A> {
- final ConstantExpression defaultValue;
-
- NamedParameterStructure(VariableDefinitions definitions, Node node,
- ParameterElement parameter, this.defaultValue)
- : super(definitions, node, parameter);
-
- @override
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
- if (parameter.isInitializingFormal) {
- return visitor.visitNamedInitializingFormalDeclaration(
- definitions, node, parameter, defaultValue, arg);
- } else {
- return visitor.visitNamedParameterDeclaration(
- definitions, node, parameter, defaultValue, arg);
- }
- }
-}
-
-enum VariableKind {
- TOP_LEVEL_FIELD,
- STATIC_FIELD,
- INSTANCE_FIELD,
- LOCAL_VARIABLE,
-}
-
-abstract class VariableStructure<R, A> {
- final VariableKind kind;
- final Node node;
- final VariableElement variable;
-
- VariableStructure(this.kind, this.node, this.variable);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor,
- VariableDefinitions definitions, A arg);
-}
-
-class NonConstantVariableStructure<R, A> extends VariableStructure<R, A> {
- NonConstantVariableStructure(
- VariableKind kind, Node node, VariableElement variable)
- : super(kind, node, variable);
-
- // ignore: MISSING_RETURN
- R dispatch(SemanticDeclarationVisitor<R, A> visitor,
- VariableDefinitions definitions, A arg) {
- switch (kind) {
- case VariableKind.TOP_LEVEL_FIELD:
- return visitor.visitTopLevelFieldDeclaration(
- definitions, node, variable, variable.initializer, arg);
- case VariableKind.STATIC_FIELD:
- return visitor.visitStaticFieldDeclaration(
- definitions, node, variable, variable.initializer, arg);
- case VariableKind.INSTANCE_FIELD:
- return visitor.visitInstanceFieldDeclaration(
- definitions, node, variable, variable.initializer, arg);
- case VariableKind.LOCAL_VARIABLE:
- return visitor.visitLocalVariableDeclaration(
- definitions, node, variable, variable.initializer, arg);
- }
- }
-}
-
-class ConstantVariableStructure<R, A> extends VariableStructure<R, A> {
- final ConstantExpression constant;
-
- ConstantVariableStructure(
- VariableKind kind, Node node, VariableElement variable, this.constant)
- : super(kind, node, variable);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor,
- VariableDefinitions definitions, A arg) {
- switch (kind) {
- case VariableKind.TOP_LEVEL_FIELD:
- return visitor.visitTopLevelConstantDeclaration(
- definitions, node, variable, constant, arg);
- case VariableKind.STATIC_FIELD:
- return visitor.visitStaticConstantDeclaration(
- definitions, node, variable, constant, arg);
- case VariableKind.LOCAL_VARIABLE:
- return visitor.visitLocalConstantDeclaration(
- definitions, node, variable, constant, arg);
- default:
- }
- throw failedAt(node, "Invalid constant variable: $variable");
- }
-}
-
-class InitializersStructure<R, A> {
- final List<InitializerStructure<R, A>> initializers;
-
- InitializersStructure(this.initializers);
-}
-
-abstract class InitializerStructure<R, A> {
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg);
-
- bool get isConstructorInvoke => false;
-}
-
-class FieldInitializerStructure<R, A> extends InitializerStructure<R, A> {
- final Send node;
- final FieldElement field;
-
- FieldInitializerStructure(this.node, this.field);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
- return visitor.visitFieldInitializer(
- node, field, node.arguments.single, arg);
- }
-}
-
-class SuperConstructorInvokeStructure<R, A> extends InitializerStructure<R, A> {
- final Send node;
- final ConstructorElement constructor;
- final ResolutionInterfaceType type;
- final CallStructure callStructure;
-
- SuperConstructorInvokeStructure(
- this.node, this.constructor, this.type, this.callStructure);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
- return visitor.visitSuperConstructorInvoke(
- node, constructor, type, node.argumentsNode, callStructure, arg);
- }
-
- bool get isConstructorInvoke => true;
-}
-
-class ImplicitSuperConstructorInvokeStructure<R, A>
- extends InitializerStructure<R, A> {
- final FunctionExpression node;
- final ConstructorElement constructor;
- final ResolutionInterfaceType type;
-
- ImplicitSuperConstructorInvokeStructure(
- this.node, this.constructor, this.type);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
- return visitor.visitImplicitSuperConstructorInvoke(
- node, constructor, type, arg);
- }
-
- bool get isConstructorInvoke => true;
-}
-
-class ThisConstructorInvokeStructure<R, A> extends InitializerStructure<R, A> {
- final Send node;
- final ConstructorElement constructor;
- final CallStructure callStructure;
-
- ThisConstructorInvokeStructure(
- this.node, this.constructor, this.callStructure);
-
- R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
- return visitor.visitThisConstructorInvoke(
- node, constructor, node.argumentsNode, callStructure, arg);
- }
-
- bool get isConstructorInvoke => true;
-}
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
deleted file mode 100644
index 36890b2..0000000
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ /dev/null
@@ -1,513 +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 dart2js.resolution.signatures;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../elements/modelx.dart'
- show
- ErroneousFieldElementX,
- ErroneousInitializingFormalElementX,
- FormalElementX,
- FunctionSignatureX,
- InitializingFormalElementX,
- LocalParameterElementX,
- TypeVariableElementX;
-import '../elements/names.dart';
-import '../tree/tree.dart';
-import '../util/util.dart' show Link, LinkBuilder;
-import 'members.dart' show ResolverVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show MappingVisitor;
-import 'scope.dart' show Scope, TypeVariablesScope;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-/**
- * [SignatureResolver] resolves function signatures.
- */
-class SignatureResolver extends MappingVisitor<FormalElementX> {
- final ResolverVisitor resolver;
- final FunctionTypedElement enclosingElement;
- final Scope scope;
- final MessageKind defaultValuesError;
- final bool createRealParameters;
- final FunctionTypeParameterScope functionTypeParameters;
- List<FormalElement> optionalParameters = const <FormalElement>[];
- int optionalParameterCount = 0;
- bool isOptionalParameter = false;
- bool optionalParametersAreNamed = false;
- VariableDefinitions currentDefinitions;
-
- SignatureResolver(Resolution resolution, this.enclosingElement, this.scope,
- this.functionTypeParameters, ResolutionRegistry registry,
- {this.defaultValuesError, this.createRealParameters})
- : this.resolver = new ResolverVisitor(
- resolution, enclosingElement, registry,
- scope: scope),
- super(resolution, registry);
-
- bool get defaultValuesAllowed => defaultValuesError == null;
-
- visitNodeList(NodeList node) {
- // This must be a list of optional arguments.
- String value = node.beginToken.stringValue;
- if ((!identical(value, '[')) && (!identical(value, '{'))) {
- reporter.internalError(node, "expected optional parameters");
- }
- optionalParametersAreNamed = (identical(value, '{'));
- isOptionalParameter = true;
- LinkBuilder<FormalElement> elements = analyzeNodes(node.nodes);
- optionalParameterCount = elements.length;
- optionalParameters = elements.toList();
- }
-
- FormalElementX visitVariableDefinitions(VariableDefinitions node) {
- Link<Node> definitions = node.definitions.nodes;
- if (definitions.isEmpty) {
- reporter.internalError(node, 'no parameter definition');
- return null;
- }
- if (!definitions.tail.isEmpty) {
- reporter.internalError(definitions.tail.head, 'extra definition');
- return null;
- }
- Node definition = definitions.head;
- if (definition is NodeList) {
- reporter.internalError(node, 'optional parameters are not implemented');
- }
- if (node.modifiers.isConst) {
- reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_CONST);
- }
- if (node.modifiers.isStatic) {
- reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_STATIC);
- }
-
- if (currentDefinitions != null) {
- reporter.internalError(node, 'function type parameters not supported');
- }
- currentDefinitions = node;
- FormalElementX element = definition == null
- ? createUnnamedParameter() // This happens in function types.
- : definition.accept(this);
- if (currentDefinitions.metadata != null) {
- element.metadataInternal =
- resolution.resolver.resolveMetadata(element, node);
- }
- currentDefinitions = null;
- return element;
- }
-
- void validateName(Identifier node) {
- if (isOptionalParameter &&
- optionalParametersAreNamed &&
- Name.isPrivateName(node.source)) {
- reporter.reportErrorMessage(node, MessageKind.PRIVATE_NAMED_PARAMETER);
- }
- }
-
- void computeParameterType(FormalElementX element,
- [VariableElement fieldElement]) {
- // Function-type as in `foo(int bar(String x))`
- void computeInlineFunctionType(FunctionExpression functionExpression) {
- FunctionSignature functionSignature = SignatureResolver.analyze(
- resolution,
- scope,
- functionTypeParameters.expand(functionExpression.typeVariables),
- null, // Don't create type variable types for the type parameters.
- functionExpression.parameters,
- functionExpression.returnType,
- element,
- registry,
- defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT);
- element.functionSignature = functionSignature;
- }
-
- if (currentDefinitions.type != null) {
- element.typeCache = resolveTypeAnnotation(currentDefinitions.type);
- } else {
- // Is node.definitions exactly one FunctionExpression?
- Link<Node> link = currentDefinitions.definitions.nodes;
- assert(!link.isEmpty, failedAt(currentDefinitions));
- assert(link.tail.isEmpty, failedAt(currentDefinitions));
- if (link.head.asFunctionExpression() != null) {
- // Inline function typed parameter, like `void m(int f(String s))`.
- computeInlineFunctionType(link.head);
- } else if (link.head.asSend() != null &&
- link.head.asSend().selector.asFunctionExpression() != null) {
- // Inline function typed initializing formal or
- // parameter with default value, like `C(int this.f(String s))` or
- // `void m([int f(String s) = null])`.
- computeInlineFunctionType(
- link.head.asSend().selector.asFunctionExpression());
- } else {
- assert(link.head.asIdentifier() != null || link.head.asSend() != null,
- failedAt(currentDefinitions));
- if (fieldElement != null) {
- element.typeCache = fieldElement.computeType(resolution);
- } else {
- element.typeCache = const ResolutionDynamicType();
- }
- }
- }
- }
-
- FormalElementX visitIdentifier(Identifier node) {
- return createParameter(node, null);
- }
-
- Identifier getParameterName(Send node) {
- var identifier = node.selector.asIdentifier();
- if (identifier != null) {
- // Normal parameter: [:Type name:].
- return identifier;
- } else {
- // Function type parameter: [:void name(DartType arg):].
- var functionExpression = node.selector.asFunctionExpression();
- if (functionExpression != null &&
- functionExpression.name.asIdentifier() != null) {
- return functionExpression.name.asIdentifier();
- } else {
- reporter.internalError(
- node, 'internal error: unimplemented receiver on parameter send');
- return null;
- }
- }
- }
-
- // The only valid [Send] can be in constructors and must be of the form
- // [:this.x:] (where [:x:] represents an instance field).
- InitializingFormalElementX visitSend(Send node) {
- return createFieldParameter(node, null);
- }
-
- FormalElementX createParameter(Identifier name, Expression initializer) {
- validateName(name);
- FormalElementX parameter;
- if (createRealParameters) {
- parameter = new LocalParameterElementX(
- enclosingElement, currentDefinitions, name, initializer,
- isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed);
- } else {
- parameter = new FormalElementX(
- ElementKind.PARAMETER, enclosingElement, currentDefinitions, name);
- }
- computeParameterType(parameter);
- return parameter;
- }
-
- FormalElementX createUnnamedParameter() {
- FormalElementX parameter;
- assert(!createRealParameters);
- parameter = new FormalElementX.unnamed(
- ElementKind.PARAMETER, enclosingElement, currentDefinitions);
- computeParameterType(parameter);
- return parameter;
- }
-
- InitializingFormalElementX createFieldParameter(
- Send node, Expression initializer) {
- InitializingFormalElementX element;
- Identifier receiver = node.receiver.asIdentifier();
- if (receiver == null || !receiver.isThis()) {
- reporter.reportErrorMessage(node, MessageKind.INVALID_PARAMETER);
- return new ErroneousInitializingFormalElementX(
- getParameterName(node), enclosingElement);
- } else {
- if (!enclosingElement.isGenerativeConstructor) {
- reporter.reportErrorMessage(
- node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
- return new ErroneousInitializingFormalElementX(
- getParameterName(node), enclosingElement);
- }
- Identifier name = getParameterName(node);
- validateName(name);
- Element fieldElement =
- enclosingElement.enclosingClass.lookupLocalMember(name.source);
- if (fieldElement == null ||
- !identical(fieldElement.kind, ElementKind.FIELD)) {
- reporter.reportErrorMessage(
- node, MessageKind.NOT_A_FIELD, {'fieldName': name});
- fieldElement =
- new ErroneousFieldElementX(name, enclosingElement.enclosingClass);
- } else if (!fieldElement.isInstanceMember) {
- reporter.reportErrorMessage(
- node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name});
- fieldElement =
- new ErroneousFieldElementX(name, enclosingElement.enclosingClass);
- }
- element = new InitializingFormalElementX(
- enclosingElement, currentDefinitions, name, initializer, fieldElement,
- isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed);
- computeParameterType(element, fieldElement);
- }
- return element;
- }
-
- /// A [SendSet] node is an optional parameter with a default value.
- FormalElementX visitSendSet(SendSet node) {
- FormalElementX element;
- if (node.receiver != null) {
- element = createFieldParameter(node, node.arguments.first);
- } else if (node.selector.asIdentifier() != null ||
- node.selector.asFunctionExpression() != null) {
- element = createParameter(getParameterName(node), node.arguments.first);
- }
- Node defaultValue = node.arguments.head;
- if (!defaultValuesAllowed) {
- reporter.reportErrorMessage(defaultValue, defaultValuesError);
- }
- return element;
- }
-
- FormalElementX visitFunctionExpression(FunctionExpression node) {
- // This is a function typed parameter.
- Modifiers modifiers = currentDefinitions.modifiers;
- if (modifiers.isFinal) {
- reporter.reportErrorMessage(
- modifiers, MessageKind.FINAL_FUNCTION_TYPE_PARAMETER);
- }
- if (modifiers.isVar) {
- reporter.reportErrorMessage(
- modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER);
- }
-
- return createParameter(node.name, null);
- }
-
- LinkBuilder<FormalElement> analyzeNodes(Link<Node> link) {
- LinkBuilder<FormalElement> elements = new LinkBuilder<FormalElement>();
- for (; !link.isEmpty; link = link.tail) {
- Element element = link.head.accept(this);
- if (element != null) {
- elements.addLast(element);
- } else {
- // If parameter is null, the current node should be the last,
- // and a list of optional named parameters.
- if (!link.tail.isEmpty || (link.head is! NodeList)) {
- reporter.internalError(link.head, "expected optional parameters");
- }
- }
- }
- return elements;
- }
-
- /**
- * Resolves formal parameters and return type of a [FunctionExpression]
- * to a [FunctionSignature].
- *
- * If [createRealParameters] is `true`, the parameters will be
- * real parameters implementing the [ParameterElement] interface. Otherwise,
- * the parameters will only implement [FormalElement].
- */
- static FunctionSignature analyze(
- Resolution resolution,
- Scope scope,
- FunctionTypeParameterScope functionTypeParameters,
- NodeList typeVariables,
- NodeList formalParameters,
- Node returnNode,
- FunctionTypedElement element,
- ResolutionRegistry registry,
- {MessageKind defaultValuesError,
- bool createRealParameters: false,
- bool isFunctionExpression: false}) {
- DiagnosticReporter reporter = resolution.reporter;
-
- List<ResolutionDartType> createTypeVariables(NodeList typeVariableNodes) {
- if (element.isPatch) {
- FunctionTypedElement origin = element.origin;
- origin.computeType(resolution);
- return origin.typeVariables;
- }
- if (typeVariableNodes == null) return const <ResolutionDartType>[];
-
- // Create the types and elements corresponding to [typeVariableNodes].
- Link<Node> nodes = typeVariableNodes.nodes;
- List<ResolutionDartType> arguments =
- new List.generate(nodes.slowLength(), (int index) {
- TypeVariable node = nodes.head;
- String variableName = node.name.source;
- nodes = nodes.tail;
- TypeVariableElementX variableElement =
- new TypeVariableElementX(variableName, element, index, node);
- // GENERIC_METHODS: When method type variables are implemented fully we
- // must resolve the actual bounds; currently we just claim that
- // every method type variable has upper bound [dynamic].
- variableElement.boundCache = const ResolutionDynamicType();
- ResolutionTypeVariableType variableType =
- new MethodTypeVariableType(variableElement);
- variableElement.typeCache = variableType;
- return variableType;
- }, growable: false);
- return arguments;
- }
-
- List<ResolutionDartType> typeVariableTypes =
- createTypeVariables(typeVariables);
- scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes);
- SignatureResolver visitor = new SignatureResolver(
- resolution, element, scope, functionTypeParameters, registry,
- defaultValuesError: defaultValuesError,
- createRealParameters: createRealParameters);
- List<FormalElement> parameters = const <FormalElement>[];
- int requiredParameterCount = 0;
- if (formalParameters == null) {
- if (!element.isGetter) {
- if (element.isMalformed) {
- // If the element is erroneous, an error should already have been
- // reported. In the case of parse errors, it is possible that there
- // are formal parameters, but something else in the method failed to
- // parse. So we suppress the message about missing formals.
- assert(reporter.hasReportedError, failedAt(element));
- } else {
- reporter.reportErrorMessage(element, MessageKind.MISSING_FORMALS);
- }
- }
- } else {
- if (element.isGetter) {
- if (!identical(
- formalParameters.endToken.next.stringValue,
- // TODO(ahe): Remove the check for native keyword.
- 'native')) {
- reporter.reportErrorMessage(
- formalParameters, MessageKind.EXTRA_FORMALS);
- }
- }
- LinkBuilder<FormalElement> parametersBuilder =
- visitor.analyzeNodes(formalParameters.nodes);
- requiredParameterCount = parametersBuilder.length;
- parameters = parametersBuilder.toList();
- }
- ResolutionDartType returnType;
- if (element.isFactoryConstructor) {
- returnType = element.enclosingClass.thisType;
- // Because there is no type annotation for the return type of
- // this element, we explicitly add one.
- registry.registerCheckedModeCheck(returnType);
- } else {
- AsyncMarker asyncMarker = AsyncMarker.SYNC;
- if (isFunctionExpression) {
- // Use async marker to determine the return type of function
- // expressions.
- FunctionElement function = element;
- asyncMarker = function.asyncMarker;
- }
- switch (asyncMarker) {
- case AsyncMarker.SYNC:
- returnType = visitor.resolveReturnType(returnNode);
- break;
- case AsyncMarker.SYNC_STAR:
- ResolutionInterfaceType iterableType =
- resolution.commonElements.iterableType();
- returnType = iterableType;
- break;
- case AsyncMarker.ASYNC:
- ResolutionInterfaceType futureType =
- resolution.commonElements.futureType();
- returnType = futureType;
- break;
- case AsyncMarker.ASYNC_STAR:
- ResolutionInterfaceType streamType =
- resolution.commonElements.streamType();
- returnType = streamType;
- break;
- }
- }
-
- if (element.isSetter &&
- (requiredParameterCount != 1 || visitor.optionalParameterCount != 0)) {
- // If there are no formal parameters, we already reported an error above.
- if (formalParameters != null) {
- reporter.reportErrorMessage(
- formalParameters, MessageKind.ILLEGAL_SETTER_FORMALS);
- }
- }
- LinkBuilder<ResolutionDartType> parameterTypes =
- new LinkBuilder<ResolutionDartType>();
- for (FormalElement parameter in parameters) {
- parameterTypes.addLast(parameter.type);
- }
- List<ResolutionDartType> optionalParameterTypes =
- const <ResolutionDartType>[];
- List<String> namedParameters = const <String>[];
- List<ResolutionDartType> namedParameterTypes = const <ResolutionDartType>[];
- List<FormalElement> orderedOptionalParameters =
- visitor.optionalParameters.toList();
- if (visitor.optionalParametersAreNamed) {
- // TODO(karlklose); replace when [visitor.optionalParameters] is a [List].
- orderedOptionalParameters.sort((Element a, Element b) {
- return a.name.compareTo(b.name);
- });
- LinkBuilder<String> namedParametersBuilder = new LinkBuilder<String>();
- LinkBuilder<ResolutionDartType> namedParameterTypesBuilder =
- new LinkBuilder<ResolutionDartType>();
- for (FormalElement parameter in orderedOptionalParameters) {
- namedParametersBuilder.addLast(parameter.name);
- namedParameterTypesBuilder.addLast(parameter.type);
- }
- namedParameters = namedParametersBuilder.toLink().toList(growable: false);
- namedParameterTypes =
- namedParameterTypesBuilder.toLink().toList(growable: false);
- } else {
- // TODO(karlklose); replace when [visitor.optionalParameters] is a [List].
- LinkBuilder<ResolutionDartType> optionalParameterTypesBuilder =
- new LinkBuilder<ResolutionDartType>();
- for (FormalElement parameter in visitor.optionalParameters) {
- optionalParameterTypesBuilder.addLast(parameter.type);
- }
- optionalParameterTypes =
- optionalParameterTypesBuilder.toLink().toList(growable: false);
- }
- ResolutionFunctionType type = new ResolutionFunctionType(
- element.declaration,
- returnType,
- parameterTypes.toLink().toList(growable: false),
- optionalParameterTypes,
- namedParameters,
- namedParameterTypes);
- return new FunctionSignatureX(
- typeVariables: typeVariableTypes,
- requiredParameters: parameters,
- optionalParameters: visitor.optionalParameters,
- requiredParameterCount: requiredParameterCount,
- optionalParameterCount: visitor.optionalParameterCount,
- optionalParametersAreNamed: visitor.optionalParametersAreNamed,
- orderedOptionalParameters: orderedOptionalParameters,
- type: type);
- }
-
- ResolutionDartType resolveTypeAnnotation(TypeAnnotation annotation) {
- ResolutionDartType type = resolveReturnType(annotation);
- if (type.isVoid) {
- reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED);
- }
- return type;
- }
-
- ResolutionDartType resolveReturnType(TypeAnnotation annotation) {
- if (annotation == null) return const ResolutionDynamicType();
- ResolutionDartType result = resolver.resolveTypeAnnotation(annotation,
- functionTypeParameters: functionTypeParameters);
- if (result == null) {
- return const ResolutionDynamicType();
- }
- return result;
- }
-}
-
-/// Used during `SignatureResolver.analyze` to provide access to the type
-/// variables of the function signature itself when its signature is analyzed.
-class FunctionSignatureBuildingScope extends TypeVariablesScope {
- @override
- final List<ResolutionDartType> typeVariables;
-
- FunctionSignatureBuildingScope(Scope parent, this.typeVariables)
- : super(parent);
-
- String toString() => 'FunctionSignatureBuildingScope($typeVariables)';
-}
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
deleted file mode 100644
index f2f43be..0000000
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.tree_elements;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../diagnostics/source_span.dart';
-import '../elements/elements.dart';
-import '../elements/jumps.dart';
-import '../tree/tree.dart';
-import '../universe/selector.dart' show Selector;
-import '../util/util.dart';
-import 'secret_tree_element.dart' show getTreeElement, setTreeElement;
-import 'send_structure.dart';
-
-abstract class TreeElements {
- AnalyzableElement get analyzedElement;
- Iterable<SourceSpan> get superUses;
-
- void forEachConstantNode(f(Node n, ConstantExpression c));
-
- Element operator [](Node node);
- Map<Node, ResolutionDartType> get typesCache;
-
- /// Returns the [SendStructure] that describes the semantics of [node].
- SendStructure getSendStructure(Send node);
-
- /// Returns the [NewStructure] that describes the semantics of [node].
- NewStructure getNewStructure(NewExpression node);
-
- // TODO(johnniwinther): Investigate whether [Node] could be a [Send].
- Selector getSelector(Node node);
- Selector getGetterSelectorInComplexSendSet(SendSet node);
- Selector getOperatorSelectorInComplexSendSet(SendSet node);
- ResolutionDartType getType(Node node);
-
- /// Returns the for-in loop variable for [node].
- Element getForInVariable(ForIn node);
- void setConstant(Node node, ConstantExpression constant);
- ConstantExpression getConstant(Node node);
-
- /// Returns the [FunctionElement] defined by [node].
- FunctionElement getFunctionDefinition(FunctionExpression node);
-
- /// Returns target constructor for the redirecting factory body [node].
- ConstructorElement getRedirectingTargetConstructor(
- RedirectingFactoryBody node);
-
- /**
- * Returns [:true:] if [node] is a type literal.
- *
- * Resolution marks this by setting the type on the node to be the
- * type that the literal refers to.
- */
- bool isTypeLiteral(Send node);
-
- /// Returns the type that the type literal [node] refers to.
- ResolutionDartType getTypeLiteralType(Send node);
-
- /// Returns a list of nodes that potentially mutate [element] anywhere in its
- /// scope.
- List<Node> getPotentialMutations(VariableElement element);
-
- /// Returns a list of nodes that potentially mutate [element] in [node].
- List<Node> getPotentialMutationsIn(Node node, VariableElement element);
-
- /// Returns a list of nodes that potentially mutate [element] in a closure.
- List<Node> getPotentialMutationsInClosure(VariableElement element);
-
- /// Returns a list of nodes that access [element] within a closure in [node].
- List<Node> getAccessesByClosureIn(Node node, VariableElement element);
-
- /// Returns the jump target defined by [node].
- JumpTarget getTargetDefinition(Node node);
-
- /// Returns the jump target of the [node].
- JumpTarget getTargetOf(GotoStatement node);
-
- /// Returns the label defined by [node].
- LabelDefinition getLabelDefinition(Label node);
-
- /// Returns the label that [node] targets.
- LabelDefinition getTargetLabel(GotoStatement node);
-
- /// `true` if the [analyzedElement]'s source code contains a [TryStatement].
- bool get containsTryStatement;
-
- /// Returns native data stored with [node].
- getNativeData(Node node);
-}
-
-class TreeElementMapping extends TreeElements {
- final AnalyzableElement analyzedElement;
- Map<Spannable, Selector> _selectors;
- Map<Node, ResolutionDartType> _types;
-
- Map<Node, ResolutionDartType> _typesCache;
- Map<Node, ResolutionDartType> get typesCache =>
- _typesCache ??= <Node, ResolutionDartType>{};
-
- Setlet<SourceSpan> _superUses;
- Map<Node, ConstantExpression> _constants;
- Map<VariableElement, List<Node>> _potentiallyMutated;
- Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn;
- Map<VariableElement, List<Node>> _potentiallyMutatedInClosure;
- Map<Node, Map<VariableElement, List<Node>>> _accessedByClosureIn;
- Maplet<Send, SendStructure> _sendStructureMap;
- Maplet<NewExpression, NewStructure> _newStructureMap;
- bool containsTryStatement = false;
-
- /// Map from nodes to the targets they define.
- Map<Node, JumpTarget> _definedTargets;
-
- /// Map from goto statements to their targets.
- Map<GotoStatement, JumpTarget> _usedTargets;
-
- /// Map from labels to their label definition.
- Map<Label, LabelDefinition> _definedLabels;
-
- /// Map from labeled goto statements to the labels they target.
- Map<GotoStatement, LabelDefinition> _targetLabels;
-
- /// Map from nodes to native data.
- Map<Node, dynamic> _nativeData;
-
- final int hashCode = _hashCodeCounter = (_hashCodeCounter + 1).toUnsigned(30);
- static int _hashCodeCounter = 0;
-
- TreeElementMapping(this.analyzedElement);
-
- operator []=(Node node, Element element) {
- // TODO(johnniwinther): Simplify this invariant to use only declarations in
- // [TreeElements].
- assert(() {
- if (!element.isMalformed && analyzedElement != null && element.isPatch) {
- return analyzedElement.implementationLibrary.isPatch;
- }
- return true;
- }(), failedAt(node));
- // TODO(ahe): Investigate why the invariant below doesn't hold.
- // assert(
- // getTreeElement(node) == element ||
- // getTreeElement(node) == null,
- // failedAt(node, '${getTreeElement(node)}; $element'));
-
- setTreeElement(node, element);
- }
-
- @override
- operator [](Node node) => getTreeElement(node);
-
- @override
- SendStructure getSendStructure(Send node) {
- if (_sendStructureMap == null) return null;
- return _sendStructureMap[node];
- }
-
- void setSendStructure(Send node, SendStructure sendStructure) {
- if (_sendStructureMap == null) {
- _sendStructureMap = new Maplet<Send, SendStructure>();
- }
- _sendStructureMap[node] = sendStructure;
- }
-
- @override
- NewStructure getNewStructure(NewExpression node) {
- if (_newStructureMap == null) return null;
- return _newStructureMap[node];
- }
-
- void setNewStructure(NewExpression node, NewStructure newStructure) {
- if (_newStructureMap == null) {
- _newStructureMap = new Maplet<NewExpression, NewStructure>();
- }
- _newStructureMap[node] = newStructure;
- }
-
- void setType(Node node, ResolutionDartType type) {
- if (_types == null) {
- _types = new Maplet<Node, ResolutionDartType>();
- }
- _types[node] = type;
- }
-
- @override
- ResolutionDartType getType(Node node) => _types != null ? _types[node] : null;
-
- @override
- Iterable<SourceSpan> get superUses {
- return _superUses != null ? _superUses : const <SourceSpan>[];
- }
-
- void addSuperUse(SourceSpan span) {
- if (_superUses == null) {
- _superUses = new Setlet<SourceSpan>();
- }
- _superUses.add(span);
- }
-
- Selector _getSelector(Spannable node) {
- return _selectors != null ? _selectors[node] : null;
- }
-
- void _setSelector(Spannable node, Selector selector) {
- if (_selectors == null) {
- _selectors = new Maplet<Spannable, Selector>();
- }
- _selectors[node] = selector;
- }
-
- void setSelector(Node node, Selector selector) {
- _setSelector(node, selector);
- }
-
- @override
- Selector getSelector(Node node) => _getSelector(node);
-
- int getSelectorCount() => _selectors == null ? 0 : _selectors.length;
-
- void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
- _setSelector(node.selector, selector);
- }
-
- @override
- Selector getGetterSelectorInComplexSendSet(SendSet node) {
- return _getSelector(node.selector);
- }
-
- void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
- _setSelector(node.assignmentOperator, selector);
- }
-
- @override
- Selector getOperatorSelectorInComplexSendSet(SendSet node) {
- return _getSelector(node.assignmentOperator);
- }
-
- @override
- Element getForInVariable(ForIn node) {
- return this[node];
- }
-
- @override
- void setConstant(Node node, ConstantExpression constant) {
- if (_constants == null) {
- _constants = new Maplet<Node, ConstantExpression>();
- }
- _constants[node] = constant;
- }
-
- @override
- ConstantExpression getConstant(Node node) {
- return _constants != null ? _constants[node] : null;
- }
-
- @override
- bool isTypeLiteral(Send node) {
- return getType(node) != null;
- }
-
- @override
- ResolutionDartType getTypeLiteralType(Send node) {
- return getType(node);
- }
-
- @override
- List<Node> getPotentialMutations(VariableElement element) {
- if (_potentiallyMutated == null) return const <Node>[];
- List<Node> mutations = _potentiallyMutated[element];
- if (mutations == null) return const <Node>[];
- return mutations;
- }
-
- void registerPotentialMutation(VariableElement element, Node mutationNode) {
- if (_potentiallyMutated == null) {
- _potentiallyMutated = new Maplet<VariableElement, List<Node>>();
- }
- _potentiallyMutated.putIfAbsent(element, () => <Node>[]).add(mutationNode);
- }
-
- @override
- List<Node> getPotentialMutationsIn(Node node, VariableElement element) {
- if (_potentiallyMutatedIn == null) return const <Node>[];
- Map<VariableElement, List<Node>> mutationsIn = _potentiallyMutatedIn[node];
- if (mutationsIn == null) return const <Node>[];
- List<Node> mutations = mutationsIn[element];
- if (mutations == null) return const <Node>[];
- return mutations;
- }
-
- void registerPotentialMutationIn(
- Node contextNode, VariableElement element, Node mutationNode) {
- if (_potentiallyMutatedIn == null) {
- _potentiallyMutatedIn =
- new Maplet<Node, Map<VariableElement, List<Node>>>();
- }
- Map<VariableElement, List<Node>> mutationMap =
- _potentiallyMutatedIn.putIfAbsent(
- contextNode, () => new Maplet<VariableElement, List<Node>>());
- mutationMap.putIfAbsent(element, () => <Node>[]).add(mutationNode);
- }
-
- @override
- List<Node> getPotentialMutationsInClosure(VariableElement element) {
- if (_potentiallyMutatedInClosure == null) return const <Node>[];
- List<Node> mutations = _potentiallyMutatedInClosure[element];
- if (mutations == null) return const <Node>[];
- return mutations;
- }
-
- void registerPotentialMutationInClosure(
- VariableElement element, Node mutationNode) {
- if (_potentiallyMutatedInClosure == null) {
- _potentiallyMutatedInClosure = new Maplet<VariableElement, List<Node>>();
- }
- _potentiallyMutatedInClosure
- .putIfAbsent(element, () => <Node>[])
- .add(mutationNode);
- }
-
- @override
- List<Node> getAccessesByClosureIn(Node node, VariableElement element) {
- if (_accessedByClosureIn == null) return const <Node>[];
- Map<VariableElement, List<Node>> accessesIn = _accessedByClosureIn[node];
- if (accessesIn == null) return const <Node>[];
- List<Node> accesses = accessesIn[element];
- if (accesses == null) return const <Node>[];
- return accesses;
- }
-
- void setAccessedByClosureIn(
- Node contextNode, VariableElement element, Node accessNode) {
- if (_accessedByClosureIn == null) {
- _accessedByClosureIn = new Map<Node, Map<VariableElement, List<Node>>>();
- }
- Map<VariableElement, List<Node>> accessMap =
- _accessedByClosureIn.putIfAbsent(
- contextNode, () => new Maplet<VariableElement, List<Node>>());
- accessMap.putIfAbsent(element, () => <Node>[]).add(accessNode);
- }
-
- String toString() => 'TreeElementMapping($analyzedElement)';
-
- @override
- void forEachConstantNode(f(Node n, ConstantExpression c)) {
- if (_constants != null) {
- _constants.forEach(f);
- }
- }
-
- @override
- FunctionElement getFunctionDefinition(FunctionExpression node) {
- Element e = this[node];
- return e is FunctionElement ? e : null;
- }
-
- @override
- ConstructorElement getRedirectingTargetConstructor(
- RedirectingFactoryBody node) {
- return this[node];
- }
-
- void defineTarget(Node node, JumpTarget target) {
- _definedTargets ??= new Maplet<Node, JumpTarget>();
- _definedTargets[node] = target;
- }
-
- void undefineTarget(Node node) {
- if (_definedTargets != null) {
- _definedTargets.remove(node);
- if (_definedTargets.isEmpty) {
- _definedTargets = null;
- }
- }
- }
-
- @override
- JumpTarget getTargetDefinition(Node node) {
- return _definedTargets != null ? _definedTargets[node] : null;
- }
-
- void registerTargetOf(GotoStatement node, JumpTarget target) {
- _usedTargets ??= new Maplet<GotoStatement, JumpTarget>();
- _usedTargets[node] = target;
- }
-
- @override
- JumpTarget getTargetOf(GotoStatement node) {
- return _usedTargets != null ? _usedTargets[node] : null;
- }
-
- void defineLabel(Label label, LabelDefinition target) {
- _definedLabels ??= new Maplet<Label, LabelDefinition>();
- _definedLabels[label] = target;
- }
-
- void undefineLabel(Label label) {
- if (_definedLabels != null) {
- _definedLabels.remove(label);
- if (_definedLabels.isEmpty) {
- _definedLabels = null;
- }
- }
- }
-
- @override
- LabelDefinition getLabelDefinition(Label label) {
- return _definedLabels != null ? _definedLabels[label] : null;
- }
-
- void registerTargetLabel(GotoStatement node, LabelDefinition label) {
- assert(node.target != null);
- if (_targetLabels == null) {
- _targetLabels = new Maplet<GotoStatement, LabelDefinition>();
- }
- _targetLabels[node] = label;
- }
-
- @override
- LabelDefinition getTargetLabel(GotoStatement node) {
- assert(node.target != null);
- return _targetLabels != null ? _targetLabels[node] : null;
- }
-
- void registerNativeData(Node node, dynamic nativeData) {
- if (_nativeData == null) {
- _nativeData = <Node, dynamic>{};
- }
- _nativeData[node] = nativeData;
- }
-
- @override
- dynamic getNativeData(Node node) {
- return _nativeData != null ? _nativeData[node] : null;
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
deleted file mode 100644
index 47b9ef0..0000000
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.types;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart'
- show
- AmbiguousElement,
- ClassElement,
- Element,
- Elements,
- ErroneousElement,
- PrefixElement,
- TypedefElement,
- TypeVariableElement;
-import '../elements/modelx.dart' show ErroneousElementX;
-import '../elements/types.dart' show DartType, TypeVariableType;
-import '../resolution/resolution.dart';
-import '../tree/tree.dart';
-import '../universe/feature.dart' show Feature;
-import '../util/util.dart' show Link;
-import 'members.dart' show lookupInScope;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show MappingVisitor;
-import 'scope.dart' show Scope;
-
-class _FormalsTypeResolutionResult {
- final List<ResolutionDartType> requiredTypes;
- final List<ResolutionDartType> orderedTypes;
- final List<String> names;
- final List<ResolutionDartType> nameTypes;
-
- _FormalsTypeResolutionResult(
- this.requiredTypes, this.orderedTypes, this.names, this.nameTypes);
-}
-
-class TypeResolver {
- final Resolution resolution;
-
- TypeResolver(this.resolution);
-
- ResolverTask get resolver => resolution.resolver;
- DiagnosticReporter get reporter => resolution.reporter;
- Types get types => resolution.types;
-
- /// Tries to resolve the type name as an element.
- Element resolveTypeName(
- Identifier prefixName, Identifier typeName, Scope scope,
- {bool deferredIsMalformed: true}) {
- Element element;
- if (prefixName != null) {
- Element prefixElement =
- lookupInScope(reporter, prefixName, scope, prefixName.source);
- if (prefixElement != null && prefixElement.isPrefix) {
- // The receiver is a prefix. Lookup in the imported members.
- PrefixElement prefix = prefixElement;
- element = prefix.lookupLocalMember(typeName.source);
- if (element != null && prefix.isDeferred && deferredIsMalformed) {
- element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION,
- {'node': typeName}, element.name, element);
- }
- } else {
- // The caller of this method will create the ErroneousElement for
- // the MalformedType.
- element = null;
- }
- } else {
- element = lookupInScope(reporter, typeName, scope, typeName.source);
- }
- return element;
- }
-
- ResolutionDartType resolveTypeAnnotation(MappingVisitor visitor,
- TypeAnnotation node, FunctionTypeParameterScope functionTypeParameters,
- {bool malformedIsError: false, bool deferredIsMalformed: true}) {
- return _resolveTypeAnnotation(visitor, node, functionTypeParameters,
- malformedIsError: malformedIsError,
- deferredIsMalformed: deferredIsMalformed);
- }
-
- ResolutionDartType _resolveTypeAnnotation(MappingVisitor visitor,
- TypeAnnotation node, FunctionTypeParameterScope functionTypeParameters,
- {bool malformedIsError: false, bool deferredIsMalformed: true}) {
- if (node.asNominalTypeAnnotation() != null) {
- return resolveNominalTypeAnnotation(visitor, node, functionTypeParameters,
- malformedIsError: malformedIsError,
- deferredIsMalformed: deferredIsMalformed);
- }
- assert(node.asFunctionTypeAnnotation() != null);
- return _resolveFunctionTypeAnnotation(visitor, node, functionTypeParameters,
- malformedIsError: malformedIsError,
- deferredIsMalformed: deferredIsMalformed);
- }
-
- /// Resolves the types of a parameter list.
- ///
- /// This function does not accept "inline" function types. For example
- /// `foo(int bar(String x))` is not accepted.
- ///
- /// However, it does work with nested generalized function types:
- /// `foo(int Function(String) x)`.
- _FormalsTypeResolutionResult _resolveFormalTypes(MappingVisitor visitor,
- NodeList formals, FunctionTypeParameterScope functionTypeParameters) {
- ResolutionDartType resolvePositionalType(VariableDefinitions node) {
- return _resolveTypeAnnotation(visitor, node.type, functionTypeParameters);
- }
-
- void fillNamedTypes(NodeList namedFormals, List<String> names,
- List<ResolutionDartType> types) {
- List<Node> nodes = namedFormals.nodes.toList(growable: false);
-
- // Sort the named arguments first.
- nodes.sort((node1, node2) {
- VariableDefinitions a = node1;
- VariableDefinitions b = node2;
- assert(a.definitions.nodes.tail.isEmpty);
- assert(b.definitions.nodes.tail.isEmpty);
- return a.definitions.nodes.head
- .asIdentifier()
- .source
- .compareTo(b.definitions.nodes.head.asIdentifier().source);
- });
-
- for (VariableDefinitions node in nodes) {
- String name = node.definitions.nodes.head.asIdentifier().source;
- ResolutionDartType type = node.type == null
- ? const ResolutionDynamicType()
- : _resolveTypeAnnotation(
- visitor, node.type, functionTypeParameters);
- names.add(name);
- types.add(type);
- }
- }
-
- List<ResolutionDartType> requiredTypes = <ResolutionDartType>[];
- NodeList optionalFormals = null;
- for (Link<Node> link = formals.nodes; !link.isEmpty; link = link.tail) {
- if (link.tail.isEmpty && link.head is NodeList) {
- optionalFormals = link.head;
- break;
- }
- requiredTypes.add(resolvePositionalType(link.head));
- }
-
- List<ResolutionDartType> orderedTypes = const <ResolutionDartType>[];
- List<String> names = const <String>[];
- List<ResolutionDartType> namedTypes = const <ResolutionDartType>[];
-
- if (optionalFormals != null) {
- // This must be a list of optional arguments.
- String value = optionalFormals.beginToken.stringValue;
- if ((!identical(value, '[')) && (!identical(value, '{'))) {
- reporter.internalError(optionalFormals, "expected optional parameters");
- }
- bool optionalParametersAreNamed = (identical(value, '{'));
-
- if (optionalParametersAreNamed) {
- names = <String>[];
- namedTypes = <ResolutionDartType>[];
- fillNamedTypes(optionalFormals, names, namedTypes);
- } else {
- orderedTypes = <ResolutionDartType>[];
- for (Link<Node> link = optionalFormals.nodes;
- !link.isEmpty;
- link = link.tail) {
- orderedTypes.add(resolvePositionalType(link.head));
- }
- }
- }
- return new _FormalsTypeResolutionResult(
- requiredTypes, orderedTypes, names, namedTypes);
- }
-
- ResolutionFunctionType _resolveFunctionTypeAnnotation(
- MappingVisitor visitor,
- FunctionTypeAnnotation node,
- FunctionTypeParameterScope functionTypeParameters,
- {bool malformedIsError: false,
- bool deferredIsMalformed: true}) {
- assert(functionTypeParameters != null);
-
- functionTypeParameters = functionTypeParameters.expand(node.typeParameters);
-
- ResolutionDartType returnType = node.returnType == null
- ? const ResolutionDynamicType()
- : _resolveTypeAnnotation(
- visitor, node.returnType, functionTypeParameters);
- var formalTypes =
- _resolveFormalTypes(visitor, node.formals, functionTypeParameters);
- var result = new ResolutionFunctionType.generalized(
- returnType,
- formalTypes.requiredTypes,
- formalTypes.orderedTypes,
- formalTypes.names,
- formalTypes.nameTypes);
- visitor.registry.useType(node, result);
-
- functionTypeParameters = functionTypeParameters.parent;
-
- return result;
- }
-
- ResolutionDartType resolveNominalTypeAnnotation(
- MappingVisitor visitor,
- NominalTypeAnnotation node,
- FunctionTypeParameterScope functionTypeParameters,
- {bool malformedIsError: false,
- bool deferredIsMalformed: true}) {
- ResolutionRegistry registry = visitor.registry;
-
- Identifier typeName;
- ResolutionDartType type;
-
- ResolutionDartType checkNoTypeArguments(ResolutionDartType type) {
- List<ResolutionDartType> arguments = new List<ResolutionDartType>();
- bool hasTypeArgumentMismatch = resolveTypeArguments(visitor, node,
- const <ResolutionDartType>[], arguments, functionTypeParameters);
- if (hasTypeArgumentMismatch) {
- return new MalformedType(
- new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
- {'type': node}, typeName.source, visitor.enclosingElement),
- type,
- arguments);
- }
- return type;
- }
-
- Identifier prefixName;
- Send send = node.typeName.asSend();
- if (send != null) {
- // The type name is of the form [: prefix . identifier :].
- prefixName = send.receiver.asIdentifier();
- typeName = send.selector.asIdentifier();
- } else {
- typeName = node.typeName.asIdentifier();
- if (identical(typeName.source, 'void')) {
- type = const ResolutionVoidType();
- checkNoTypeArguments(type);
- registry.useType(node, type);
- return type;
- } else if (identical(typeName.source, 'dynamic')) {
- type = const ResolutionDynamicType();
- checkNoTypeArguments(type);
- registry.useType(node, type);
- return type;
- }
- }
-
- ResolutionDartType reportFailureAndCreateType(
- MessageKind messageKind, Map messageArguments,
- {ResolutionDartType userProvidedBadType,
- Element erroneousElement,
- List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) {
- if (malformedIsError) {
- reporter.reportError(
- reporter.createMessage(node, messageKind, messageArguments), infos);
- } else {
- registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
- reporter.reportWarning(
- reporter.createMessage(node, messageKind, messageArguments), infos);
- }
- if (erroneousElement == null) {
- registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
- erroneousElement = new ErroneousElementX(messageKind, messageArguments,
- typeName.source, visitor.enclosingElement);
- }
- List<ResolutionDartType> arguments = <ResolutionDartType>[];
- resolveTypeArguments(visitor, node, const <ResolutionDartType>[],
- arguments, functionTypeParameters);
- return new MalformedType(
- erroneousElement, userProvidedBadType, arguments);
- }
-
- Element element;
- if (prefixName == null) {
- type = functionTypeParameters.lookup(typeName.source);
- }
- if (type == null) {
- element = resolveTypeName(prefixName, typeName, visitor.scope,
- deferredIsMalformed: deferredIsMalformed);
- }
-
- // Try to construct the type from the element.
- if (type != null) {
- // Already assigned to through the visibleTypeParameterNames.
- // Just make sure that it doesn't have type arguments.
- if (node.typeArguments != null) {
- reporter.reportWarningMessage(node.typeArguments.nodes.head,
- MessageKind.ADDITIONAL_TYPE_ARGUMENT);
- }
- } else if (element == null) {
- type = reportFailureAndCreateType(
- MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
- } else if (element.isAmbiguous) {
- AmbiguousElement ambiguous = element;
- type = reportFailureAndCreateType(
- ambiguous.messageKind, ambiguous.messageArguments,
- infos: ambiguous.computeInfos(
- registry.mapping.analyzedElement, reporter));
- ;
- } else if (element.isMalformed) {
- if (element is ErroneousElement) {
- type = reportFailureAndCreateType(
- element.messageKind, element.messageArguments,
- erroneousElement: element);
- } else {
- type = const ResolutionDynamicType();
- }
- } else if (!element.impliesType) {
- type = reportFailureAndCreateType(
- MessageKind.NOT_A_TYPE, {'node': node.typeName});
- } else if (element.library.isPlatformLibrary &&
- element.name == 'FutureOr') {
- type = const ResolutionDynamicType();
- registry.useType(node, type);
- return type;
- } else {
- bool addTypeVariableBoundsCheck = false;
- if (element.isClass) {
- ClassElement cls = element;
- // TODO(johnniwinther): [ensureClassWillBeResolvedInternal] should imply
- // [computeType].
- resolver.ensureClassWillBeResolvedInternal(cls);
- cls.computeType(resolution);
- List<ResolutionDartType> arguments = <ResolutionDartType>[];
- bool hasTypeArgumentMismatch = resolveTypeArguments(visitor, node,
- cls.typeVariables, arguments, functionTypeParameters);
- if (hasTypeArgumentMismatch) {
- type = new BadInterfaceType(
- cls.declaration,
- new ResolutionInterfaceType.forUserProvidedBadType(
- cls.declaration, arguments));
- } else {
- if (arguments.isEmpty) {
- type = cls.rawType;
- } else {
- type = new ResolutionInterfaceType(
- cls.declaration, arguments.toList(growable: false));
- addTypeVariableBoundsCheck =
- arguments.any((ResolutionDartType type) => !type.isDynamic);
- }
- }
- } else if (element.isTypedef) {
- TypedefElement typdef = element;
- // TODO(johnniwinther): [ensureResolved] should imply [computeType].
- typdef.ensureResolved(resolution);
- typdef.computeType(resolution);
- List<ResolutionDartType> arguments = <ResolutionDartType>[];
- bool hasTypeArgumentMismatch = resolveTypeArguments(visitor, node,
- typdef.typeVariables, arguments, functionTypeParameters);
- if (hasTypeArgumentMismatch) {
- type = new BadTypedefType(
- typdef,
- new ResolutionTypedefType.forUserProvidedBadType(
- typdef, arguments));
- } else {
- if (arguments.isEmpty) {
- type = typdef.rawType;
- } else {
- type = new ResolutionTypedefType(
- typdef, arguments.toList(growable: false));
- addTypeVariableBoundsCheck =
- arguments.any((ResolutionDartType type) => !type.isDynamic);
- }
- }
- } else if (element.isTypeVariable) {
- TypeVariableElement typeVariable = element;
- Element outer =
- visitor.enclosingElement.outermostEnclosingMemberOrTopLevel;
- if (!outer.isClass &&
- !outer.isTypedef &&
- !Elements.hasAccessToTypeVariable(
- visitor.enclosingElement, typeVariable)) {
- registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
- type = reportFailureAndCreateType(
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
- {'typeVariableName': node},
- userProvidedBadType: typeVariable.type);
- } else {
- type = typeVariable.type;
- }
- type = checkNoTypeArguments(type);
- } else {
- reporter.internalError(
- node, "Unexpected element kind ${element.kind}.");
- }
- if (addTypeVariableBoundsCheck) {
- visitor.addDeferredAction(visitor.enclosingElement,
- () => checkTypeVariableBounds(node, type));
- }
- }
- registry.useType(node, type);
- return type;
- }
-
- /// Checks the type arguments of [type] against the type variable bounds.
- void checkTypeVariableBounds(NominalTypeAnnotation node, GenericType type) {
- void checkTypeVariableBound(_, DartType _typeArgument,
- TypeVariableType _typeVariable, DartType _bound) {
- ResolutionDartType typeArgument = _typeArgument;
- ResolutionTypeVariableType typeVariable = _typeVariable;
- ResolutionDartType bound = _bound;
- if (!types.isSubtype(typeArgument, bound)) {
- reporter.reportWarningMessage(
- node, MessageKind.INVALID_TYPE_VARIABLE_BOUND, {
- 'typeVariable': typeVariable,
- 'bound': bound,
- 'typeArgument': typeArgument,
- 'thisType': type.element.thisType
- });
- }
- }
-
- types.genericCheckTypeVariableBounds(type, type.typeArguments,
- type.element.typeVariables, checkTypeVariableBound);
- }
-
- /**
- * Resolves the type arguments of [node] and adds these to [arguments].
- *
- * Returns [: true :] if the number of type arguments did not match the
- * number of type variables.
- */
- bool resolveTypeArguments(
- MappingVisitor visitor,
- NominalTypeAnnotation node,
- List<ResolutionDartType> typeVariables,
- List<ResolutionDartType> arguments,
- FunctionTypeParameterScope functionTypeParameters) {
- if (node.typeArguments == null) {
- return false;
- }
- int expectedVariables = typeVariables.length;
- int index = 0;
- bool typeArgumentCountMismatch = false;
- for (Link<Node> typeArguments = node.typeArguments.nodes;
- !typeArguments.isEmpty;
- typeArguments = typeArguments.tail, index++) {
- if (index > expectedVariables - 1) {
- reporter.reportWarningMessage(
- typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
- typeArgumentCountMismatch = true;
- }
- ResolutionDartType argType = _resolveTypeAnnotation(
- visitor, typeArguments.head, functionTypeParameters);
- // TODO(karlklose): rewrite to not modify [arguments].
- arguments.add(argType);
- }
- if (index < expectedVariables) {
- reporter.reportWarningMessage(
- node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
- typeArgumentCountMismatch = true;
- }
- return typeArgumentCountMismatch;
- }
-}
-
-/// [FunctionTypeParameterScope] put type parameters in scope for the nested
-/// types.
-///
-/// For example, in the following examples, the generic types `A` would be stored
-/// in a [FunctionTypeParameterScope].
-///
-/// typedef F = List<A> Function<A>(A x)
-/// typedef F = Function(List<A> Function<A>(A x))
-///
-/// They are resolved to `dynamic` until dart2js supports generic methods.
-class FunctionTypeParameterScope {
- final FunctionTypeParameterScope parent;
- final Map<String, ResolutionDartType> _map;
-
- const FunctionTypeParameterScope()
- : parent = null,
- _map = const {};
-
- FunctionTypeParameterScope._(this.parent, this._map);
-
- FunctionTypeParameterScope expand(NodeList typeParameters) {
- if (typeParameters == null)
- return new FunctionTypeParameterScope._(this, const {});
- Map<String, ResolutionDartType> map = <String, ResolutionDartType>{};
- for (TypeVariable node in typeParameters) {
- /// TODO(johnniwinther): Create a special [FunctionTypeVariableType]
- /// instead of [ResolutionDynamicType].
- map[node.name.source] = const ResolutionDynamicType();
- }
- return new FunctionTypeParameterScope._(this, map);
- }
-
- ResolutionDartType lookup(String name) {
- return _map[name] ?? parent?.lookup(name);
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/typedefs.dart b/pkg/compiler/lib/src/resolution/typedefs.dart
deleted file mode 100644
index e3e58ec..0000000
--- a/pkg/compiler/lib/src/resolution/typedefs.dart
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.typedefs;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart'
- show FunctionSignature, TypedefElement, TypeVariableElement;
-import '../elements/modelx.dart' show ErroneousElementX, TypedefElementX;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link;
-import 'class_hierarchy.dart' show TypeDefinitionVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'scope.dart' show MethodScope, TypeDeclarationScope;
-import 'signatures.dart' show SignatureResolver;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-class TypedefResolverVisitor extends TypeDefinitionVisitor {
- TypedefElementX get element => enclosingElement;
-
- TypedefResolverVisitor(Resolution resolution, TypedefElement typedefElement,
- ResolutionRegistry registry)
- : super(resolution, typedefElement, registry);
-
- visitTypedef(Typedef node) {
- element.computeType(resolution);
- scope = new TypeDeclarationScope(scope, element);
- resolveTypeVariableBounds(node.templateParameters);
-
- FunctionTypeParameterScope functionTypeParameters =
- const FunctionTypeParameterScope().expand(node.typeParameters);
-
- FunctionSignature signature = SignatureResolver.analyze(
- resolution,
- scope,
- functionTypeParameters,
- null, // Don't create type variable types for the type parameters.
- node.formals,
- node.returnType,
- element,
- registry,
- defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
- element.functionSignature = signature;
-
- scope = new MethodScope(scope, element);
- signature.forEachParameter(addToScope);
-
- element.aliasCache = signature.type;
-
- void checkCyclicReference() {
- element.checkCyclicReference(resolution);
- }
-
- addDeferredAction(element, checkCyclicReference);
- }
-}
-
-// TODO(johnniwinther): Replace with a traversal on the AST when the type
-// annotations in typedef alias are stored in a [TreeElements] mapping.
-class TypedefCyclicVisitor extends BaseResolutionDartTypeVisitor {
- final DiagnosticReporter reporter;
- final TypedefElementX element;
- bool hasCyclicReference = false;
-
- Link<TypedefElement> seenTypedefs = const Link<TypedefElement>();
-
- int seenTypedefsCount = 0;
-
- Link<TypeVariableElement> seenTypeVariables =
- const Link<TypeVariableElement>();
-
- TypedefCyclicVisitor(this.reporter, this.element);
-
- visitType(ResolutionDartType type, _) {
- // Do nothing.
- }
-
- visitTypedefType(ResolutionTypedefType type, _) {
- TypedefElementX typedefElement = type.element;
- if (seenTypedefs.contains(typedefElement)) {
- if (!hasCyclicReference && identical(element, typedefElement)) {
- // Only report an error on the checked typedef to avoid generating
- // multiple errors for the same cyclicity.
- hasCyclicReference = true;
- if (seenTypedefsCount == 1) {
- // Direct cyclicity.
- reporter.reportErrorMessage(element, MessageKind.CYCLIC_TYPEDEF,
- {'typedefName': element.name});
- } else if (seenTypedefsCount == 2) {
- // Cyclicity through one other typedef.
- reporter.reportErrorMessage(element, MessageKind.CYCLIC_TYPEDEF_ONE, {
- 'typedefName': element.name,
- 'otherTypedefName': seenTypedefs.head.name
- });
- } else {
- // Cyclicity through more than one other typedef.
- for (TypedefElement cycle in seenTypedefs) {
- if (!identical(typedefElement, cycle)) {
- reporter.reportErrorMessage(
- element, MessageKind.CYCLIC_TYPEDEF_ONE, {
- 'typedefName': element.name,
- 'otherTypedefName': cycle.name
- });
- }
- }
- }
- ErroneousElementX erroneousElement = new ErroneousElementX(
- MessageKind.CYCLIC_TYPEDEF,
- {'typedefName': element.name},
- element.name,
- element);
- element.aliasCache =
- new MalformedType(erroneousElement, typedefElement.aliasCache);
- element.hasBeenCheckedForCycles = true;
- }
- } else {
- seenTypedefs = seenTypedefs.prepend(typedefElement);
- seenTypedefsCount++;
- type.visitChildren(this, null);
- if (!typedefElement.isMalformed) {
- typedefElement.aliasCache.accept(this, null);
- }
- seenTypedefs = seenTypedefs.tail;
- seenTypedefsCount--;
- }
- }
-
- visitFunctionType(ResolutionFunctionType type, _) {
- type.visitChildren(this, null);
- }
-
- visitInterfaceType(ResolutionInterfaceType type, _) {
- type.visitChildren(this, null);
- }
-
- visitTypeVariableType(ResolutionTypeVariableType type, _) {
- TypeVariableElement typeVariableElement = type.element;
- if (seenTypeVariables.contains(typeVariableElement)) {
- // Avoid running in cycles on cyclic type variable bounds.
- // Cyclicity is reported elsewhere.
- return;
- }
- seenTypeVariables = seenTypeVariables.prepend(typeVariableElement);
- typeVariableElement.bound.accept(this, null);
- seenTypeVariables = seenTypeVariables.tail;
- }
-}
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
deleted file mode 100644
index 60541a5..0000000
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.variables;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../elements/modelx.dart' show LocalVariableElementX, VariableList;
-import '../tree/tree.dart';
-import '../universe/feature.dart';
-import '../util/util.dart' show Link;
-import 'members.dart' show ResolverVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show CommonResolverVisitor;
-import 'scope.dart' show VariableDefinitionScope;
-
-class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> {
- VariableDefinitions definitions;
- ResolverVisitor resolver;
- VariableList variables;
-
- VariableDefinitionsVisitor(
- Resolution resolution, this.definitions, this.resolver, this.variables)
- : super(resolution);
-
- ResolutionRegistry get registry => resolver.registry;
-
- Identifier visitSendSet(SendSet node) {
- assert(node.arguments.tail.isEmpty); // Sanity check
- Identifier identifier = node.selector;
- String name = identifier.source;
- VariableDefinitionScope scope =
- new VariableDefinitionScope(resolver.scope, name);
- resolver.visitIn(node.arguments.head, scope);
- if (scope.variableReferencedInInitializer) {
- reporter.reportErrorMessage(identifier,
- MessageKind.REFERENCE_IN_INITIALIZATION, {'variableName': name});
- }
- return identifier;
- }
-
- Identifier visitIdentifier(Identifier node) {
- if (!resolver.inCatchParameters) {
- // The variable is initialized to null.
- registry.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER);
- }
- if (definitions.modifiers.isConst) {
- if (resolver.inLoopVariable) {
- reporter.reportErrorMessage(node, MessageKind.CONST_LOOP_VARIABLE);
- } else {
- reporter.reportErrorMessage(
- node, MessageKind.CONST_WITHOUT_INITIALIZER);
- }
- }
- if (definitions.modifiers.isFinal && !resolver.inLoopVariable) {
- reporter.reportErrorMessage(node, MessageKind.FINAL_WITHOUT_INITIALIZER);
- }
- return node;
- }
-
- visitNodeList(NodeList node) {
- for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
- Identifier name = visit(link.head);
- LocalVariableElementX element = new LocalVariableElementX(
- name.source, resolver.enclosingElement, variables, name.token);
- resolver.defineLocalVariable(link.head, element);
- resolver.addToScope(element);
- if (definitions.modifiers.isConst) {
- addDeferredAction(element, () {
- element.constant =
- resolution.resolver.constantCompiler.compileConstant(element);
- });
- }
- }
- }
-}
diff --git a/pkg/compiler/lib/src/resolved_uri_translator.dart b/pkg/compiler/lib/src/resolved_uri_translator.dart
index f40aeb3..ded9161 100644
--- a/pkg/compiler/lib/src/resolved_uri_translator.dart
+++ b/pkg/compiler/lib/src/resolved_uri_translator.dart
@@ -2,41 +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 'common.dart';
-import 'elements/elements.dart' show LibraryElement;
-import 'util/emptyset.dart';
-
/// API used by the library loader to translate internal SDK URIs into file
/// system readable URIs.
abstract class ResolvedUriTranslator {
- factory ResolvedUriTranslator(
- Map<String, Uri> sdkLibraries,
- DiagnosticReporter reporter,
- Uri platformConfigUri) = _ResolvedUriTranslator;
-
- /// The set of platform libraries reported as unsupported.
- ///
- /// For instance when importing 'dart:io' without '--categories=Server'.
- Set<Uri> get disallowedLibraryUris;
-
- /// Whether or not a mockable library has been translated.
- bool get mockableLibraryUsed;
+ factory ResolvedUriTranslator(Map<String, Uri> sdkLibraries) =
+ _ResolvedUriTranslator;
/// A mapping from dart: library names to their location.
Map<String, Uri> get sdkLibraries;
-
- /// Translates the resolved [uri] into a readable URI.
- ///
- /// The [importingLibrary] holds the library importing [uri] or `null` if
- /// [uri] is loaded as the main library. The [importingLibrary] is used to
- /// grant access to internal libraries from platform libraries and patch
- /// libraries.
- ///
- /// If the [uri] is not accessible from [importingLibrary], this method is
- /// responsible for reporting errors.
- ///
- /// See [LibraryLoader] for terminology on URIs.
- Uri translate(LibraryElement importingLibrary, Uri uri, Spannable spannable);
}
/// A translator that forwards all methods to an internal
@@ -58,129 +31,13 @@
bool get isNotSet => resolvedUriTranslator == null;
@override
- Uri translate(LibraryElement importingLibrary, Uri resolvedUri,
- Spannable spannable) =>
- resolvedUriTranslator.translate(importingLibrary, resolvedUri, spannable);
-
- @override
- Set<Uri> get disallowedLibraryUris =>
- resolvedUriTranslator?.disallowedLibraryUris ??
- const ImmutableEmptySet<Uri>();
-
- @override
- bool get mockableLibraryUsed => resolvedUriTranslator.mockableLibraryUsed;
-
- @override
Map<String, Uri> get sdkLibraries => resolvedUriTranslator.sdkLibraries;
}
class _ResolvedUriTranslator implements ResolvedUriTranslator {
final Map<String, Uri> _sdkLibraries;
- final DiagnosticReporter _reporter;
- final Uri _platformConfigUri;
- Set<Uri> disallowedLibraryUris = new Set<Uri>();
- bool mockableLibraryUsed = false;
-
- _ResolvedUriTranslator(
- this._sdkLibraries, this._reporter, this._platformConfigUri);
+ _ResolvedUriTranslator(this._sdkLibraries);
Map<String, Uri> get sdkLibraries => _sdkLibraries;
-
- @override
- Uri translate(LibraryElement importingLibrary, Uri uri, Spannable spannable) {
- if (uri.scheme == 'dart') {
- return translateDartUri(importingLibrary, uri, spannable);
- }
- return uri;
- }
-
- /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
- /// to `options.platformConfigUri` according to the information in the file at
- /// `options.platformConfigUri`.
- ///
- /// Returns `null` and emits an error if the library could not be found or
- /// imported into [importingLibrary].
- ///
- /// Internal libraries (whose name starts with '_') can be only resolved if
- /// [importingLibrary] is a platform or patch library.
- Uri translateDartUri(
- LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable) {
- Uri location = lookupLibraryUri(resolvedUri.path);
-
- if (location == null) {
- _reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_FOUND,
- {'resolvedUri': resolvedUri});
- return null;
- }
-
- if (resolvedUri.path.startsWith('_')) {
- bool allowInternalLibraryAccess = importingLibrary != null &&
- (importingLibrary.isPlatformLibrary ||
- importingLibrary.isPatch ||
- importingLibrary.canonicalUri.scheme == 'memory' ||
- importingLibrary.canonicalUri.path
- .contains('tests/compiler/dart2js_native') ||
- importingLibrary.canonicalUri.path
- .contains('tests/compiler/dart2js_extra') ||
- (importingLibrary.canonicalUri.scheme == 'package' &&
- importingLibrary.canonicalUri.path
- .startsWith('dart_internal/')));
-
- if (!allowInternalLibraryAccess) {
- if (importingLibrary != null) {
- _reporter.reportErrorMessage(
- spannable, MessageKind.INTERNAL_LIBRARY_FROM, {
- 'resolvedUri': resolvedUri,
- 'importingUri': importingLibrary.canonicalUri
- });
- } else {
- _reporter.reportErrorMessage(spannable, MessageKind.INTERNAL_LIBRARY,
- {'resolvedUri': resolvedUri});
- registerDisallowedLibraryUse(resolvedUri);
- }
- return null;
- }
- }
-
- if (location.scheme == "unsupported") {
- if (location.path == "") {
- _reporter.reportErrorMessage(spannable,
- MessageKind.LIBRARY_NOT_SUPPORTED, {'resolvedUri': resolvedUri});
- registerDisallowedLibraryUse(resolvedUri);
- } else {
- // If the specification includes a path, we treat it as "partially"
- // unsupported: it is allowed to be imported unconditionally, but we
- // will not expose it as being supported in the const variable
- // `dart.library.name`.
- //
- // This is a stopgap measure to support packages like `http` that need
- // to import `dart:io` conditionally. Once config-imports are supported
- // in the language, we can make it an error again to import it
- // unconditionally.
- //
- // The plaform configuration files contain a URI of the form
- // `unsupported:path/to/library.dart` to indicate this partially
- // supported mode. We resolve the path with respect to the configuration
- // file.
- return _platformConfigUri.resolve(location.path);
- }
- return null;
- }
-
- if (resolvedUri.path == 'html' || resolvedUri.path == 'io') {
- // TODO(ahe): Get rid of mockableLibraryUsed when test.dart
- // supports this use case better.
- mockableLibraryUsed = true;
- }
- return location;
- }
-
- void registerDisallowedLibraryUse(Uri uri) {
- disallowedLibraryUris.add(uri);
- }
-
- Uri lookupLibraryUri(String libraryName) {
- return _sdkLibraries[libraryName];
- }
}
diff --git a/pkg/compiler/lib/src/scanner/scanner_task.dart b/pkg/compiler/lib/src/scanner/scanner_task.dart
deleted file mode 100644
index 6e3b3e9..0000000
--- a/pkg/compiler/lib/src/scanner/scanner_task.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.scanner.task;
-
-import '../common/tasks.dart' show CompilerTask, Measurer;
-import '../diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
-import '../elements/elements.dart' show CompilationUnitElement, LibraryElement;
-import '../parser/diet_parser_task.dart' show DietParserTask;
-import '../script.dart' show Script;
-import 'package:front_end/src/fasta/scanner.dart'
- show Scanner, StringScanner, Token, Utf8BytesScanner;
-import '../io/source_file.dart';
-
-class ScannerTask extends CompilerTask {
- final DietParserTask _dietParser;
- final DiagnosticReporter reporter;
-
- ScannerTask(this._dietParser, this.reporter, Measurer measurer)
- : super(measurer);
-
- String get name => 'Scanner';
-
- void scanLibrary(LibraryElement library) {
- CompilationUnitElement compilationUnit = library.entryCompilationUnit;
- String canonicalUri = library.canonicalUri.toString();
- String resolvedUri = compilationUnit.script.resourceUri.toString();
- if (canonicalUri == resolvedUri) {
- reporter.log("Scanning library $canonicalUri");
- } else {
- reporter.log("Scanning library $canonicalUri ($resolvedUri)");
- }
- scan(compilationUnit);
- }
-
- void scan(CompilationUnitElement compilationUnit) {
- measure(() {
- scanElements(compilationUnit);
- });
- }
-
- Token scanFile(SourceFile file, {bool includeComments: false}) {
- Scanner scanner = file is Utf8BytesSourceFile
- ? new Utf8BytesScanner(file.slowUtf8ZeroTerminatedBytes(),
- includeComments: includeComments)
- : new StringScanner(file.slowText(), includeComments: includeComments);
- return measure(scanner.tokenize);
- }
-
- void scanElements(CompilationUnitElement compilationUnit) {
- Script script = compilationUnit.script;
- Token tokens = scanFile(script.file);
- _dietParser.dietParse(compilationUnit, tokens);
- }
-
- /**
- * Returns the tokens for the [source].
- *
- * The [StringScanner] implementation works on strings that end with a '0'
- * value ('\x00'). If [source] does not end with '0', the string is copied
- * before scanning.
- */
- Token tokenize(String source) {
- return measure(() {
- return new StringScanner(source, includeComments: false).tokenize();
- });
- }
-}
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
deleted file mode 100644
index 2616b59..0000000
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ /dev/null
@@ -1,7089 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:js_runtime/shared/embedded_names.dart';
-
-import '../closure.dart';
-import '../common.dart';
-import '../common/codegen.dart' show CodegenRegistry;
-import '../common/names.dart' show Identifiers, Selectors;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart';
-import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../deferred_load.dart' show OutputUnit;
-import '../diagnostics/messages.dart' show Message, MessageTemplate;
-import '../dump_info.dart' show InfoReporter;
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/jumps.dart';
-import '../elements/modelx.dart' show ConstructorBodyElementX;
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../io/source_information.dart';
-import '../js/js.dart' as js;
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../js_backend/element_strategy.dart' show ElementCodegenWorkItem;
-import '../js_backend/runtime_types.dart';
-import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
-import '../native/native.dart' as native;
-import '../resolution/deferred_load.dart' show AstDeferredLoadTask;
-import '../resolution/semantic_visitor.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart' as ast;
-import '../types/types.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import '../universe/side_effects.dart' show SideEffects;
-import '../universe/use.dart'
- show ConstantUse, ConstrainedDynamicUse, StaticUse;
-import '../util/util.dart';
-import '../world.dart' show ClosedWorld;
-
-import 'graph_builder.dart';
-import 'jump_handler.dart';
-import 'locals_handler.dart';
-import 'loop_handler.dart';
-import 'nodes.dart';
-import 'optimize.dart';
-import 'ssa.dart';
-import 'ssa_branch_builder.dart';
-import 'type_builder.dart';
-import 'types.dart';
-
-abstract class SsaAstBuilderBase extends SsaBuilderFieldMixin
- implements SsaBuilder {
- final CompilerTask task;
- final JavaScriptBackend backend;
-
- SsaAstBuilderBase(this.task, this.backend);
-
- ConstantValue getFieldInitialConstantValue(FieldElement field) {
- ConstantExpression constant = field.constant;
- if (constant != null) {
- ConstantValue initialValue = backend.constants.getConstantValue(constant);
- if (initialValue == null) {
- assert(
- field.isInstanceMember ||
- constant.isImplicit ||
- constant.isPotential,
- failedAt(
- field,
- "Constant expression without value: "
- "${constant.toStructuredText()}."));
- }
- return initialValue;
- }
- return null;
- }
-}
-
-class SsaAstBuilder extends SsaAstBuilderBase {
- final CodeEmitterTask emitter;
- final SourceInformationStrategy sourceInformationFactory;
-
- SsaAstBuilder(CompilerTask task, JavaScriptBackend backend,
- this.sourceInformationFactory)
- : emitter = backend.emitter,
- super(task, backend);
-
- DiagnosticReporter get reporter => backend.reporter;
-
- HGraph build(covariant ElementCodegenWorkItem work, ClosedWorld closedWorld) {
- return task.measure(() {
- if (handleConstantField(work.element, work.registry, closedWorld)) {
- // No code is generated for `work.element`.
- return null;
- }
- MemberElement element = work.element.implementation;
- return reporter.withCurrentElement(element, () {
- SsaAstGraphBuilder builder = new SsaAstGraphBuilder(
- work.element.implementation,
- work.resolvedAst,
- work.registry,
- backend,
- closedWorld,
- emitter.nativeEmitter,
- sourceInformationFactory);
- HGraph graph = builder.build();
-
- // Default arguments are handled elsewhere, but we must ensure
- // that the default values are computed during codegen.
- if (!identical(element.kind, ElementKind.FIELD)) {
- MethodElement function = element;
- FunctionSignature signature = function.functionSignature;
- signature.forEachOptionalParameter((_parameter) {
- ParameterElement parameter = _parameter;
- // This ensures the default value will be computed.
- ConstantValue constant =
- backend.constants.getConstantValue(parameter.constant);
- work.registry.registerConstantUse(new ConstantUse.init(constant));
- });
- }
- if (backend.tracer.isEnabled) {
- String name;
- if (element.isClassMember) {
- String className = element.enclosingClass.name;
- String memberName = element.name;
- name = "$className.$memberName";
- if (element.isGenerativeConstructorBody) {
- name = "$name (body)";
- }
- } else {
- name = "${element.name}";
- }
- backend.tracer.traceCompilation(name);
- backend.tracer.traceGraph('builder', graph);
- }
- return graph;
- });
- });
- }
-}
-
-/**
- * This class builds SSA nodes for functions represented in AST.
- */
-class SsaAstGraphBuilder extends ast.Visitor
- with
- BaseImplementationOfCompoundsMixin,
- BaseImplementationOfSetIfNullsMixin,
- BaseImplementationOfSuperIndexSetIfNullMixin,
- SemanticSendResolvedMixin,
- NewBulkMixin,
- ErrorBulkMixin,
- GraphBuilder
- implements SemanticSendVisitor {
- /// The element for which this SSA builder is being used.
- final MemberElement target;
- final ClosedWorld closedWorld;
-
- ResolvedAst resolvedAst;
-
- /// Used to report information about inlining (which occurs while building the
- /// SSA graph), when dump-info is enabled.
- final InfoReporter infoReporter;
-
- /// Registry used to enqueue work during codegen, may be null to avoid
- /// enqueing any work.
- // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be
- // able to return the impact as a result after building and avoid enqueing
- // things here. Later the codegen task can decide whether to enqueue
- // something. In the past this didn't matter as much because the SSA graph was
- // used only for codegen, but currently we want to experiment using it for
- // code-analysis too.
- final CodegenRegistry registry;
-
- /// Results from the global type-inference analysis corresponding to the
- /// current element being visited.
- ///
- /// Invariant: this property is updated together with [resolvedAst].
- GlobalTypeInferenceElementResult elementInferenceResults;
-
- final JavaScriptBackend backend;
-
- Compiler get compiler => backend.compiler;
-
- AstDeferredLoadTask get deferredLoadTask => super.deferredLoadTask;
-
- final ConstantSystem constantSystem;
- final RuntimeTypesSubstitutions rtiSubstitutions;
-
- SourceInformationBuilder sourceInformationBuilder;
-
- bool inLazyInitializerExpression = false;
-
- // TODO(sigmund): make all comments /// instead of /* */
- /* This field is used by the native handler. */
- final NativeEmitter nativeEmitter;
-
- /**
- * True if we are visiting the expression of a throw statement; we assume this
- * is a slow path.
- */
- bool inExpressionOfThrow = false;
-
- /**
- * This stack contains declaration elements of the functions being built
- * or inlined by this builder.
- */
- final List<MemberElement> sourceElementStack = <MemberElement>[];
-
- HInstruction rethrowableException;
-
- /// Returns `true` if the current element is an `async` function.
- bool get isBuildingAsyncFunction {
- Element element = sourceElement;
- return (element is FunctionElement &&
- element.asyncMarker == AsyncMarker.ASYNC);
- }
-
- /// Handles the building of loops.
- LoopHandler<ast.Node> loopHandler;
-
- /// Handles type check building.
- TypeBuilder typeBuilder;
-
- // TODO(sigmund): make most args optional
- SsaAstGraphBuilder(
- this.target,
- this.resolvedAst,
- this.registry,
- JavaScriptBackend backend,
- this.closedWorld,
- this.nativeEmitter,
- SourceInformationStrategy sourceInformationFactory)
- : this.infoReporter = backend.compiler.dumpInfoTask,
- this.backend = backend,
- this.constantSystem = backend.constantSystem,
- this.rtiSubstitutions = backend.rtiSubstitutions {
- assert(target.isImplementation);
- elementInferenceResults = _resultOf(target.declaration);
- assert(elementInferenceResults != null);
- graph.element = target;
- sourceElementStack.add(target.declaration);
- sourceInformationBuilder =
- sourceInformationFactory.createBuilderForContext(target);
- graph.sourceInformation =
- sourceInformationBuilder.buildVariableDeclaration();
- localsHandler = new LocalsHandler(
- this,
- target,
- target.memberContext,
- target.contextClass?.thisType,
- closedWorld.nativeData,
- closedWorld.interceptorData);
- loopHandler = new SsaLoopHandler(this);
- typeBuilder = new AstTypeBuilder(this);
- }
-
- MemberElement get targetElement => target;
-
- /// Reference to resolved elements in [target]'s AST.
- TreeElements get elements => resolvedAst.elements;
-
- @override
- SemanticSendVisitor get sendVisitor => this;
-
- @override
- void visitNode(ast.Node node) {
- internalError(node, "Unhandled node: $node");
- }
-
- @override
- void apply(ast.Node node, [_]) {
- node.accept(this);
- }
-
- /// Returns the current source element.
- ///
- /// The returned element is a declaration element.
- // TODO(johnniwinther): Check that all usages of sourceElement agree on
- // implementation/declaration distinction.
- @override
- MemberElement get sourceElement => sourceElementStack.last;
-
- /// Helper to retrieve global inference results for [element] with special
- /// care for `ConstructorBodyElement`s which don't exist at the time the
- /// global analysis run.
- ///
- /// Note: this helper is used selectively. When we know that we are in a
- /// context were we don't expect to see a constructor body element, we
- /// directly fetch the data from the global inference results.
- GlobalTypeInferenceElementResult _resultOf(MemberElement element) {
- assert(element.isDeclaration);
- return globalInferenceResults.resultOfMember(
- element is ConstructorBodyElementX ? element.constructor : element);
- }
-
- /// Build the graph for [target].
- HGraph build() {
- assert(target.isImplementation, failedAt(target));
- HInstruction.idCounter = 0;
- // TODO(sigmund): remove `result` and return graph directly, need to ensure
- // that it can never be null (see result in buildFactory for instance).
- var result;
- if (target.isGenerativeConstructor) {
- result = buildFactory(resolvedAst);
- } else if (target.isGenerativeConstructorBody ||
- target.isFactoryConstructor ||
- target.isFunction ||
- target.isGetter ||
- target.isSetter) {
- result = buildMethod(target);
- } else if (target.isField) {
- if (target.isInstanceMember) {
- assert(options.enableTypeAssertions);
- result = buildCheckedSetter(target);
- } else {
- result = buildLazyInitializer(target);
- }
- } else {
- reporter.internalError(target, 'Unexpected element kind $target.');
- }
- assert(result.isValid());
- return result;
- }
-
- void addWithPosition(HInstruction instruction, ast.Node node) {
- add(attachPosition(instruction, node));
- }
-
- /**
- * Returns a complete argument list for a call of [function].
- */
- List<HInstruction> completeSendArgumentsList(
- FunctionElement function,
- Selector selector,
- List<HInstruction> providedArguments,
- ast.Node currentNode) {
- assert(function.isImplementation, failedAt(function));
- assert(providedArguments != null);
-
- bool isInstanceMember = function.isInstanceMember;
- // For static calls, [providedArguments] is complete, default arguments
- // have been included if necessary, see [makeStaticArgumentList].
- if (!isInstanceMember ||
- currentNode == null || // In erroneous code, currentNode can be null.
- providedArgumentsKnownToBeComplete(currentNode) ||
- function.isGenerativeConstructorBody ||
- selector.isGetter) {
- // For these cases, the provided argument list is known to be complete.
- return providedArguments;
- } else {
- return completeDynamicSendArgumentsList(
- selector, function, providedArguments);
- }
- }
-
- /**
- * Returns a complete argument list for a dynamic call of [function]. The
- * initial argument list [providedArguments], created by
- * [addDynamicSendArgumentsToList], does not include values for default
- * arguments used in the call. The reason is that the target function (which
- * defines the defaults) is not known.
- *
- * However, inlining can only be performed when the target function can be
- * resolved statically. The defaults can therefore be included at this point.
- *
- * The [providedArguments] list contains first all positional arguments, then
- * the provided named arguments (the named arguments that are defined in the
- * [selector]) in a specific order (see [addDynamicSendArgumentsToList]).
- */
- List<HInstruction> completeDynamicSendArgumentsList(Selector selector,
- MethodElement function, List<HInstruction> providedArguments) {
- assert(selector.applies(function));
- FunctionSignature signature = function.functionSignature;
- List<HInstruction> compiledArguments = new List<HInstruction>(
- signature.parameterCount + 1); // Plus one for receiver.
-
- compiledArguments[0] = providedArguments[0]; // Receiver.
- int index = 1;
- for (; index <= signature.requiredParameterCount; index++) {
- compiledArguments[index] = providedArguments[index];
- }
- if (!signature.optionalParametersAreNamed) {
- signature.forEachOptionalParameter((element) {
- if (index < providedArguments.length) {
- compiledArguments[index] = providedArguments[index];
- } else {
- compiledArguments[index] =
- handleConstantForOptionalParameter(element);
- }
- index++;
- });
- } else {
- /* Example:
- * void foo(a, {b, d, c})
- * foo(0, d = 1, b = 2)
- *
- * providedArguments = [0, 2, 1]
- * selectorArgumentNames = [b, d]
- * signature.orderedOptionalParameters = [b, c, d]
- *
- * For each parameter name in the signature, if the argument name matches
- * we use the next provided argument, otherwise we get the default.
- */
- List<String> selectorArgumentNames =
- selector.callStructure.getOrderedNamedArguments();
- int namedArgumentIndex = 0;
- int firstProvidedNamedArgument = index;
- signature.orderedOptionalParameters.forEach((element) {
- if (namedArgumentIndex < selectorArgumentNames.length &&
- element.name == selectorArgumentNames[namedArgumentIndex]) {
- // The named argument was provided in the function invocation.
- compiledArguments[index] = providedArguments[
- firstProvidedNamedArgument + namedArgumentIndex++];
- } else {
- compiledArguments[index] =
- handleConstantForOptionalParameter(element);
- }
- index++;
- });
- }
- return compiledArguments;
- }
-
- /**
- * Try to inline [element] within the correct context of the builder. The
- * insertion point is the state of the builder.
- */
- bool tryInlineMethod(MethodElement element, Selector selector, TypeMask mask,
- List<HInstruction> providedArguments, ast.Node currentNode,
- {ResolutionInterfaceType instanceType}) {
- if (nativeData.isJsInteropMember(element) &&
- !element.isFactoryConstructor) {
- // We only inline factory JavaScript interop constructors.
- return false;
- }
-
- // Ensure that [element] is an implementation element.
- element = element.implementation;
-
- if (compiler.elementHasCompileTimeError(element)) return false;
-
- MethodElement function = element;
- MethodElement declaration = function.declaration;
- ResolvedAst functionResolvedAst = function.resolvedAst;
- bool insideLoop = loopDepth > 0 || graph.calledInLoop;
-
- // Bail out early if the inlining decision is in the cache and we can't
- // inline (no need to check the hard constraints).
- bool cachedCanBeInlined =
- inlineCache.canInline(declaration, insideLoop: insideLoop);
- if (cachedCanBeInlined == false) return false;
-
- bool meetsHardConstraints() {
- if (options.disableInlining) return false;
-
- assert(
- selector != null ||
- Elements.isStaticOrTopLevel(function) ||
- function.isGenerativeConstructorBody,
- failedAt(currentNode ?? function,
- "Missing selector for inlining of $function."));
- if (selector != null) {
- if (!selector.applies(function)) return false;
- if (mask != null && !mask.canHit(function, selector, closedWorld)) {
- return false;
- }
- }
-
- if (nativeData.isJsInteropMember(function)) return false;
-
- // Don't inline operator== methods if the parameter can be null.
- if (function.name == '==') {
- if (function.enclosingClass != commonElements.objectClass &&
- providedArguments[1].canBeNull(abstractValueDomain)) {
- return false;
- }
- }
-
- // Generative constructors of native classes should not be called directly
- // and have an extra argument that causes problems with inlining.
- if (function.isGenerativeConstructor &&
- nativeData.isNativeOrExtendsNative(function.enclosingClass)) {
- return false;
- }
-
- // A generative constructor body is not seen by global analysis,
- // so we should not query for its type.
- if (!function.isGenerativeConstructorBody) {
- if (globalInferenceResults.resultOfMember(declaration).throwsAlways) {
- isReachable = false;
- return false;
- }
- }
-
- return true;
- }
-
- bool doesNotContainCode() {
- // A function with size 1 does not contain any code.
- return InlineWeeder.canBeInlined(functionResolvedAst, 1,
- enableUserAssertions: options.enableUserAssertions);
- }
-
- bool reductiveHeuristic() {
- // The call is on a path which is executed rarely, so inline only if it
- // does not make the program larger.
- if (isCalledOnce(declaration)) {
- return InlineWeeder.canBeInlined(functionResolvedAst, null,
- enableUserAssertions: options.enableUserAssertions);
- }
- // TODO(sra): Measure if inlining would 'reduce' the size. One desirable
- // case we miss by doing nothing is inlining very simple constructors
- // where all fields are initialized with values from the arguments at this
- // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but
- // that usually means the factory constructor is left unused and not
- // emitted.
- // We at least inline bodies that are empty (and thus have a size of 1).
- return doesNotContainCode();
- }
-
- bool heuristicSayGoodToGo() {
- // Don't inline recursively
- if (inliningStack.any((entry) => entry.function == function)) {
- return false;
- }
-
- if (function.isSynthesized) return true;
-
- // Don't inline across deferred import to prevent leaking code. The only
- // exception is an empty function (which does not contain code).
- bool hasOnlyNonDeferredImportPaths = backend.outputUnitData
- .hasOnlyNonDeferredImportPaths(compiler.currentElement, function);
-
- if (!hasOnlyNonDeferredImportPaths) {
- return doesNotContainCode();
- }
-
- // Do not inline code that is rarely executed unless it reduces size.
- if (inExpressionOfThrow || inLazyInitializerExpression) {
- return reductiveHeuristic();
- }
-
- if (cachedCanBeInlined == true) {
- // We may have forced the inlining of some methods. Therefore check
- // if we can inline this method regardless of size.
- assert(InlineWeeder.canBeInlined(functionResolvedAst, null,
- allowLoops: true,
- enableUserAssertions: options.enableUserAssertions));
- return true;
- }
-
- int numParameters = function.functionSignature.parameterCount;
- int maxInliningNodes;
- if (insideLoop) {
- maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
- InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
- } else {
- maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
- InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
- }
-
- // If a method is called only once, and all the methods in the
- // inlining stack are called only once as well, we know we will
- // save on output size by inlining this method.
- if (isCalledOnce(declaration)) {
- maxInliningNodes = null;
- }
- bool canInline = InlineWeeder.canBeInlined(
- functionResolvedAst, maxInliningNodes,
- enableUserAssertions: options.enableUserAssertions);
- if (canInline) {
- inlineCache.markAsInlinable(declaration, insideLoop: insideLoop);
- } else {
- inlineCache.markAsNonInlinable(declaration, insideLoop: insideLoop);
- }
- return canInline;
- }
-
- void doInlining() {
- registry
- .registerStaticUse(new StaticUse.inlining(declaration, instanceType));
-
- // Add an explicit null check on the receiver before doing the
- // inlining. We use [element] to get the same name in the
- // NoSuchMethodError message as if we had called it.
- if (function.isInstanceMember &&
- !function.isGenerativeConstructorBody &&
- (mask == null || mask.isNullable)) {
- addWithPosition(
- new HFieldGet(null, providedArguments[0], commonMasks.dynamicType,
- isAssignable: false),
- currentNode);
- }
- List<HInstruction> compiledArguments = completeSendArgumentsList(
- function, selector, providedArguments, currentNode);
- enterInlinedMethod(
- function, functionResolvedAst, compiledArguments, instanceType);
- inlinedFrom(functionResolvedAst, () {
- if (!isReachable) {
- emitReturn(graph.addConstantNull(closedWorld), null);
- } else {
- doInline(functionResolvedAst);
- }
- });
- leaveInlinedMethod();
- }
-
- if (meetsHardConstraints() && heuristicSayGoodToGo()) {
- doInlining();
- MemberElement inlinedFrom = inliningStack.isEmpty
- ? target.declaration
- : inliningStack.last.function.declaration;
- infoReporter?.reportInlined(declaration, inlinedFrom);
- return true;
- }
-
- return false;
- }
-
- bool get allInlinedFunctionsCalledOnce {
- return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
- }
-
- bool isFunctionCalledOnce(MethodElement element) {
- // ConstructorBodyElements are not in the type inference graph.
- if (element is ConstructorBodyEntity) return false;
- return globalInferenceResults.resultOfMember(element).isCalledOnce;
- }
-
- bool isCalledOnce(MethodElement element) {
- assert(element.isDeclaration);
- return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element);
- }
-
- inlinedFrom(ResolvedAst resolvedAst, f()) {
- MemberElement element = resolvedAst.element;
- assert(element is FunctionElement || element is VariableElement);
- return reporter.withCurrentElement(element.implementation, () {
- // The [sourceElementStack] contains declaration elements.
- SourceInformationBuilder oldSourceInformationBuilder =
- sourceInformationBuilder;
- sourceInformationBuilder = sourceInformationBuilder.forContext(element);
- sourceElementStack.add(element);
- var result = f();
- sourceInformationBuilder = oldSourceInformationBuilder;
- sourceElementStack.removeLast();
- return result;
- });
- }
-
- /**
- * Return null so it is simple to remove the optional parameters completely
- * from interop methods to match JavaScript semantics for omitted arguments.
- */
- HInstruction handleConstantForOptionalParameterJsInterop(Element parameter) =>
- null;
-
- HInstruction handleConstantForOptionalParameter(ParameterElement parameter) {
- ConstantValue constantValue =
- constants.getConstantValue(parameter.constant);
- assert(constantValue != null,
- failedAt(parameter, 'No constant computed for $parameter'));
- return graph.addConstant(constantValue, closedWorld);
- }
-
- ClassElement get currentNonClosureClass {
- ClassElement cls = sourceElement.enclosingClass;
- if (cls != null && cls.isClosure) {
- dynamic closureClass = cls;
- // ignore: UNDEFINED_GETTER
- return closureClass.methodElement.enclosingClass;
- } else {
- return cls;
- }
- }
-
- /// A stack of [ResolutionDartType]s that have been seen during inlining of
- /// factory constructors. These types are preserved in [HInvokeStatic]s and
- /// [HCreate]s inside the inline code and registered during code generation
- /// for these nodes.
- // TODO(karlklose): consider removing this and keeping the (substituted) types
- // of the type variables in an environment (like the [LocalsHandler]).
- final List<ResolutionDartType> currentInlinedInstantiations =
- <ResolutionDartType>[];
-
- final List<AstInliningState> inliningStack = <AstInliningState>[];
-
- Local returnLocal;
- ResolutionDartType returnType;
-
- ConstantValue getConstantForNode(ast.Node node) {
- ConstantValue constantValue =
- constants.getConstantValueForNode(node, elements);
- assert(constantValue != null,
- failedAt(node, 'No constant computed for $node'));
- return constantValue;
- }
-
- HInstruction addConstant(ast.Node node) {
- return graph.addConstant(getConstantForNode(node), closedWorld);
- }
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [functionElement] must be an implementation element.
- */
- HGraph buildMethod(MethodElement functionElement) {
- assert(functionElement.isImplementation, failedAt(functionElement));
- MethodElement declaration = functionElement.declaration;
- graph.calledInLoop = closedWorld.isCalledInLoop(declaration);
- ast.FunctionExpression function = resolvedAst.node;
- assert(function != null);
- assert(elements.getFunctionDefinition(function) != null);
- openFunction(functionElement, function);
- String name = functionElement.name;
- if (nativeData.isJsInteropMember(functionElement)) {
- push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
- sourceInformationBuilder.buildGeneric(function)));
- var value = pop();
- closeAndGotoExit(new HReturn(abstractValueDomain, value,
- sourceInformationBuilder.buildReturn(functionElement.node)));
- return closeFunction();
- }
- assert(!function.modifiers.isExternal, failedAt(functionElement));
-
- // If [functionElement] is `operator==` we explicitly add a null check at
- // the beginning of the method. This is to avoid having call sites do the
- // null check.
- if (name == '==') {
- if (!commonElements.operatorEqHandlesNullArgument(functionElement)) {
- handleIf(
- node: function,
- visitCondition: () {
- HParameterValue parameter = parameters.values.first;
- push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
- null, commonMasks.boolType));
- },
- visitThen: () {
- closeAndGotoExit(new HReturn(
- abstractValueDomain,
- graph.addConstantBool(false, closedWorld),
- sourceInformationBuilder
- .buildImplicitReturn(functionElement)));
- },
- visitElse: null,
- sourceInformation: sourceInformationBuilder.buildIf(function.body));
- }
- }
- if (const bool.fromEnvironment('unreachable-throw')) {
- var emptyParameters = parameters.values
- .where((p) => abstractValueDomain.isEmpty(p.instructionType));
- if (emptyParameters.length > 0) {
- addComment('${emptyParameters} inferred as [empty]');
- pushInvokeStatic(
- function.body, commonElements.assertUnreachableMethod, []);
- pop();
- return closeFunction();
- }
- }
- function.body.accept(this);
- return closeFunction();
- }
-
- /// Adds a JavaScript comment to the output. The comment will be omitted in
- /// minified mode. Each line in [text] is preceded with `//` and indented.
- /// Use sparingly. In order for the comment to be retained it is modeled as
- /// having side effects which will inhibit code motion.
- // TODO(sra): Figure out how to keep comment anchored without effects.
- void addComment(String text) {
- add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)),
- commonMasks.dynamicType, <HInstruction>[],
- isStatement: true));
- }
-
- HGraph buildCheckedSetter(FieldElement field) {
- ResolvedAst resolvedAst = field.resolvedAst;
- openFunction(field, resolvedAst.node);
- HInstruction thisInstruction = localsHandler.readThis(
- sourceInformation: sourceInformationBuilder.buildDeclaration(field));
- // Use dynamic type because the type computed by the inferrer is
- // narrowed to the type annotation.
- HInstruction parameter =
- new HParameterValue(field, commonMasks.dynamicType);
- // Add the parameter as the last instruction of the entry block.
- // If the method is intercepted, we want the actual receiver
- // to be the first parameter.
- graph.entry.addBefore(graph.entry.last, parameter);
- HInstruction value = typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
- parameter, field.type);
- add(new HFieldSet(abstractValueDomain, field, thisInstruction, value));
- return closeFunction();
- }
-
- HGraph buildLazyInitializer(FieldElement variable) {
- assert(resolvedAst.element == variable,
- failedAt(variable, "Unexpected variable $variable for $resolvedAst."));
- inLazyInitializerExpression = true;
- ast.VariableDefinitions node = resolvedAst.node;
- ast.Node initializer = resolvedAst.body;
- assert(
- initializer != null,
- failedAt(
- variable, "Non-constant variable $variable has no initializer."));
- openFunction(variable, node);
- visit(initializer);
- HInstruction value = pop();
- value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
- value, variable.type);
- // In the case of multiple declarations (and some definitions) on the same
- // line, the source pointer needs to point to the right initialized
- // variable. So find the specific initialized variable we are referring to.
- ast.Node sourceInfoNode = initializer;
- for (var definition in node.definitions) {
- if (definition is ast.SendSet &&
- definition.selector.asIdentifier().source == variable.name) {
- sourceInfoNode = definition.assignmentOperator;
- break;
- }
- }
-
- closeAndGotoExit(new HReturn(abstractValueDomain, value,
- sourceInformationBuilder.buildReturn(sourceInfoNode)));
- return closeFunction();
- }
-
- /**
- * This method sets up the local state of the builder for inlining [function].
- * The arguments of the function are inserted into the [localsHandler].
- *
- * When inlining a function, [:return:] statements are not emitted as
- * [HReturn] instructions. Instead, the value of a synthetic element is
- * updated in the [localsHandler]. This function creates such an element and
- * stores it in the [returnLocal] field.
- */
- void setupStateForInlining(
- MethodElement function, List<HInstruction> compiledArguments,
- {ResolutionInterfaceType instanceType}) {
- ResolvedAst resolvedAst = function.resolvedAst;
- assert(resolvedAst != null);
- localsHandler = new LocalsHandler(
- this,
- function,
- function.memberContext,
- instanceType ?? function.contextClass?.thisType,
- nativeData,
- interceptorData);
- localsHandler.scopeInfo = closureDataLookup.getScopeInfo(function);
- returnLocal =
- new SyntheticLocal("result", function, function.memberContext);
- localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld));
-
- inTryStatement = false; // TODO(lry): why? Document.
-
- int argumentIndex = 0;
- if (function.isInstanceMember) {
- localsHandler.updateLocal(localsHandler.scopeInfo.thisLocal,
- compiledArguments[argumentIndex++]);
- }
-
- FunctionSignature signature = function.functionSignature;
- signature.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- HInstruction argument = compiledArguments[argumentIndex++];
- localsHandler.updateLocal(parameter, argument);
- });
-
- ClassElement enclosing = function.enclosingClass;
- if ((function.isConstructor || function.isGenerativeConstructorBody) &&
- rtiNeed.classNeedsTypeArguments(enclosing)) {
- enclosing.typeVariables.forEach((_typeVariable) {
- ResolutionTypeVariableType typeVariable = _typeVariable;
- HInstruction argument = compiledArguments[argumentIndex++];
- localsHandler.updateLocal(
- localsHandler.getTypeVariableAsLocal(typeVariable), argument);
- });
- }
- assert(argumentIndex == compiledArguments.length);
-
- returnType = signature.type.returnType;
- stack = <HInstruction>[];
-
- insertTraceCall(function);
- insertCoverageCall(function);
- }
-
- void restoreState(AstInliningState state) {
- localsHandler = state.oldLocalsHandler;
- returnLocal = state.oldReturnLocal;
- inTryStatement = state.inTryStatement;
- resolvedAst = state.oldResolvedAst;
- elementInferenceResults = state.oldElementInferenceResults;
- returnType = state.oldReturnType;
- assert(stack.isEmpty);
- stack = state.oldStack;
- }
-
- /**
- * Run this builder on the body of the [function] to be inlined.
- */
- void visitInlinedFunction(ResolvedAst resolvedAst) {
- MethodElement function = resolvedAst.element.implementation;
- typeBuilder.potentiallyCheckInlinedParameterTypes(function);
-
- if (resolvedAst.element.isGenerativeConstructor) {
- buildFactory(resolvedAst);
- } else {
- ast.FunctionExpression functionNode = resolvedAst.node;
- functionNode.body.accept(this);
- }
- }
-
- addInlinedInstantiation(ResolutionDartType type) {
- if (type != null) {
- currentInlinedInstantiations.add(type);
- }
- }
-
- removeInlinedInstantiation(ResolutionDartType type) {
- if (type != null) {
- currentInlinedInstantiations.removeLast();
- }
- }
-
- bool providedArgumentsKnownToBeComplete(ast.Node currentNode) {
- /* When inlining the iterator methods generated for a [:for-in:] loop, the
- * [currentNode] is the [ForIn] tree. The compiler-generated iterator
- * invocations are known to have fully specified argument lists, no default
- * arguments are used. See invocations of [pushInvokeDynamic] in
- * [visitForIn].
- */
- return currentNode.asForIn() != null;
- }
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [constructors] must contain only implementation elements.
- */
- void inlineSuperOrRedirect(
- ResolvedAst constructorResolvedAst,
- List<HInstruction> compiledArguments,
- List<ResolvedAst> constructorResolvedAsts,
- Map<FieldElement, HInstruction> fieldValues,
- FunctionElement caller) {
- ConstructorElement callee = constructorResolvedAst.element.implementation;
-
- reporter.withCurrentElement(callee, () {
- Set<ClassElement> includedClasses = new Set<ClassElement>();
- constructorResolvedAsts.add(constructorResolvedAst);
- ClassElement currentClass = caller.enclosingClass;
-
- /// Include locals for type variable used in [member].
- void includeTypeVariables(MemberElement member) {
- ClassElement enclosingClass = member.enclosingClass;
- if (!includedClasses.add(enclosingClass)) return;
-
- if (rtiNeed.classNeedsTypeArguments(enclosingClass)) {
- // If [enclosingClass] needs RTI, we have to give a value to its
- // type parameters.
- // For a super constructor call, the type is the supertype of
- // [currentClass]. For a redirecting constructor, the type is
- // the current type. [InterfaceType.asInstanceOf] takes care
- // of both.
- ResolutionInterfaceType type =
- currentClass.thisType.asInstanceOf(enclosingClass);
- type = localsHandler.substInContext(type);
- List<ResolutionDartType> arguments = type.typeArguments;
- List<ResolutionDartType> typeVariables = enclosingClass.typeVariables;
- if (!type.isRaw) {
- assert(arguments.length == typeVariables.length);
- Iterator<ResolutionDartType> variables = typeVariables.iterator;
- type.typeArguments.forEach((ResolutionDartType argument) {
- variables.moveNext();
- ResolutionTypeVariableType typeVariable = variables.current;
- localsHandler.updateLocal(
- localsHandler.getTypeVariableAsLocal(typeVariable),
- typeBuilder.analyzeTypeArgument(argument, sourceElement));
- });
- } else {
- // If the supertype is a raw type, we need to set to null the
- // type variables.
- for (ResolutionTypeVariableType variable in typeVariables) {
- localsHandler.updateLocal(
- localsHandler.getTypeVariableAsLocal(variable),
- graph.addConstantNull(closedWorld));
- }
- }
- }
- }
-
- includeTypeVariables(callee);
-
- // For redirecting constructors, the fields will be initialized later
- // by the effective target.
- if (!callee.isRedirectingGenerative) {
- callee.enclosingClass.implementation.forEachInstanceField(
- (ClassElement enclosingClass, FieldElement member) {
- includeTypeVariables(member);
- });
- inlinedFrom(constructorResolvedAst, () {
- buildFieldInitializers(
- callee.enclosingClass.implementation, fieldValues);
- });
- }
-
- int index = 0;
- FunctionSignature params = callee.functionSignature;
- params.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- HInstruction argument = compiledArguments[index++];
- // Because we are inlining the initializer, we must update
- // what was given as parameter. This will be used in case
- // there is a parameter check expression in the initializer.
- parameters[parameter] = argument;
- localsHandler.updateLocal(parameter, argument);
- // Don't forget to update the field, if the parameter is of the
- // form [:this.x:].
- if (parameter.isInitializingFormal) {
- InitializingFormalElement fieldParameterElement = parameter;
- fieldValues[fieldParameterElement.fieldElement] = argument;
- }
- });
-
- // Build the initializers in the context of the new constructor.
- ResolvedAst oldResolvedAst = resolvedAst;
- resolvedAst = callee.resolvedAst;
- final oldElementInferenceResults = elementInferenceResults;
- elementInferenceResults = globalInferenceResults.resultOfMember(callee);
- ScopeInfo oldScopeInfo = localsHandler.scopeInfo;
- ScopeInfo newScopeInfo = closureDataLookup.getScopeInfo(callee);
- localsHandler.scopeInfo = newScopeInfo;
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- localsHandler.enterScope(closureDataLookup.getCapturedScope(callee),
- sourceInformationBuilder.buildDeclaration(callee),
- forGenerativeConstructorBody: callee.isGenerativeConstructorBody);
- }
- buildInitializers(callee, constructorResolvedAsts, fieldValues);
- localsHandler.scopeInfo = oldScopeInfo;
- resolvedAst = oldResolvedAst;
- elementInferenceResults = oldElementInferenceResults;
- });
- }
-
- void buildInitializers(
- ConstructorElement constructor,
- List<ResolvedAst> constructorResolvedAsts,
- Map<FieldElement, HInstruction> fieldValues) {
- assert(
- resolvedAst.element == constructor.declaration,
- failedAt(constructor,
- "Expected ResolvedAst for $constructor, found $resolvedAst"));
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- buildParsedInitializers(
- constructor, constructorResolvedAsts, fieldValues);
- } else {
- buildSynthesizedConstructorInitializers(
- constructor, constructorResolvedAsts, fieldValues);
- }
- }
-
- void buildSynthesizedConstructorInitializers(
- ConstructorElement constructor,
- List<ResolvedAst> constructorResolvedAsts,
- Map<FieldElement, HInstruction> fieldValues) {
- assert(
- constructor.isSynthesized,
- failedAt(
- constructor, "Unexpected unsynthesized constructor: $constructor"));
- List<HInstruction> arguments = <HInstruction>[];
- HInstruction compileArgument(ParameterElement parameter) {
- return localsHandler.readLocal(parameter);
- }
-
- ConstructorElement target = constructor.definingConstructor.implementation;
- bool match = !target.isMalformed &&
- Elements.addForwardingElementArgumentsToList<HInstruction>(
- constructor,
- arguments,
- target,
- compileArgument,
- handleConstantForOptionalParameter);
- if (!match) {
- if (compiler.elementHasCompileTimeError(constructor)) {
- return;
- }
- // If this fails, the selector we constructed for the call to a
- // forwarding constructor in a mixin application did not match the
- // constructor (which, for example, may happen when the libraries are
- // not compatible for private names, see issue 20394).
- reporter.internalError(
- constructor, 'forwarding constructor call does not match');
- }
- inlineSuperOrRedirect(target.resolvedAst, arguments,
- constructorResolvedAsts, fieldValues, constructor);
- }
-
- /**
- * Run through the initializers and inline all field initializers. Recursively
- * inlines super initializers.
- *
- * The constructors of the inlined initializers is added to [constructors]
- * with sub constructors having a lower index than super constructors.
- *
- * Invariant: The [constructor] and elements in [constructors] must all be
- * implementation elements.
- */
- void buildParsedInitializers(
- ConstructorElement constructor,
- List<ResolvedAst> constructorResolvedAsts,
- Map<FieldElement, HInstruction> fieldValues) {
- assert(
- resolvedAst.element == constructor.declaration, failedAt(constructor));
- assert(constructor.isImplementation, failedAt(constructor));
- assert(
- !constructor.isSynthesized,
- failedAt(
- constructor, "Unexpected synthesized constructor: $constructor"));
- ast.FunctionExpression functionNode = resolvedAst.node;
-
- bool foundSuperOrRedirect = false;
- if (functionNode.initializers != null) {
- Link<ast.Node> initializers = functionNode.initializers.nodes;
- for (Link<ast.Node> link = initializers;
- !link.isEmpty;
- link = link.tail) {
- assert(link.head is ast.Send);
- if (link.head is! ast.SendSet) {
- // A super initializer or constructor redirection.
- foundSuperOrRedirect = true;
- ast.Send call = link.head;
- assert(ast.Initializers.isSuperConstructorCall(call) ||
- ast.Initializers.isConstructorRedirect(call));
- ConstructorElement target = elements[call];
- CallStructure callStructure =
- elements.getSelector(call).callStructure;
- Link<ast.Node> arguments = call.arguments;
- List<HInstruction> compiledArguments;
- inlinedFrom(resolvedAst, () {
- compiledArguments =
- makeStaticArgumentList(callStructure, arguments, target);
- });
- inlineSuperOrRedirect(target.resolvedAst, compiledArguments,
- constructorResolvedAsts, fieldValues, constructor);
- } else {
- // A field initializer.
- ast.SendSet init = link.head;
- Link<ast.Node> arguments = init.arguments;
- assert(!arguments.isEmpty && arguments.tail.isEmpty);
- inlinedFrom(resolvedAst, () {
- visit(arguments.head);
- });
- fieldValues[elements[init]] = pop();
- }
- }
- }
-
- if (!foundSuperOrRedirect) {
- // No super initializer found. Try to find the default constructor if
- // the class is not Object.
- ClassElement enclosingClass = constructor.enclosingClass;
- ClassElement superClass = enclosingClass.superclass;
- if (!enclosingClass.isObject) {
- assert(superClass != null);
- assert(superClass.isResolved);
- // TODO(johnniwinther): Should we find injected constructors as well?
- FunctionElement target = superClass.lookupDefaultConstructor();
- if (target == null) {
- reporter.internalError(
- superClass, "No default constructor available.");
- }
- List<HInstruction> arguments = Elements.makeArgumentsList<HInstruction>(
- CallStructure.NO_ARGS,
- const Link<ast.Node>(),
- target.implementation,
- null,
- handleConstantForOptionalParameter);
- inlineSuperOrRedirect(target.resolvedAst, arguments,
- constructorResolvedAsts, fieldValues, constructor);
- }
- }
- }
-
- /**
- * Run through the fields of [cls] and add their potential
- * initializers.
- *
- * Invariant: [classElement] must be an implementation element.
- */
- void buildFieldInitializers(
- ClassElement classElement, Map<Element, HInstruction> fieldValues) {
- assert(classElement.isImplementation, failedAt(classElement));
- classElement.forEachInstanceField(
- (ClassElement enclosingClass, FieldElement member) {
- if (compiler.elementHasCompileTimeError(member)) return;
- reporter.withCurrentElement(member, () {
- ResolvedAst fieldResolvedAst = member.resolvedAst;
- ast.Expression initializer = fieldResolvedAst.body;
- if (initializer == null) {
- // Unassigned fields of native classes are not initialized to
- // prevent overwriting pre-initialized native properties.
- if (!nativeData.isNativeOrExtendsNative(classElement)) {
- fieldValues[member] = graph.addConstantNull(closedWorld);
- }
- } else {
- ast.Node right = initializer;
- ResolvedAst savedResolvedAst = resolvedAst;
- resolvedAst = fieldResolvedAst;
- final oldElementInferenceResults = elementInferenceResults;
- elementInferenceResults =
- globalInferenceResults.resultOfMember(member);
- inlinedFrom(fieldResolvedAst, () => right.accept(this));
- resolvedAst = savedResolvedAst;
- elementInferenceResults = oldElementInferenceResults;
- fieldValues[member] = pop();
- }
- });
- });
- }
-
- /**
- * Build the factory function corresponding to the constructor
- * [functionElement]:
- * - Initialize fields with the values of the field initializers of the
- * current constructor and super constructors or constructors redirected
- * to, starting from the current constructor.
- * - Call the constructor bodies, starting from the constructor(s) in the
- * super class(es).
- */
- HGraph buildFactory(ResolvedAst resolvedAst) {
- ConstructorElement functionElement = resolvedAst.element;
- functionElement = functionElement.implementation;
- ClassElement classElement = functionElement.enclosingClass.implementation;
- bool isNativeUpgradeFactory =
- nativeData.isNativeOrExtendsNative(classElement) &&
- !nativeData.isJsInteropClass(classElement);
- ast.FunctionExpression function;
- if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- function = resolvedAst.node;
- }
-
- // Note that constructors (like any other static function) do not need
- // to deal with optional arguments. It is the callers job to provide all
- // arguments as if they were positional.
-
- if (inliningStack.isEmpty) {
- // The initializer list could contain closures.
- openFunction(functionElement, function);
- }
-
- Map<FieldElement, HInstruction> fieldValues =
- new Map<FieldElement, HInstruction>();
-
- // Compile the possible initialization code for local fields and
- // super fields, unless this is a redirecting constructor, in which case
- // the effective target will initialize these.
- if (!functionElement.isRedirectingGenerative) {
- buildFieldInitializers(classElement, fieldValues);
- }
-
- // Compile field-parameters such as [:this.x:].
- FunctionSignature params = functionElement.functionSignature;
- params.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- if (parameter.isInitializingFormal) {
- // If the [element] is a field-parameter then
- // initialize the field element with its value.
- InitializingFormalElement fieldParameter = parameter;
- HInstruction parameterValue = localsHandler.readLocal(fieldParameter);
- fieldValues[fieldParameter.fieldElement] = parameterValue;
- }
- });
-
- // Analyze the constructor and all referenced constructors and collect
- // initializers and constructor bodies.
- List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst];
- buildInitializers(functionElement, constructorResolvedAsts, fieldValues);
-
- // Call the JavaScript constructor with the fields as argument.
- List<HInstruction> constructorArguments = <HInstruction>[];
- List<FieldEntity> fields = <FieldEntity>[];
-
- classElement.forEachInstanceField(
- (ClassElement enclosingClass, FieldElement member) {
- HInstruction value = fieldValues[member];
- if (value == null) {
- // Uninitialized native fields are pre-initialized by the native
- // implementation.
- assert(isNativeUpgradeFactory || reporter.hasReportedError,
- failedAt(member));
- } else {
- fields.add(member);
- ResolutionDartType type = localsHandler.substInContext(member.type);
- constructorArguments.add(
- typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type));
- }
- }, includeSuperAndInjectedMembers: true);
-
- ResolutionInterfaceType type = classElement.thisType;
- TypeMask ssaType =
- new TypeMask.nonNullExact(classElement.declaration, closedWorld);
- List<DartType> instantiatedTypes;
- addInlinedInstantiation(type);
- if (!currentInlinedInstantiations.isEmpty) {
- instantiatedTypes =
- new List<ResolutionInterfaceType>.from(currentInlinedInstantiations);
- }
-
- HInstruction newObject;
- if (!isNativeUpgradeFactory) {
- // Create the runtime type information, if needed.
- bool hasRtiInput = false;
- if (rtiNeed.classNeedsTypeArguments(classElement.declaration)) {
- // Read the values of the type arguments and create a
- // HTypeInfoExpression to set on the newly create object.
- hasRtiInput = true;
- List<HInstruction> typeArguments = <HInstruction>[];
- classElement.typeVariables.forEach((_typeVariable) {
- ResolutionTypeVariableType typeVariable = _typeVariable;
- HInstruction argument = localsHandler
- .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
- typeArguments.add(argument);
- });
-
- HInstruction typeInfo = new HTypeInfoExpression(
- TypeInfoExpressionKind.INSTANCE,
- classElement.thisType,
- typeArguments,
- commonMasks.dynamicType);
- add(typeInfo);
- constructorArguments.add(typeInfo);
- }
-
- newObject = new HCreate(
- classElement,
- constructorArguments,
- ssaType,
- function != null
- ? sourceInformationBuilder.buildCreate(function)
- : sourceInformationBuilder.buildDeclaration(functionElement),
- instantiatedTypes: instantiatedTypes,
- hasRtiInput: hasRtiInput);
- add(newObject);
- } else {
- // Bulk assign to the initialized fields.
- newObject = graph.explicitReceiverParameter;
- // Null guard ensures an error if we are being called from an explicit
- // 'new' of the constructor instead of via an upgrade. It is optimized out
- // if there are field initializers.
- add(new HFieldGet(null, newObject, commonMasks.dynamicType,
- isAssignable: false));
- for (int i = 0; i < fields.length; i++) {
- add(new HFieldSet(abstractValueDomain, fields[i], newObject,
- constructorArguments[i]));
- }
- }
- removeInlinedInstantiation(type);
-
- // Generate calls to the constructor bodies.
- HInstruction interceptor = null;
- for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) {
- ResolvedAst constructorResolvedAst = constructorResolvedAsts[index];
- ConstructorElement constructor =
- constructorResolvedAst.element.implementation;
- ConstructorBodyElement body =
- ConstructorBodyElementX.createFromResolvedAst(constructorResolvedAst);
- if (body == null) continue;
-
- List bodyCallInputs = <HInstruction>[];
- if (isNativeUpgradeFactory) {
- if (interceptor == null) {
- ConstantValue constant = new InterceptorConstantValue(classElement);
- interceptor = graph.addConstant(constant, closedWorld);
- }
- bodyCallInputs.add(interceptor);
- }
- bodyCallInputs.add(newObject);
-
- FunctionSignature functionSignature = body.functionSignature;
- // Provide the parameters to the generative constructor body.
- functionSignature.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- // If [parameter] is boxed, it will be a field in the box passed as the
- // last parameter. So no need to directly pass it.
- if (!localsHandler.isBoxed(parameter)) {
- bodyCallInputs.add(localsHandler.readLocal(parameter));
- }
- });
-
- // If there are locals that escape (ie mutated in closures), we
- // pass the box to the constructor.
- // The box must be passed before any type variable.
- CapturedScope scopeData = closureDataLookup.getCapturedScope(constructor);
- if (scopeData.requiresContextBox) {
- bodyCallInputs.add(localsHandler.readLocal(scopeData.context));
- }
-
- // Type variables arguments must come after the box (if there is one).
- ClassElement currentClass = constructor.enclosingClass;
- if (rtiNeed.classNeedsTypeArguments(currentClass)) {
- // If [currentClass] needs RTI, we add the type variables as
- // parameters of the generative constructor body.
- currentClass.typeVariables.forEach((_argument) {
- ResolutionTypeVariableType argument = _argument;
- // TODO(johnniwinther): Substitute [argument] with
- // `localsHandler.substInContext(argument)`.
- bodyCallInputs.add(localsHandler
- .readLocal(localsHandler.getTypeVariableAsLocal(argument)));
- });
- }
-
- if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining.
- tryInlineMethod(body, null, null, bodyCallInputs, function)) {
- pop();
- } else {
- ConstructorBodyElement declaration = body.declaration;
- HInvokeConstructorBody invoke = new HInvokeConstructorBody(
- declaration,
- bodyCallInputs,
- commonMasks.nonNullType,
- sourceInformationBuilder.buildDeclaration(constructor));
- invoke.sideEffects = closedWorld.getSideEffectsOfElement(constructor);
- add(invoke);
- }
- }
- if (inliningStack.isEmpty) {
- closeAndGotoExit(new HReturn(abstractValueDomain, newObject,
- sourceInformationBuilder.buildImplicitReturn(functionElement)));
- return closeFunction();
- } else {
- localsHandler.updateLocal(returnLocal, newObject);
- return null;
- }
- }
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [functionElement] must be the implementation element.
- */
- void openFunction(MemberElement element, ast.Node node) {
- assert(element.isImplementation, failedAt(element));
- HBasicBlock block = graph.addNewBlock();
- open(graph.entry);
-
- Map<Local, TypeMask> parameters = <Local, TypeMask>{};
- if (element is MethodElement) {
- element.functionSignature.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- parameters[parameter] = TypeMaskFactory.inferredTypeForParameter(
- parameter, globalInferenceResults);
- });
- }
-
- localsHandler.startFunction(
- element,
- closureDataLookup.getScopeInfo(element),
- closureDataLookup.getCapturedScope(element),
- parameters,
- sourceInformationBuilder.buildDeclaration(element),
- isGenerativeConstructorBody: element.isGenerativeConstructorBody);
- close(new HGoto(abstractValueDomain)).addSuccessor(block);
-
- open(block);
-
- // Add the type parameters of the class as parameters of this method. This
- // must be done before adding the normal parameters, because their types
- // may contain references to type variables.
- ClassElement cls = element.enclosingClass;
- if ((element.isConstructor || element.isGenerativeConstructorBody) &&
- rtiNeed.classNeedsTypeArguments(cls)) {
- cls.typeVariables.forEach((_typeVariable) {
- ResolutionTypeVariableType typeVariable = _typeVariable;
- HParameterValue param =
- addParameter(typeVariable.element, commonMasks.nonNullType);
- localsHandler.directLocals[
- localsHandler.getTypeVariableAsLocal(typeVariable)] = param;
- });
- }
-
- if (element is MethodElement) {
- MethodElement functionElement = element;
- FunctionSignature signature = functionElement.functionSignature;
-
- // Put the type checks in the first successor of the entry,
- // because that is where the type guards will also be inserted.
- // This way we ensure that a type guard will dominate the type
- // check.
- signature.forEachParameter((_parameterElement) {
- ParameterElement parameterElement = _parameterElement;
- if (element.isGenerativeConstructorBody) {
- if (closureDataLookup
- .getCapturedScope(element)
- .isBoxed(parameterElement)) {
- // The parameter will be a field in the box passed as the
- // last parameter. So no need to have it.
- return;
- }
- }
- HInstruction newParameter =
- localsHandler.directLocals[parameterElement];
- if (!element.isConstructor ||
- !(element as ConstructorElement).isRedirectingFactory) {
- // Redirection factories must not check their argument types.
- // Example:
- //
- // class A {
- // A(String foo) = A.b;
- // A.b(int foo) { print(foo); }
- // }
- // main() {
- // new A(499); // valid even in checked mode.
- // new A("foo"); // invalid in checked mode.
- //
- // Only the final target is allowed to check for the argument types.
- newParameter = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
- newParameter, parameterElement.type);
- }
- localsHandler.directLocals[parameterElement] = newParameter;
- });
-
- returnType = signature.type.returnType;
- } else {
- // Otherwise it is a lazy initializer which does not have parameters.
- assert(element is VariableElement);
- }
-
- insertTraceCall(element);
- insertCoverageCall(element);
- }
-
- insertTraceCall(Element element) {
- if (JavaScriptBackend.TRACE_METHOD == 'console') {
- if (element == commonElements.traceHelper) return;
- n(e) => e == null ? '' : e.name;
- String name = "${n(element.library)}:${n(element.enclosingClass)}."
- "${n(element)}";
- HConstant nameConstant = addConstantString(name);
- add(new HInvokeStatic(
- commonElements.traceHelper,
- <HInstruction>[nameConstant],
- commonMasks.dynamicType,
- const <DartType>[]));
- }
- }
-
- insertCoverageCall(Element element) {
- if (JavaScriptBackend.TRACE_METHOD == 'post') {
- if (element == commonElements.traceHelper) return;
- // TODO(sigmund): create a better uuid for elements.
- HConstant idConstant =
- graph.addConstantInt(element.hashCode, closedWorld);
- HConstant nameConstant = addConstantString(element.name);
- add(new HInvokeStatic(
- commonElements.traceHelper,
- <HInstruction>[idConstant, nameConstant],
- commonMasks.dynamicType,
- const <DartType>[]));
- }
- }
-
- void assertIsSubtype(
- ast.Node node,
- ResolutionDartType subtype,
- ResolutionDartType supertype,
- String prefix,
- String infix,
- String suffix) {
- HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument(
- localsHandler.substInContext(subtype), sourceElement);
- HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument(
- localsHandler.substInContext(supertype), sourceElement);
- HInstruction prefixInstruction =
- graph.addConstantString(prefix, closedWorld);
- HInstruction infixInstruction = graph.addConstantString(infix, closedWorld);
- HInstruction suffixInstruction =
- graph.addConstantString(suffix, closedWorld);
- MethodElement element = commonElements.assertIsSubtype;
- var inputs = <HInstruction>[
- subtypeInstruction,
- supertypeInstruction,
- prefixInstruction,
- infixInstruction,
- suffixInstruction,
- ];
- HInstruction assertIsSubtype = new HInvokeStatic(element, inputs,
- subtypeInstruction.instructionType, const <DartType>[]);
- registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
- add(assertIsSubtype);
- }
-
- HGraph closeFunction() {
- // TODO(kasperl): Make this goto an implicit return.
- if (!isAborted()) closeAndGotoExit(new HGoto(abstractValueDomain));
- graph.finalize(abstractValueDomain);
- return graph;
- }
-
- void pushWithPosition(HInstruction instruction, ast.Node node) {
- push(attachPosition(instruction, node));
- }
-
- /// Pops the most recent instruction from the stack and 'boolifies' it.
- ///
- /// Boolification is checking if the value is '=== true'.
- @override
- HInstruction popBoolified() {
- HInstruction value = pop();
- if (typeBuilder.checkOrTrustTypes) {
- ResolutionInterfaceType boolType = commonElements.boolType;
- return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
- value, boolType,
- kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
- }
- HInstruction result = new HBoolify(value, commonMasks.boolType)
- ..sourceInformation = value.sourceInformation;
- add(result);
- return result;
- }
-
- HInstruction attachPosition(HInstruction target, ast.Node node) {
- if (node != null) {
- target.sourceInformation = sourceInformationBuilder.buildGeneric(node);
- }
- return target;
- }
-
- void visit(ast.Node node) {
- if (node != null) node.accept(this);
- }
-
- /// Visit [node] and pop the resulting [HInstruction].
- HInstruction visitAndPop(ast.Node node) {
- node.accept(this);
- return pop();
- }
-
- visitAssert(ast.Assert node) {
- if (!options.enableUserAssertions) return;
-
- if (!node.hasMessage) {
- // Generate:
- //
- // assertHelper(condition);
- //
- visit(node.condition);
- pushInvokeStatic(node, commonElements.assertHelper, [pop()]);
- pop();
- return;
- }
- // Assert has message. Generate:
- //
- // if (assertTest(condition)) assertThrow(message);
- //
- void buildCondition() {
- visit(node.condition);
- pushInvokeStatic(node, commonElements.assertTest, [pop()]);
- }
-
- void fail() {
- visit(node.message);
- pushInvokeStatic(node, commonElements.assertThrow, [pop()]);
- pop();
- }
-
- handleIf(node: node, visitCondition: buildCondition, visitThen: fail);
- }
-
- visitBlock(ast.Block node) {
- assert(!isAborted());
- if (!isReachable) return; // This can only happen when inlining.
- for (Link<ast.Node> link = node.statements.nodes;
- !link.isEmpty;
- link = link.tail) {
- visit(link.head);
- if (!isReachable) {
- // The block has been aborted by a return or a throw.
- if (!stack.isEmpty) {
- reporter.internalError(node, 'Non-empty instruction stack.');
- }
- return;
- }
- }
- assert(!current.isClosed());
- if (!stack.isEmpty) {
- reporter.internalError(node, 'Non-empty instruction stack.');
- }
- }
-
- visitClassNode(ast.ClassNode node) {
- reporter.internalError(
- node, 'SsaBuilder.visitClassNode should not be called.');
- }
-
- visitThrowExpression(ast.Expression expression) {
- bool old = inExpressionOfThrow;
- try {
- inExpressionOfThrow = true;
- visit(expression);
- } finally {
- inExpressionOfThrow = old;
- }
- }
-
- visitExpressionStatement(ast.ExpressionStatement node) {
- if (!isReachable) return;
- ast.Throw throwExpression = node.expression.asThrow();
- if (throwExpression != null && inliningStack.isEmpty) {
- visitThrowExpression(throwExpression.expression);
- handleInTryStatement();
- closeAndGotoExit(new HThrow(abstractValueDomain, pop(),
- sourceInformationBuilder.buildThrow(node)));
- } else {
- visit(node.expression);
- pop();
- }
- }
-
- visitFor(ast.For node) {
- assert(isReachable);
- assert(node.body != null);
- void buildInitializer() {
- ast.Node initializer = node.initializer;
- if (initializer == null) return;
- visit(initializer);
- if (initializer.asExpression() != null) {
- pop();
- }
- }
-
- HInstruction buildCondition() {
- if (node.condition == null) {
- return graph.addConstantBool(true, closedWorld);
- }
- visit(node.condition);
- return popBoolified();
- }
-
- void buildUpdate() {
- for (ast.Expression expression in node.update) {
- visit(expression);
- assert(!isAborted());
- // The result of the update instruction isn't used, and can just
- // be dropped.
- pop();
- }
- }
-
- void buildBody() {
- visit(node.body);
- }
-
- loopHandler.handleLoop(
- node,
- closureDataLookup.getCapturedLoopScope(node),
- elements.getTargetDefinition(node),
- buildInitializer,
- buildCondition,
- buildUpdate,
- buildBody,
- sourceInformationBuilder.buildLoop(node));
- }
-
- visitWhile(ast.While node) {
- assert(isReachable);
- HInstruction buildCondition() {
- visit(node.condition);
- return popBoolified();
- }
-
- loopHandler.handleLoop(node, closureDataLookup.getCapturedLoopScope(node),
- elements.getTargetDefinition(node), () {}, buildCondition, () {}, () {
- visit(node.body);
- }, sourceInformationBuilder.buildLoop(node));
- }
-
- visitDoWhile(ast.DoWhile node) {
- assert(isReachable);
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildLoop(node);
- LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
- var loopClosureInfo = closureDataLookup.getCapturedLoopScope(node);
- localsHandler.startLoop(loopClosureInfo, sourceInformation);
- loopDepth++;
- JumpTarget target = elements.getTargetDefinition(node);
- JumpHandler jumpHandler = loopHandler.beginLoopHeader(node, target);
- HLoopInformation loopInfo = current.loopInformation;
- HBasicBlock loopEntryBlock = current;
- HBasicBlock bodyEntryBlock = current;
- bool hasContinues = target != null && target.isContinueTarget;
- if (hasContinues) {
- // Add extra block to hang labels on.
- // It doesn't currently work if they are on the same block as the
- // HLoopInfo. The handling of HLabeledBlockInformation will visit a
- // SubGraph that starts at the same block again, so the HLoopInfo is
- // either handled twice, or it's handled after the labeled block info,
- // both of which generate the wrong code.
- // Using a separate block is just a simple workaround.
- bodyEntryBlock = openNewBlock();
- }
- localsHandler.enterLoopBody(loopClosureInfo, sourceInformation);
- visit(node.body);
-
- // If there are no continues we could avoid the creation of the condition
- // block. This could also lead to a block having multiple entries and exits.
- HBasicBlock bodyExitBlock;
- bool isAbortingBody = false;
- if (current != null) {
- bodyExitBlock = close(new HGoto(abstractValueDomain));
- } else {
- isAbortingBody = true;
- bodyExitBlock = lastOpenedBlock;
- }
-
- SubExpression conditionExpression;
- bool loopIsDegenerate = isAbortingBody && !hasContinues;
- if (!loopIsDegenerate) {
- HBasicBlock conditionBlock = addNewBlock();
-
- List<LocalsHandler> continueHandlers = <LocalsHandler>[];
- jumpHandler
- .forEachContinue((HContinue instruction, LocalsHandler locals) {
- instruction.block.addSuccessor(conditionBlock);
- continueHandlers.add(locals);
- });
-
- if (!isAbortingBody) {
- bodyExitBlock.addSuccessor(conditionBlock);
- }
-
- if (!continueHandlers.isEmpty) {
- if (!isAbortingBody) continueHandlers.add(localsHandler);
- localsHandler =
- savedLocals.mergeMultiple(continueHandlers, conditionBlock);
- SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
- List<LabelDefinition> labels = jumpHandler.labels;
- HSubGraphBlockInformation bodyInfo =
- new HSubGraphBlockInformation(bodyGraph);
- HLabeledBlockInformation info;
- if (!labels.isEmpty) {
- info =
- new HLabeledBlockInformation(bodyInfo, labels, isContinue: true);
- } else {
- info = new HLabeledBlockInformation.implicit(bodyInfo, target,
- isContinue: true);
- }
- bodyEntryBlock.setBlockFlow(info, conditionBlock);
- }
- open(conditionBlock);
-
- visit(node.condition);
- assert(!isAborted());
- HInstruction conditionInstruction = popBoolified();
- HBasicBlock conditionEndBlock = close(new HLoopBranch(abstractValueDomain,
- conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
-
- HBasicBlock avoidCriticalEdge = addNewBlock();
- conditionEndBlock.addSuccessor(avoidCriticalEdge);
- open(avoidCriticalEdge);
- close(new HGoto(abstractValueDomain));
- avoidCriticalEdge.addSuccessor(loopEntryBlock); // The back-edge.
-
- conditionExpression =
- new SubExpression(conditionBlock, conditionEndBlock);
-
- // Avoid a critical edge from the condition to the loop-exit body.
- HBasicBlock conditionExitBlock = addNewBlock();
- open(conditionExitBlock);
- close(new HGoto(abstractValueDomain));
- conditionEndBlock.addSuccessor(conditionExitBlock);
-
- loopHandler.endLoop(
- loopEntryBlock, conditionExitBlock, jumpHandler, localsHandler);
-
- loopEntryBlock.postProcessLoopHeader();
- SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock);
- HLoopBlockInformation loopBlockInfo = new HLoopBlockInformation(
- HLoopBlockInformation.DO_WHILE_LOOP,
- null,
- wrapExpressionGraph(conditionExpression),
- wrapStatementGraph(bodyGraph),
- null,
- loopEntryBlock.loopInformation.target,
- loopEntryBlock.loopInformation.labels,
- sourceInformation);
- loopEntryBlock.setBlockFlow(loopBlockInfo, current);
- loopInfo.loopBlockInformation = loopBlockInfo;
- } else {
- // Since the loop has no back edge, we remove the loop information on the
- // header.
- loopEntryBlock.loopInformation = null;
-
- if (jumpHandler.hasAnyBreak()) {
- // Null branchBlock because the body of the do-while loop always aborts,
- // so we never get to the condition.
- loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler);
-
- // Since the body of the loop has a break, we attach a synthesized label
- // to the body.
- SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
- JumpTarget target = elements.getTargetDefinition(node);
- LabelDefinition label =
- target.addLabel(null, 'loop', isBreakTarget: true);
- HLabeledBlockInformation info = new HLabeledBlockInformation(
- new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]);
- loopEntryBlock.setBlockFlow(info, current);
- jumpHandler.forEachBreak((HBreak breakInstruction, _) {
- HBasicBlock block = breakInstruction.block;
- block.addAtExit(new HBreak.toLabel(
- abstractValueDomain, label, sourceInformation));
- block.remove(breakInstruction);
- });
- }
- }
- jumpHandler.close();
- loopDepth--;
- }
-
- visitFunctionExpression(ast.FunctionExpression node) {
- ClosureRepresentationInfo closureInfo =
- closureDataLookup.getClosureInfo(node);
- ClassEntity closureClassEntity = closureInfo.closureClassEntity;
-
- List<HInstruction> capturedVariables = <HInstruction>[];
- compiler.codegenWorldBuilder.forEachInstanceField(closureClassEntity,
- (_, FieldEntity field) {
- capturedVariables
- .add(localsHandler.readLocal(closureInfo.getLocalForField(field)));
- });
-
- TypeMask type = new TypeMask.nonNullExact(closureClassEntity, closedWorld);
- push(new HCreate(closureClassEntity, capturedVariables, type,
- sourceInformationBuilder.buildCreate(node),
- callMethod: closureInfo.callMethod));
- }
-
- visitFunctionDeclaration(ast.FunctionDeclaration node) {
- assert(isReachable);
- visit(node.function);
- LocalFunctionElement localFunction =
- elements.getFunctionDefinition(node.function);
- localsHandler.updateLocal(localFunction, pop());
- }
-
- @override
- void visitThisGet(ast.Identifier node, [_]) {
- stack.add(localsHandler.readThis(
- sourceInformation: sourceInformationBuilder.buildGet(node)));
- }
-
- visitIdentifier(ast.Identifier node) {
- if (node.isThis()) {
- visitThisGet(node);
- } else {
- reporter.internalError(
- node, "SsaFromAstMixin.visitIdentifier on non-this.");
- }
- }
-
- void handleIf(
- {ast.Node node,
- void visitCondition(),
- void visitThen(),
- void visitElse(),
- SourceInformation sourceInformation}) {
- SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
- branchBuilder.handleIf(visitCondition, visitThen, visitElse,
- sourceInformation: sourceInformation);
- }
-
- visitIf(ast.If node) {
- assert(isReachable);
- handleIf(
- node: node,
- visitCondition: () => visit(node.condition),
- visitThen: () => visit(node.thenPart),
- visitElse: node.elsePart != null ? () => visit(node.elsePart) : null,
- sourceInformation: sourceInformationBuilder.buildIf(node));
- }
-
- @override
- void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleIfNull(() => visit(left), () => visit(right));
- }
-
- /// Optimizes logical binary where the left is also a logical binary.
- ///
- /// This method transforms the operator by optimizing the case where [left] is
- /// a logical "and" or logical "or". Then it uses [branchBuilder] to build the
- /// graph for the optimized expression.
- ///
- /// For example, `(x && y) && z` is transformed into `x && (y && z)`:
- ///
- /// t0 = boolify(x);
- /// if (t0) {
- /// t1 = boolify(y);
- /// if (t1) {
- /// t2 = boolify(z);
- /// }
- /// t3 = phi(t2, false);
- /// }
- /// result = phi(t3, false);
- void handleLogicalBinaryWithLeftNode(ast.Node left, void visitRight(),
- SsaBranchBuilder branchBuilder, SourceInformation sourceInformation,
- {bool isAnd}) {
- ast.Send send = left.asSend();
- if (send != null && (isAnd ? send.isLogicalAnd : send.isLogicalOr)) {
- ast.Node newLeft = send.receiver;
- Link<ast.Node> link = send.argumentsNode.nodes;
- assert(link.tail.isEmpty);
- ast.Node middle = link.head;
- handleLogicalBinaryWithLeftNode(
- newLeft,
- () => handleLogicalBinaryWithLeftNode(middle, visitRight,
- branchBuilder, sourceInformationBuilder.buildBinary(middle),
- isAnd: isAnd),
- branchBuilder,
- sourceInformation,
- isAnd: isAnd);
- } else {
- branchBuilder.handleLogicalBinary(
- () => visit(left), visitRight, sourceInformation,
- isAnd: isAnd);
- }
- }
-
- @override
- void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) {
- SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
- handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder,
- sourceInformationBuilder.buildBinary(node),
- isAnd: true);
- }
-
- @override
- void visitLogicalOr(ast.Send node, ast.Node left, ast.Node right, _) {
- SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
- handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder,
- sourceInformationBuilder.buildBinary(node),
- isAnd: false);
- }
-
- @override
- void visitNot(ast.Send node, ast.Node expression, _) {
- assert(node.argumentsNode is ast.Prefix);
- visit(expression);
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildGeneric(node);
- push(new HNot(popBoolified(), commonMasks.boolType)
- ..sourceInformation = sourceInformation);
- }
-
- @override
- void visitUnary(
- ast.Send node, UnaryOperator operator, ast.Node expression, _) {
- assert(node.argumentsNode is ast.Prefix);
- HInstruction operand = visitAndPop(expression);
-
- // See if we can constant-fold right away. This avoids rewrites later on.
- if (operand is HConstant) {
- UnaryOperation operation = constantSystem.lookupUnary(operator);
- HConstant constant = operand;
- ConstantValue folded = operation.fold(constant.constant);
- if (folded != null) {
- stack.add(graph.addConstant(folded, closedWorld));
- return;
- }
- }
-
- pushInvokeDynamic(node, elements.getSelector(node),
- elementInferenceResults.typeOfSend(node), [operand],
- sourceInformation: sourceInformationBuilder.buildGeneric(node));
- }
-
- @override
- void visitBinary(ast.Send node, ast.Node left, BinaryOperator operator,
- ast.Node right, _) {
- handleBinary(node, left, right);
- }
-
- @override
- void visitIndex(ast.Send node, ast.Node receiver, ast.Node index, _) {
- generateDynamicSend(node);
- }
-
- @override
- void visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
- handleBinary(node, left, right);
- }
-
- @override
- void visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) {
- handleBinary(node, left, right);
- pushWithPosition(
- new HNot(popBoolified(), commonMasks.boolType), node.selector);
- }
-
- void handleBinary(ast.Send node, ast.Node left, ast.Node right) {
- visitBinarySend(
- visitAndPop(left),
- visitAndPop(right),
- elements.getSelector(node),
- elementInferenceResults.typeOfSend(node),
- node,
- sourceInformation:
- sourceInformationBuilder.buildGeneric(node.selector));
- }
-
- /// TODO(johnniwinther): Merge [visitBinarySend] with [handleBinary] and
- /// remove use of [location] for source information.
- void visitBinarySend(HInstruction left, HInstruction right, Selector selector,
- TypeMask mask, ast.Send send,
- {SourceInformation sourceInformation}) {
- pushInvokeDynamic(send, selector, mask, [left, right],
- sourceInformation: sourceInformation);
- }
-
- HInstruction generateInstanceSendReceiver(ast.Send send) {
- assert(Elements.isInstanceSend(send, elements));
- if (send.receiver == null) {
- return localsHandler.readThis(
- sourceInformation: sourceInformationBuilder.buildGet(send));
- }
- visit(send.receiver);
- return pop();
- }
-
- String noSuchMethodTargetSymbolString(Element error, [String prefix]) {
- String result = error.name;
- if (prefix == "set") return "$result=";
- return result;
- }
-
- /**
- * Returns a set of interceptor classes that contain the given
- * [selector].
- */
- void generateInstanceGetterWithCompiledReceiver(
- ast.Send send, Selector selector, TypeMask mask, HInstruction receiver) {
- assert(Elements.isInstanceSend(send, elements));
- assert(selector.isGetter);
- pushInvokeDynamic(send, selector, mask, [receiver],
- sourceInformation: sourceInformationBuilder.buildGet(send));
- }
-
- /// Inserts a call to checkDeferredIsLoaded for a deferred [import].
- /// If [import] is [null], do nothing.
- void generateIsDeferredLoadedCheckIfNeeded(
- ImportElement import, ast.Node location) {
- if (import == null) return;
- String loadId = deferredLoadTask.getImportDeferName(location, import);
- HInstruction loadIdConstant = addConstantString(loadId);
- String uri = import.uri.toString();
- HInstruction uriConstant = addConstantString(uri);
- MethodElement helper = commonElements.checkDeferredIsLoaded;
- pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]);
- pop();
- }
-
- /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that
- /// resolves to a deferred library.
- void generateIsDeferredLoadedCheckOfSend(ast.Send node) {
- generateIsDeferredLoadedCheckIfNeeded(
- deferredLoadTask.deferredImportElement(node, elements), node);
- }
-
- void handleInvalidStaticGet(ast.Send node, Element element) {
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildGet(node);
- generateThrowNoSuchMethod(
- node, noSuchMethodTargetSymbolString(element, 'get'),
- argumentNodes: const Link<ast.Node>(),
- sourceInformation: sourceInformation);
- }
-
- /// Generate read access of an unresolved static or top level entity.
- void generateStaticUnresolvedGet(ast.Send node, Element element) {
- if (element is ErroneousElement) {
- // An erroneous element indicates an unresolved static getter.
- handleInvalidStaticGet(node, element);
- } else {
- // This happens when [element] has parse errors.
- assert(element == null || element.isMalformed, failedAt(node));
- // TODO(ahe): Do something like the above, that is, emit a runtime
- // error.
- stack.add(graph.addConstantNull(closedWorld));
- }
- }
-
- /// Read a static or top level [field] of constant value.
- void generateStaticConstGet(ast.Send node, FieldElement field,
- ConstantExpression constant, SourceInformation sourceInformation) {
- ConstantValue value = constants.getConstantValue(constant);
- HConstant instruction;
- // Constants that are referred via a deferred prefix should be referred
- // by reference.
- ImportElement deferredImport =
- deferredLoadTask.deferredImportElement(node, elements);
- if (deferredImport != null) {
- OutputUnit unit =
- compiler.backend.outputUnitData.outputUnitForMember(field);
- instruction = graph.addDeferredConstant(
- value, unit, sourceInformation, compiler, closedWorld);
- } else {
- instruction = graph.addConstant(value, closedWorld,
- sourceInformation: sourceInformation);
- }
- stack.add(instruction);
- // The inferrer may have found a better type than the constant
- // handler in the case of lists, because the constant handler
- // does not look at elements in the list.
- TypeMask type =
- TypeMaskFactory.inferredTypeForMember(field, globalInferenceResults);
- if (!type.containsAll(closedWorld) && !instruction.isConstantNull()) {
- // TODO(13429): The inferrer should know that an element
- // cannot be null.
- instruction.instructionType = type.nonNullable();
- }
- }
-
- @override
- void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
- generateIsDeferredLoadedCheckIfNeeded(prefix.deferredImport, node);
- }
-
- /// Read a static or top level [field].
- void generateStaticFieldGet(ast.Send node, FieldElement field) {
- ConstantExpression constant = field.constant;
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildGet(node.selector);
- if (constant != null) {
- if (!field.isAssignable) {
- // A static final or const. Get its constant value and inline it if
- // the value can be compiled eagerly.
- generateStaticConstGet(node, field, constant, sourceInformation);
- } else {
- // TODO(5346): Try to avoid the need for calling [declaration] before
- // creating an [HStatic].
- HInstruction instruction = new HStatic(
- field,
- TypeMaskFactory.inferredTypeForMember(
- field, globalInferenceResults),
- sourceInformation);
- push(instruction);
- }
- } else {
- HInstruction instruction = new HLazyStatic(
- field,
- TypeMaskFactory.inferredTypeForMember(field, globalInferenceResults),
- sourceInformation);
- push(instruction);
- }
- }
-
- /// Generate a getter invocation of the static or top level [getter].
- void generateStaticGetterGet(ast.Send node, MethodElement getter) {
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildGet(node.selector);
- if (getter.isDeferredLoaderGetter) {
- generateDeferredLoaderGet(node, getter, sourceInformation);
- } else {
- pushInvokeStatic(node, getter, <HInstruction>[],
- sourceInformation: sourceInformation);
- }
- }
-
- /// Generate a dynamic getter invocation.
- void generateDynamicGet(ast.Send node) {
- HInstruction receiver = generateInstanceSendReceiver(node);
- generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node),
- elementInferenceResults.typeOfSend(node), receiver);
- }
-
- /// Generate a closurization of the static or top level [method].
- void generateStaticFunctionGet(ast.Send node, MethodElement method) {
- assert(method.isDeclaration);
- // TODO(5346): Try to avoid the need for calling [declaration] before
- // creating an [HStatic].
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildGet(node.selector);
- push(new HStatic(method, commonMasks.nonNullType, sourceInformation));
- }
-
- /// Read a local variable, function or parameter.
- void buildLocalGet(LocalElement local, SourceInformation sourceInformation) {
- stack.add(
- localsHandler.readLocal(local, sourceInformation: sourceInformation));
- }
-
- void handleLocalGet(ast.Send node, LocalElement local) {
- buildLocalGet(local, sourceInformationBuilder.buildGet(node));
- }
-
- @override
- void visitDynamicPropertyGet(ast.Send node, ast.Node receiver, Name name, _) {
- generateDynamicGet(node);
- }
-
- @override
- void visitIfNotNullDynamicPropertyGet(
- ast.Send node, ast.Node receiver, Name name, _) {
- // exp?.x compiled as:
- // t1 = exp;
- // result = t1 == null ? t1 : t1.x;
- // This is equivalent to t1 == null ? null : t1.x, but in the current form
- // we will be able to later compress it as:
- // t1 || t1.x
- HInstruction expression;
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleConditional(
- () {
- expression = visitAndPop(receiver);
- pushCheckNull(expression);
- },
- () => stack.add(expression),
- () {
- generateInstanceGetterWithCompiledReceiver(
- node,
- elements.getSelector(node),
- elementInferenceResults.typeOfSend(node),
- expression);
- });
- }
-
- @override
- void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
- handleLocalGet(node, variable);
- }
-
- @override
- void visitParameterGet(ast.Send node, ParameterElement parameter, _) {
- handleLocalGet(node, parameter);
- }
-
- @override
- void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
- handleLocalGet(node, function);
- }
-
- @override
- void visitStaticFieldGet(ast.Send node, FieldElement field, _) {
- generateStaticFieldGet(node, field);
- }
-
- @override
- void visitStaticFunctionGet(ast.Send node, MethodElement function, _) {
- generateStaticFunctionGet(node, function);
- }
-
- @override
- void visitStaticGetterGet(ast.Send node, FunctionElement getter, _) {
- generateStaticGetterGet(node, getter);
- }
-
- @override
- void visitThisPropertyGet(ast.Send node, Name name, _) {
- generateDynamicGet(node);
- }
-
- @override
- void visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
- generateStaticFieldGet(node, field);
- }
-
- @override
- void visitTopLevelFunctionGet(ast.Send node, MethodElement function, _) {
- generateStaticFunctionGet(node, function);
- }
-
- @override
- void visitTopLevelGetterGet(ast.Send node, FunctionElement getter, _) {
- generateStaticGetterGet(node, getter);
- }
-
- void generateInstanceSetterWithCompiledReceiver(
- ast.Send send, HInstruction receiver, HInstruction value,
- {Selector selector, TypeMask mask, ast.Node location}) {
- assert(
- send == null || Elements.isInstanceSend(send, elements),
- failedAt(
- send ?? location,
- "Unexpected instance setter"
- "${send != null ? " element: ${elements[send]}" : ""}"));
- if (selector == null) {
- assert(send != null);
- selector = elements.getSelector(send);
- mask ??= elementInferenceResults.typeOfSend(send);
- }
- if (location == null) {
- assert(send != null);
- location = send;
- }
- assert(selector.isSetter);
- pushInvokeDynamic(location, selector, mask, [receiver, value],
- sourceInformation: sourceInformationBuilder.buildAssignment(location));
- pop();
- stack.add(value);
- }
-
- void generateNoSuchSetter(
- ast.Node location, Element element, HInstruction value) {
- List<HInstruction> arguments =
- value == null ? const <HInstruction>[] : <HInstruction>[value];
- // An erroneous element indicates an unresolved static setter.
- generateThrowNoSuchMethod(
- location, noSuchMethodTargetSymbolString(element, 'set'),
- argumentValues: arguments);
- }
-
- void generateNonInstanceSetter(
- ast.SendSet send, Element element, HInstruction value,
- {ast.Node location}) {
- if (location == null) {
- assert(send != null);
- location = send;
- }
- assert(send == null || !Elements.isInstanceSend(send, elements),
- failedAt(location, "Unexpected non instance setter: $element."));
- if (Elements.isStaticOrTopLevelField(element)) {
- if (element.isSetter) {
- pushInvokeStatic(location, element, <HInstruction>[value]);
- pop();
- } else {
- FieldElement field = element;
- value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
- value, field.type);
- addWithPosition(
- new HStaticStore(abstractValueDomain, field, value), location);
- }
- stack.add(value);
- } else if (Elements.isError(element)) {
- generateNoSuchSetter(location, element, send == null ? null : value);
- } else if (Elements.isMalformed(element)) {
- // TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(closedWorld));
- } else {
- stack.add(value);
- LocalElement local = element;
- // If the value does not already have a name, give it here.
- if (value.sourceElement == null) {
- value.sourceElement = local;
- }
- HInstruction checkedOrTrusted = typeBuilder
- .potentiallyCheckOrTrustTypeOfAssignment(value, local.type);
- if (!identical(checkedOrTrusted, value)) {
- pop();
- stack.add(checkedOrTrusted);
- }
-
- localsHandler.updateLocal(local, checkedOrTrusted,
- sourceInformation:
- sourceInformationBuilder.buildAssignment(location));
- }
- }
-
- HInstruction invokeInterceptor(HInstruction receiver) {
- HInterceptor interceptor =
- new HInterceptor(receiver, commonMasks.nonNullType);
- add(interceptor);
- return interceptor;
- }
-
- @override
- void visitAs(ast.Send node, ast.Node expression, ResolutionDartType type, _) {
- HInstruction expressionInstruction = visitAndPop(expression);
- if (type.isMalformed) {
- if (type is MalformedType) {
- ErroneousElement element = type.element;
- generateTypeError(node, element.message);
- } else {
- assert(type is MethodTypeVariableType);
- stack.add(expressionInstruction);
- }
- } else {
- HInstruction converted = typeBuilder.buildTypeConversion(
- expressionInstruction,
- localsHandler.substInContext(type),
- HTypeConversion.CAST_TYPE_CHECK,
- sourceInformation: sourceInformationBuilder.buildAs(node));
- if (converted != expressionInstruction) add(converted);
- stack.add(converted);
- }
- }
-
- @override
- void visitIs(ast.Send node, ast.Node expression, ResolutionDartType type, _) {
- HInstruction expressionInstruction = visitAndPop(expression);
- push(buildIsNode(node, type, expressionInstruction,
- sourceInformationBuilder.buildIs(node)));
- }
-
- @override
- void visitIsNot(
- ast.Send node, ast.Node expression, ResolutionDartType type, _) {
- HInstruction expressionInstruction = visitAndPop(expression);
- HInstruction instruction = buildIsNode(node, type, expressionInstruction,
- sourceInformationBuilder.buildIs(node));
- add(instruction);
- push(new HNot(instruction, commonMasks.boolType));
- }
-
- HInstruction buildIsNode(ast.Node node, ResolutionDartType type,
- HInstruction expression, SourceInformation sourceInformation) {
- type = localsHandler.substInContext(type).unaliased;
- if (type.isMalformed) {
- String message;
- if (type is MethodTypeVariableType) {
- message = "Method type variables are not reified, "
- "so they cannot be tested with an `is` expression.";
- } else {
- assert(type is MalformedType);
- ErroneousElement element = type.element;
- message = element.message;
- }
- generateTypeError(node, message);
- HInstruction call = pop();
- return new HIs.compound(
- type, expression, call, commonMasks.boolType, sourceInformation);
- } else if (type.isFunctionType) {
- HInstruction representation =
- typeBuilder.analyzeTypeArgument(type, sourceElement);
- List<HInstruction> inputs = <HInstruction>[
- expression,
- representation,
- ];
- pushInvokeStatic(node, commonElements.functionTypeTest, inputs,
- typeMask: commonMasks.boolType, sourceInformation: sourceInformation);
- HInstruction call = pop();
- return new HIs.compound(
- type, expression, call, commonMasks.boolType, sourceInformation);
- } else if (type.isTypeVariable) {
- ResolutionTypeVariableType typeVariable = type;
- HInstruction runtimeType =
- typeBuilder.addTypeVariableReference(typeVariable, sourceElement);
- MethodElement helper = commonElements.checkSubtypeOfRuntimeType;
- List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
- pushInvokeStatic(null, helper, inputs,
- typeMask: commonMasks.boolType, sourceInformation: sourceInformation);
- HInstruction call = pop();
- return new HIs.variable(
- type, expression, call, commonMasks.boolType, sourceInformation);
- } else if (RuntimeTypesSubstitutions.hasTypeArguments(type)) {
- ClassElement element = type.element;
- MethodElement helper = commonElements.checkSubtype;
- HInstruction representations =
- typeBuilder.buildTypeArgumentRepresentations(type, sourceElement);
- add(representations);
- js.Name operator = namer.operatorIs(element);
- HInstruction isFieldName = addConstantStringFromName(operator);
- HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element)
- ? addConstantStringFromName(namer.substitutionName(element))
- : graph.addConstantNull(closedWorld);
- List<HInstruction> inputs = <HInstruction>[
- expression,
- isFieldName,
- representations,
- asFieldName
- ];
- pushInvokeStatic(node, helper, inputs,
- typeMask: commonMasks.boolType, sourceInformation: sourceInformation);
- HInstruction call = pop();
- return new HIs.compound(
- type, expression, call, commonMasks.boolType, sourceInformation);
- } else {
- if (backend.hasDirectCheckFor(closedWorld.commonElements, type)) {
- return new HIs.direct(
- type, expression, commonMasks.boolType, sourceInformation);
- }
- // The interceptor is not always needed. It is removed by optimization
- // when the receiver type or tested type permit.
- return new HIs.raw(type, expression, invokeInterceptor(expression),
- commonMasks.boolType, sourceInformation);
- }
- }
-
- void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) {
- CallStructure callStructure = elements.getSelector(node).callStructure;
- if (callStructure.namedArgumentCount == 0) {
- addGenericSendArgumentsToList(node.arguments, list);
- } else {
- // Visit positional arguments and add them to the list.
- Link<ast.Node> arguments = node.arguments;
- int positionalArgumentCount = callStructure.positionalArgumentCount;
- for (int i = 0;
- i < positionalArgumentCount;
- arguments = arguments.tail, i++) {
- visit(arguments.head);
- list.add(pop());
- }
-
- // Visit named arguments and add them into a temporary map.
- Map<String, HInstruction> instructions = new Map<String, HInstruction>();
- List<String> namedArguments = callStructure.namedArguments;
- int nameIndex = 0;
- for (; !arguments.isEmpty; arguments = arguments.tail) {
- visit(arguments.head);
- instructions[namedArguments[nameIndex++]] = pop();
- }
-
- // Iterate through the named arguments to add them to the list
- // of instructions, in an order that can be shared with
- // selectors with the same named arguments.
- List<String> orderedNames = callStructure.getOrderedNamedArguments();
- for (String name in orderedNames) {
- list.add(instructions[name]);
- }
- }
- }
-
- /**
- * Returns a list with the evaluated [arguments] in the normalized order.
- *
- * Precondition: `this.applies(element, world)`.
- * Invariant: [element] must be an implementation element.
- */
- List<HInstruction> makeStaticArgumentList(CallStructure callStructure,
- Link<ast.Node> arguments, MethodElement element) {
- assert(element.isDeclaration, failedAt(element));
-
- HInstruction compileArgument(ast.Node argument) {
- visit(argument);
- return pop();
- }
-
- return Elements.makeArgumentsList<HInstruction>(
- callStructure,
- arguments,
- element.implementation,
- compileArgument,
- nativeData.isJsInteropMember(element)
- ? handleConstantForOptionalParameterJsInterop
- : handleConstantForOptionalParameter);
- }
-
- void addGenericSendArgumentsToList(
- Link<ast.Node> link, List<HInstruction> list) {
- for (; !link.isEmpty; link = link.tail) {
- visit(link.head);
- list.add(pop());
- }
- }
-
- /// Generate a dynamic method, getter or setter invocation.
- void generateDynamicSend(ast.Send node) {
- HInstruction receiver = generateInstanceSendReceiver(node);
- _generateDynamicSend(node, receiver);
- }
-
- void _generateDynamicSend(ast.Send node, HInstruction receiver) {
- Selector selector = elements.getSelector(node);
- TypeMask mask = elementInferenceResults.typeOfSend(node);
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildCall(node, node.selector);
-
- List<HInstruction> inputs = <HInstruction>[];
- inputs.add(receiver);
- addDynamicSendArgumentsToList(node, inputs);
-
- pushInvokeDynamic(node, selector, mask, inputs,
- sourceInformation: sourceInformation);
- if (selector.isSetter || selector.isIndexSet) {
- pop();
- stack.add(inputs.last);
- }
- }
-
- @override
- visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
- ast.NodeList arguments, Selector selector, _) {
- generateDynamicSend(node);
- }
-
- @override
- visitIfNotNullDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
- ast.NodeList arguments, Selector selector, _) {
- /// Desugar `exp?.m()` to `(t1 = exp) == null ? t1 : t1.m()`
- HInstruction receiver;
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleConditional(() {
- receiver = generateInstanceSendReceiver(node);
- pushCheckNull(receiver);
- }, () => stack.add(receiver), () => _generateDynamicSend(node, receiver));
- }
-
- @override
- visitThisPropertyInvoke(
- ast.Send node, ast.NodeList arguments, Selector selector, _) {
- generateDynamicSend(node);
- }
-
- @override
- visitExpressionInvoke(ast.Send node, ast.Node expression,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateCallInvoke(node, visitAndPop(expression),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- visitThisInvoke(
- ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
- generateCallInvoke(
- node,
- localsHandler.readThis(
- sourceInformation: sourceInformationBuilder.buildGet(node)),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- visitParameterInvoke(ast.Send node, ParameterElement parameter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateCallInvoke(node, localsHandler.readLocal(parameter),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- visitLocalVariableInvoke(ast.Send node, LocalVariableElement variable,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateCallInvoke(node, localsHandler.readLocal(variable),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- visitLocalFunctionInvoke(ast.Send node, LocalFunctionElement function,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateCallInvoke(node, localsHandler.readLocal(function),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- visitLocalFunctionIncompatibleInvoke(
- ast.Send node,
- LocalFunctionElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- generateCallInvoke(node, localsHandler.readLocal(function),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- void handleForeignJs(ast.Send node) {
- Link<ast.Node> link = node.arguments;
- // Don't visit the first argument, which is the type, and the second
- // argument, which is the foreign code.
- if (link.isEmpty || link.tail.isEmpty) {
- // We should not get here because the call should be compiled to NSM.
- reporter.internalError(
- node.argumentsNode, 'At least two arguments expected.');
- }
- native.NativeBehavior nativeBehavior = elements.getNativeData(node);
- assert(
- nativeBehavior != null, failedAt(node, "No NativeBehavior for $node"));
-
- List<HInstruction> inputs = <HInstruction>[];
- addGenericSendArgumentsToList(link.tail.tail, inputs);
-
- if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) {
- reporter.reportErrorMessage(node, MessageKind.GENERIC, {
- 'text': 'Mismatch between number of placeholders'
- ' and number of arguments.'
- });
- // Result expected on stack.
- stack.add(graph.addConstantNull(closedWorld));
- return;
- }
-
- if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) {
- reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
- }
-
- TypeMask ssaType =
- TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
-
- DartType typeArgument;
- ast.NodeList typeArgumentsNode = node.typeArgumentsNode;
- if (typeArgumentsNode != null) {
- if (typeArgumentsNode.slowLength() == 1) {
- ast.Node typeNode = typeArgumentsNode.single;
- typeArgument = elements.getType(typeNode);
- } else {
- reporter.reportErrorMessage(typeArgumentsNode, MessageKind.GENERIC,
- {'text': 'JS takes one type argument'});
- }
- }
-
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildCall(node, node.argumentsNode);
- push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs,
- isStatement: !nativeBehavior.codeTemplate.isExpression,
- effects: nativeBehavior.sideEffects,
- nativeBehavior: nativeBehavior)
- ..sourceInformation = sourceInformation);
-
- HInstruction code = stack.last;
- TypeMask trustedMask = typeBuilder.trustTypeMask(typeArgument);
-
- if (trustedMask != null) {
- // We only allow the type argument to narrow `dynamic`, which probably
- // comes from an unspecified return type in the NativeBehavior.
- if (abstractValueDomain.containsAll(code.instructionType)) {
- // Overwrite the type with the narrower type.
- code.instructionType = trustedMask;
- } else if (trustedMask.containsMask(code.instructionType, closedWorld)) {
- // It is acceptable for the type parameter to be broader than the
- // specified type.
- } else {
- reporter.reportErrorMessage(typeArgumentsNode, MessageKind.GENERIC, {
- 'text': 'Type argument too narrow for specified behavior type '
- '(${trustedMask} does not allow '
- 'all values in ${code.instructionType})'
- });
- }
- }
- }
-
- void handleJsStringConcat(ast.Send node) {
- List<HInstruction> inputs = <HInstruction>[];
- addGenericSendArgumentsToList(node.arguments, inputs);
- if (inputs.length != 2) {
- reporter.internalError(node.argumentsNode, 'Two arguments expected.');
- }
- push(new HStringConcat(inputs[0], inputs[1], commonMasks.stringType));
- }
-
- void handleForeignJsCurrentIsolateContext(ast.Send node) {
- if (!node.arguments.isEmpty) {
- reporter.internalError(
- node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.');
- }
-
- String name = namer.staticStateHolder;
- push(new HForeignCode(
- js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
- nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
- }
-
- void handleForeignJsGetFlag(ast.Send node) {
- List<ast.Node> arguments = node.arguments.toList();
- ast.Node argument;
- switch (arguments.length) {
- case 0:
- reporter.reportErrorMessage(node, MessageKind.GENERIC,
- {'text': 'Error: Expected one argument to JS_GET_FLAG.'});
- return;
- case 1:
- argument = arguments[0];
- break;
- default:
- for (int i = 1; i < arguments.length; i++) {
- reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC,
- {'text': 'Error: Extra argument to JS_GET_FLAG.'});
- }
- return;
- }
- ast.LiteralString string = argument.asLiteralString();
- if (string == null) {
- reporter.reportErrorMessage(argument, MessageKind.GENERIC,
- {'text': 'Error: Expected a literal string.'});
- }
- String name = string.dartString.slowToString();
- bool value = getFlagValue(name);
- if (value == null) {
- reporter.reportErrorMessage(node, MessageKind.GENERIC,
- {'text': 'Error: Unknown internal flag "$name".'});
- } else {
- stack.add(graph.addConstantBool(value, closedWorld));
- }
- }
-
- void handleForeignJsGetName(ast.Send node) {
- List<ast.Node> arguments = node.arguments.toList();
- ast.Node argument;
- switch (arguments.length) {
- case 0:
- reporter.reportErrorMessage(node, MessageKind.GENERIC,
- {'text': 'Error: Expected one argument to JS_GET_NAME.'});
- return;
- case 1:
- argument = arguments[0];
- break;
- default:
- for (int i = 1; i < arguments.length; i++) {
- reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC,
- {'text': 'Error: Extra argument to JS_GET_NAME.'});
- }
- return;
- }
- Element element = elements[argument];
- if (element == null ||
- element is! EnumConstantElement ||
- element.enclosingClass != commonElements.jsGetNameEnum) {
- reporter.reportErrorMessage(argument, MessageKind.GENERIC,
- {'text': 'Error: Expected a JsGetName enum value.'});
- }
- EnumConstantElement enumConstant = element;
- int index = enumConstant.index;
- stack.add(addConstantStringFromName(
- namer.getNameForJsGetName(argument, JsGetName.values[index])));
- }
-
- void handleForeignJsBuiltin(ast.Send node) {
- List<ast.Node> arguments = node.arguments.toList();
- ast.Node argument;
- if (arguments.length < 2) {
- reporter.reportErrorMessage(node, MessageKind.GENERIC,
- {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'});
- }
-
- Element builtinElement = elements[arguments[1]];
- if (builtinElement == null ||
- (builtinElement is! EnumConstantElement) ||
- builtinElement.enclosingClass != commonElements.jsBuiltinEnum) {
- reporter.reportErrorMessage(argument, MessageKind.GENERIC,
- {'text': 'Error: Expected a JsBuiltin enum value.'});
- }
- EnumConstantElement enumConstant = builtinElement;
- int index = enumConstant.index;
-
- js.Template template = emitter.builtinTemplateFor(JsBuiltin.values[index]);
-
- List<HInstruction> compiledArguments = <HInstruction>[];
- for (int i = 2; i < arguments.length; i++) {
- visit(arguments[i]);
- compiledArguments.add(pop());
- }
-
- native.NativeBehavior nativeBehavior = elements.getNativeData(node);
- assert(
- nativeBehavior != null, failedAt(node, "No NativeBehavior for $node"));
-
- TypeMask ssaType =
- TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
-
- push(new HForeignCode(template, ssaType, compiledArguments,
- nativeBehavior: nativeBehavior));
- }
-
- void handleForeignJsEmbeddedGlobal(ast.Send node) {
- List<ast.Node> arguments = node.arguments.toList();
- ast.Node globalNameNode;
- switch (arguments.length) {
- case 0:
- case 1:
- reporter.reportErrorMessage(node, MessageKind.GENERIC,
- {'text': 'Error: Expected two arguments to JS_EMBEDDED_GLOBAL.'});
- return;
- case 2:
- // The type has been extracted earlier. We are only interested in the
- // name in this function.
- globalNameNode = arguments[1];
- break;
- default:
- for (int i = 2; i < arguments.length; i++) {
- reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC,
- {'text': 'Error: Extra argument to JS_EMBEDDED_GLOBAL.'});
- }
- return;
- }
- visit(globalNameNode);
- HInstruction globalNameHNode = pop();
- if (!globalNameHNode.isConstantString()) {
- reporter.reportErrorMessage(arguments[1], MessageKind.GENERIC, {
- 'text': 'Error: Expected String as second argument '
- 'to JS_EMBEDDED_GLOBAL.'
- });
- return;
- }
- HConstant hConstant = globalNameHNode;
- StringConstantValue constant = hConstant.constant;
- String globalName = constant.stringValue;
- js.Template expr = js.js.expressionTemplateYielding(
- emitter.generateEmbeddedGlobalAccess(globalName));
- native.NativeBehavior nativeBehavior = elements.getNativeData(node);
- assert(
- nativeBehavior != null, failedAt(node, "No NativeBehavior for $node"));
- TypeMask ssaType =
- TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
- push(new HForeignCode(expr, ssaType, const [],
- nativeBehavior: nativeBehavior));
- }
-
- void handleJsInterceptorConstant(ast.Send node) {
- // Single argument must be a TypeConstant which is converted into a
- // InterceptorConstant.
- if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
- ast.Node argument = node.arguments.head;
- visit(argument);
- HInstruction argumentInstruction = pop();
- if (argumentInstruction is HConstant) {
- ConstantValue argumentConstant = argumentInstruction.constant;
- if (argumentConstant is TypeConstantValue &&
- argumentConstant.representedType is ResolutionInterfaceType) {
- ResolutionInterfaceType type = argumentConstant.representedType;
- ConstantValue constant = new InterceptorConstantValue(type.element);
- HInstruction instruction = graph.addConstant(constant, closedWorld);
- stack.add(instruction);
- return;
- }
- }
- }
- reporter.reportErrorMessage(
- node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
- stack.add(graph.addConstantNull(closedWorld));
- }
-
- FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) {
- if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
- reporter.internalError(
- node.argumentsNode, '"$name" requires exactly one argument.');
- }
- ast.Node closure = node.arguments.head;
- Element element = elements[closure];
- if (!Elements.isStaticOrTopLevelFunction(element)) {
- reporter.internalError(
- closure, '"$name" requires a static or top-level method.');
- }
- MethodElement function = element;
- // TODO(johnniwinther): Try to eliminate the need to distinguish declaration
- // and implementation signatures. Currently it is need because the
- // signatures have different elements for parameters.
- FunctionElement implementation = function.implementation;
- FunctionSignature params = implementation.functionSignature;
- if (params.optionalParameterCount != 0) {
- reporter.internalError(
- closure, '"$name" does not handle closure with optional parameters.');
- }
-
- push(new HForeignCode(
- js.js
- .expressionTemplateYielding(emitter.staticFunctionAccess(function)),
- commonMasks.dynamicType,
- <HInstruction>[],
- nativeBehavior: native.NativeBehavior.PURE,
- foreignFunction: function));
- return params;
- }
-
- void handleForeignDartClosureToJs(ast.Send node, String name) {
- // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take
- // care to wrap the closure in another closure that saves the current
- // isolate.
- handleForeignRawFunctionRef(node, name);
- }
-
- void handleForeignJsSetStaticState(ast.Send node) {
- if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
- reporter.internalError(
- node.argumentsNode, 'Exactly one argument required.');
- }
- visit(node.arguments.head);
- String isolateName = namer.staticStateHolder;
- SideEffects sideEffects = new SideEffects.empty();
- sideEffects.setAllSideEffects();
- push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
- commonMasks.dynamicType, <HInstruction>[pop()],
- nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
- effects: sideEffects));
- }
-
- void handleForeignJsGetStaticState(ast.Send node) {
- if (!node.arguments.isEmpty) {
- reporter.internalError(node.argumentsNode, 'Too many arguments.');
- }
- push(new HForeignCode(js.js.parseForeignJS(namer.staticStateHolder),
- commonMasks.dynamicType, <HInstruction>[],
- nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
- }
-
- void handleForeignSend(ast.Send node, FunctionElement element) {
- String name = element.name;
- if (name == JavaScriptBackend.JS) {
- handleForeignJs(node);
- } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
- handleForeignJsCurrentIsolateContext(node);
- } else if (name == 'DART_CLOSURE_TO_JS') {
- handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
- } else if (name == 'RAW_DART_FUNCTION_REF') {
- handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
- } else if (name == 'JS_SET_STATIC_STATE') {
- handleForeignJsSetStaticState(node);
- } else if (name == 'JS_GET_STATIC_STATE') {
- handleForeignJsGetStaticState(node);
- } else if (name == 'JS_GET_NAME') {
- handleForeignJsGetName(node);
- } else if (name == JavaScriptBackend.JS_EMBEDDED_GLOBAL) {
- handleForeignJsEmbeddedGlobal(node);
- } else if (name == JavaScriptBackend.JS_BUILTIN) {
- handleForeignJsBuiltin(node);
- } else if (name == 'JS_GET_FLAG') {
- handleForeignJsGetFlag(node);
- } else if (name == 'JS_EFFECT') {
- stack.add(graph.addConstantNull(closedWorld));
- } else if (name == JavaScriptBackend.JS_INTERCEPTOR_CONSTANT) {
- handleJsInterceptorConstant(node);
- } else if (name == 'JS_STRING_CONCAT') {
- handleJsStringConcat(node);
- } else {
- reporter.internalError(node, "Unknown foreign: ${element}");
- }
- }
-
- generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader,
- SourceInformation sourceInformation) {
- // Until now we only handle these as getters.
- if (!deferredLoader.isDeferredLoaderGetter) {
- failedAt(node);
- }
- FunctionEntity loadFunction = commonElements.loadLibraryWrapper;
- PrefixElement prefixElement = deferredLoader.enclosingElement;
- String loadId =
- deferredLoadTask.getImportDeferName(node, prefixElement.deferredImport);
- var inputs = [graph.addConstantString(loadId, closedWorld)];
- push(new HInvokeStatic(
- loadFunction, inputs, commonMasks.nonNullType, const <DartType>[],
- targetCanThrow: false)
- ..sourceInformation = sourceInformation);
- }
-
- generateSuperNoSuchMethodSend(
- ast.Send node, Selector selector, List<HInstruction> arguments) {
- String name = selector.name;
-
- ClassElement cls = currentNonClosureClass;
- MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
- if (!Selectors.noSuchMethod_.signatureApplies(element)) {
- ClassElement objectClass = commonElements.objectClass;
- element = objectClass.lookupMember(Identifiers.noSuchMethod_);
- }
- if (backendUsage.isInvokeOnUsed && !element.enclosingClass.isObject) {
- // Register the call as dynamic if [noSuchMethod] on the super
- // class is _not_ the default implementation from [Object], in
- // case the [noSuchMethod] implementation calls
- // [JSInvocationMirror._invokeOn].
- // TODO(johnniwinther): Register this more precisely.
- registry
- ?.registerDynamicUse(new ConstrainedDynamicUse(selector, null, null));
- }
- String publicName = name;
- if (selector.isSetter) publicName += '=';
-
- ConstantValue nameConstant = constantSystem.createString(publicName);
-
- js.Name internalName = namer.invocationName(selector);
-
- MethodElement createInvocationMirror =
- commonElements.createInvocationMirror;
- var argumentsInstruction = buildLiteralList(arguments);
- add(argumentsInstruction);
-
- var argumentNames = new List<HInstruction>();
- for (String argumentName in selector.namedArguments) {
- ConstantValue argumentNameConstant =
- constantSystem.createString(argumentName);
- argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld));
- }
- var argumentNamesInstruction = buildLiteralList(argumentNames);
- add(argumentNamesInstruction);
-
- ConstantValue kindConstant =
- constantSystem.createInt(selector.invocationMirrorKind);
-
- pushInvokeStatic(
- null,
- createInvocationMirror,
- [
- graph.addConstant(nameConstant, closedWorld),
- graph.addConstantStringFromName(internalName, closedWorld),
- graph.addConstant(kindConstant, closedWorld),
- argumentsInstruction,
- argumentNamesInstruction,
- graph.addConstantInt(0, closedWorld), // type argument count.
- ],
- typeMask: commonMasks.dynamicType);
-
- var inputs = <HInstruction>[pop()];
- push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs,
- sourceInformationBuilder.buildGeneric(node)));
- }
-
- /// Generate a call to a super method or constructor.
- void generateSuperInvoke(ast.Send node, MethodElement method,
- SourceInformation sourceInformation) {
- // TODO(5347): Try to avoid the need for calling [implementation] before
- // calling [makeStaticArgumentList].
- Selector selector = elements.getSelector(node);
- MethodElement implementation = method.implementation;
- assert(selector.applies(implementation),
- failedAt(node, "$selector does not apply to ${implementation}"));
- List<HInstruction> inputs =
- makeStaticArgumentList(selector.callStructure, node.arguments, method);
- push(buildInvokeSuper(selector, method, inputs, sourceInformation));
- }
-
- /// Access the value from the super [element].
- void handleSuperGet(ast.Send node, Element element) {
- Selector selector = elements.getSelector(node);
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildGet(node.selector);
- push(buildInvokeSuper(
- selector, element, const <HInstruction>[], sourceInformation));
- }
-
- /// Invoke .call on the value retrieved from the super [element].
- void handleSuperCallInvoke(ast.Send node, Element element) {
- Selector selector = elements.getSelector(node);
- HInstruction target = buildInvokeSuper(
- selector,
- element,
- const <HInstruction>[],
- sourceInformationBuilder.buildGet(node.selector));
- add(target);
- generateCallInvoke(
- node,
- target,
- sourceInformationBuilder.buildCall(
- node.argumentsNode, node.argumentsNode));
- }
-
- /// Invoke super [method].
- void handleSuperMethodInvoke(ast.Send node, MethodElement method) {
- generateSuperInvoke(node, method,
- sourceInformationBuilder.buildCall(node.selector, node.selector));
- }
-
- /// Access an unresolved super property.
- void handleUnresolvedSuperInvoke(ast.Send node) {
- Selector selector = elements.getSelector(node);
- List<HInstruction> arguments = <HInstruction>[];
- if (!node.isPropertyAccess) {
- addGenericSendArgumentsToList(node.arguments, arguments);
- }
- generateSuperNoSuchMethodSend(node, selector, arguments);
- }
-
- @override
- void visitUnresolvedSuperIndex(
- ast.Send node, Element element, ast.Node index, _) {
- handleUnresolvedSuperInvoke(node);
- }
-
- @override
- void visitUnresolvedSuperUnary(
- ast.Send node, UnaryOperator operator, Element element, _) {
- handleUnresolvedSuperInvoke(node);
- }
-
- @override
- void visitUnresolvedSuperBinary(ast.Send node, Element element,
- BinaryOperator operator, ast.Node argument, _) {
- handleUnresolvedSuperInvoke(node);
- }
-
- @override
- void visitUnresolvedSuperGet(ast.Send node, Element element, _) {
- handleUnresolvedSuperInvoke(node);
- }
-
- @override
- void visitUnresolvedSuperSet(
- ast.Send node, Element element, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
- handleUnresolvedSuperInvoke(node);
- }
-
- @override
- void visitUnresolvedSuperInvoke(
- ast.Send node, Element element, ast.Node argument, Selector selector, _) {
- handleUnresolvedSuperInvoke(node);
- }
-
- @override
- void visitSuperFieldGet(ast.Send node, FieldElement field, _) {
- handleSuperGet(node, field);
- }
-
- @override
- void visitSuperGetterGet(ast.Send node, MethodElement method, _) {
- handleSuperGet(node, method);
- }
-
- @override
- void visitSuperMethodGet(ast.Send node, MethodElement method, _) {
- handleSuperGet(node, method);
- }
-
- @override
- void visitSuperFieldInvoke(ast.Send node, FieldElement field,
- ast.NodeList arguments, CallStructure callStructure, _) {
- handleSuperCallInvoke(node, field);
- }
-
- @override
- void visitSuperGetterInvoke(ast.Send node, MethodElement getter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- handleSuperCallInvoke(node, getter);
- }
-
- @override
- void visitSuperMethodInvoke(ast.Send node, MethodElement method,
- ast.NodeList arguments, CallStructure callStructure, _) {
- handleSuperMethodInvoke(node, method);
- }
-
- @override
- void visitSuperIndex(ast.Send node, MethodElement method, ast.Node index, _) {
- handleSuperMethodInvoke(node, method);
- }
-
- @override
- void visitSuperEquals(
- ast.Send node, MethodElement method, ast.Node argument, _) {
- handleSuperMethodInvoke(node, method);
- }
-
- @override
- void visitSuperBinary(ast.Send node, MethodElement method,
- BinaryOperator operator, ast.Node argument, _) {
- handleSuperMethodInvoke(node, method);
- }
-
- @override
- void visitSuperNotEquals(
- ast.Send node, MethodElement method, ast.Node argument, _) {
- handleSuperMethodInvoke(node, method);
- pushWithPosition(
- new HNot(popBoolified(), commonMasks.boolType), node.selector);
- }
-
- @override
- void visitSuperUnary(
- ast.Send node, UnaryOperator operator, MethodElement method, _) {
- handleSuperMethodInvoke(node, method);
- }
-
- @override
- void visitSuperMethodIncompatibleInvoke(ast.Send node, MethodElement method,
- ast.NodeList arguments, CallStructure callStructure, _) {
- handleInvalidSuperInvoke(node, arguments);
- }
-
- @override
- void visitSuperSetterInvoke(ast.Send node, SetterElement setter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- handleInvalidSuperInvoke(node, arguments);
- }
-
- void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) {
- Selector selector = elements.getSelector(node);
- List<HInstruction> inputs = <HInstruction>[];
- addGenericSendArgumentsToList(arguments.nodes, inputs);
- generateSuperNoSuchMethodSend(node, selector, inputs);
- }
-
- bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
- if (closedWorld.isUsedAsMixin(cls)) return true;
-
- return closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) {
- return !rtiSubstitutions.isTrivialSubstitution(subclass, cls);
- });
- }
-
- HInstruction handleListConstructor(ResolutionInterfaceType type,
- HInstruction newObject, SourceInformation sourceInformation) {
- if (!rtiNeed.classNeedsTypeArguments(type.element) || type.treatAsRaw) {
- return newObject;
- }
- List<HInstruction> inputs = <HInstruction>[];
- type = localsHandler.substInContext(type);
- type.typeArguments.forEach((ResolutionDartType argument) {
- inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
- sourceInformation: sourceInformation));
- });
- // TODO(15489): Register at codegen.
- registry?.registerInstantiation(type);
- return callSetRuntimeTypeInfoWithTypeArguments(
- type, inputs, newObject, sourceInformation);
- }
-
- HInstruction callSetRuntimeTypeInfo(HInstruction typeInfo,
- HInstruction newObject, SourceInformation sourceInformation) {
- // Set the runtime type information on the object.
- MethodElement typeInfoSetterElement = commonElements.setRuntimeTypeInfo;
- pushInvokeStatic(
- null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo],
- typeMask: commonMasks.dynamicType,
- sourceInformation: sourceInformation);
-
- // The new object will now be referenced through the
- // `setRuntimeTypeInfo` call. We therefore set the type of that
- // instruction to be of the object's type.
- assert(
- stack.last is HInvokeStatic || stack.last == newObject,
- failedAt(
- CURRENT_ELEMENT_SPANNABLE,
- "Unexpected `stack.last`: Found ${stack.last}, "
- "expected ${newObject} or an HInvokeStatic. "
- "State: typeInfo=$typeInfo, stack=$stack."));
- stack.last.instructionType = newObject.instructionType;
- return pop();
- }
-
- void handleNewSend(ast.NewExpression node) {
- ast.Send send = node.send;
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildNew(send);
-
- generateIsDeferredLoadedCheckOfSend(send);
-
- ConstructorElement constructor = elements[send];
- bool isFixedList = false;
- bool isFixedListConstructorCall = Elements.isFixedListConstructorCall(
- constructor, send, closedWorld.commonElements);
- bool isGrowableListConstructorCall = Elements.isGrowableListConstructorCall(
- constructor, send, closedWorld.commonElements);
-
- TypeMask computeType(element) {
- ConstructorElement originalElement = elements[send];
- if (isFixedListConstructorCall ||
- Elements.isFilledListConstructorCall(
- originalElement, send, closedWorld.commonElements)) {
- isFixedList = true;
- TypeMask inferred = _inferredTypeOfNewList(send);
- return inferred.containsAll(closedWorld)
- ? commonMasks.fixedArrayType
- : inferred;
- } else if (isGrowableListConstructorCall) {
- TypeMask inferred = _inferredTypeOfNewList(send);
- return inferred.containsAll(closedWorld)
- ? commonMasks.growableListType
- : inferred;
- } else if (Elements.isConstructorOfTypedArraySubclass(
- originalElement, closedWorld)) {
- isFixedList = true;
- TypeMask inferred = _inferredTypeOfNewList(send);
- ClassElement cls = element.enclosingClass;
- assert(nativeData.isNativeClass(cls));
- return inferred.containsAll(closedWorld)
- ? new TypeMask.nonNullExact(cls, closedWorld)
- : inferred;
- } else if (element.isGenerativeConstructor) {
- ClassElement cls = element.enclosingClass;
- if (cls.isAbstract) {
- // An error will be thrown.
- return new TypeMask.nonNullEmpty();
- } else {
- return new TypeMask.nonNullExact(cls, closedWorld);
- }
- } else {
- return TypeMaskFactory.inferredReturnTypeForElement(
- originalElement, globalInferenceResults);
- }
- }
-
- CallStructure callStructure = elements.getSelector(send).callStructure;
- ConstructorElement constructorDeclaration = constructor;
- ConstructorElement constructorImplementation = constructor.implementation;
- constructor = constructorImplementation.effectiveTarget;
-
- final bool isSymbolConstructor =
- closedWorld.commonElements.isSymbolConstructor(constructorDeclaration);
- final bool isJSArrayTypedConstructor = constructorDeclaration ==
- closedWorld.commonElements.jsArrayTypedConstructor;
-
- if (isSymbolConstructor) {
- constructor = commonElements.symbolValidatedConstructor;
- assert(constructor != null,
- failedAt(send, 'Constructor Symbol.validated is missing'));
- callStructure =
- commonElements.symbolValidatedConstructorSelector.callStructure;
- assert(callStructure != null,
- failedAt(send, 'Constructor Symbol.validated is missing'));
- }
-
- bool isRedirected = constructorDeclaration.isRedirectingFactory;
- if (!constructorDeclaration.isCyclicRedirection) {
- // Insert a check for every deferred redirection on the path to the
- // final target.
- ConstructorElement target = constructorDeclaration;
- while (target.isRedirectingFactory) {
- if (constructorDeclaration.redirectionDeferredPrefix != null) {
- generateIsDeferredLoadedCheckIfNeeded(
- target.redirectionDeferredPrefix.deferredImport, node);
- }
- target = target.immediateRedirectionTarget;
- }
- }
- ResolutionInterfaceType type = elements.getType(node);
- ResolutionDartType expectedType =
- constructorDeclaration.computeEffectiveTargetType(type);
- expectedType = localsHandler.substInContext(expectedType);
-
- if (compiler.elementHasCompileTimeError(constructor) ||
- compiler.elementHasCompileTimeError(constructor.enclosingClass)) {
- // TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(closedWorld));
- return;
- }
-
- if (checkTypeVariableBounds(node, type)) return;
-
- // Abstract class instantiation error takes precedence over argument
- // mismatch.
- ClassElement cls = constructor.enclosingClass;
- if (cls.isAbstract && constructor.isGenerativeConstructor) {
- // However, we need to ensure that all arguments are evaluated before we
- // throw the ACIE exception.
- send.arguments.forEach((arg) {
- visit(arg);
- pop();
- });
- generateAbstractClassInstantiationError(send, cls.name);
- return;
- }
-
- // TODO(5347): Try to avoid the need for calling [implementation] before
- // calling [makeStaticArgumentList].
- constructorImplementation = constructor.implementation;
- if (constructorImplementation.isMalformed ||
- !callStructure
- .signatureApplies(constructorImplementation.parameterStructure)) {
- generateWrongArgumentCountError(send, constructor, send.arguments);
- return;
- }
-
- List<HInstruction> inputs = <HInstruction>[];
- if (constructor.isGenerativeConstructor &&
- nativeData.isNativeOrExtendsNative(constructor.enclosingClass) &&
- !nativeData.isJsInteropMember(constructor)) {
- // Native class generative constructors take a pre-constructed object.
- inputs.add(graph.addConstantNull(closedWorld));
- }
- inputs.addAll(makeStaticArgumentList(
- callStructure, send.arguments, constructorImplementation.declaration));
-
- TypeMask elementType = computeType(constructor);
- if (isFixedListConstructorCall) {
- if (!inputs[0].isNumber(abstractValueDomain)) {
- HTypeConversion conversion = new HTypeConversion(
- null,
- HTypeConversion.ARGUMENT_TYPE_CHECK,
- commonMasks.numType,
- inputs[0],
- sourceInformation);
- add(conversion);
- inputs[0] = conversion;
- }
- js.Template code = js.js.parseForeignJS('new Array(#)');
- var behavior = new native.NativeBehavior();
- behavior.typesInstantiated.add(expectedType);
- behavior.typesReturned.add(expectedType);
- // The allocation can throw only if the given length is a double or
- // outside the unsigned 32 bit range.
- // TODO(sra): Array allocation should be an instruction so that canThrow
- // can depend on a length type discovered in optimization.
- bool canThrow = true;
- if (inputs[0].isInteger(abstractValueDomain) && inputs[0] is HConstant) {
- dynamic constant = inputs[0];
- IntConstantValue intConstant = constant.constant;
- int value = intConstant.intValue;
- if (0 <= value && value < 0x100000000) canThrow = false;
- }
- HForeignCode foreign = new HForeignCode(code, elementType, inputs,
- nativeBehavior: behavior,
- throwBehavior: canThrow
- ? native.NativeThrowBehavior.MAY
- : native.NativeThrowBehavior.NEVER);
- push(foreign);
- if (globalInferenceResults.isFixedArrayCheckedForGrowable(send)) {
- js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
- // We set the instruction as [canThrow] to avoid it being dead code.
- // We need a finer grained side effect.
- add(new HForeignCode(code, commonMasks.nullType, [stack.last],
- throwBehavior: native.NativeThrowBehavior.MAY));
- }
- } else if (isGrowableListConstructorCall) {
- push(buildLiteralList(<HInstruction>[]));
- stack.last.instructionType = elementType;
- } else if (constructor.isExternal &&
- constructor.isFromEnvironmentConstructor) {
- generateUnsupportedError(
- node,
- '${cls.name}.${constructor.name} '
- 'can only be used as a const constructor');
- } else {
- potentiallyAddTypeArguments(inputs, cls, expectedType);
- addInlinedInstantiation(expectedType);
- pushInvokeStatic(node, constructor.declaration, inputs,
- typeMask: elementType,
- instanceType: expectedType,
- sourceInformation: sourceInformation);
- removeInlinedInstantiation(expectedType);
- }
- HInstruction newInstance = stack.last;
- if (isFixedList) {
- // Overwrite the element type, in case the allocation site has
- // been inlined.
- newInstance.instructionType = elementType;
- graph.allocatedFixedLists?.add(newInstance);
- }
-
- // The List constructor forwards to a Dart static method that does
- // not know about the type argument. Therefore we special case
- // this constructor to have the setRuntimeTypeInfo called where
- // the 'new' is done.
- if (rtiNeed.classNeedsTypeArguments(commonElements.listClass) &&
- (isFixedListConstructorCall ||
- isGrowableListConstructorCall ||
- isJSArrayTypedConstructor)) {
- newInstance = handleListConstructor(type, pop(), sourceInformation);
- stack.add(newInstance);
- }
-
- // Finally, if we called a redirecting factory constructor, check the type.
- if (isRedirected) {
- HInstruction checked = typeBuilder
- .potentiallyCheckOrTrustTypeOfAssignment(newInstance, type);
- if (checked != newInstance) {
- pop();
- stack.add(checked);
- }
- }
- }
-
- void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls,
- ResolutionInterfaceType expectedType,
- {SourceInformation sourceInformation}) {
- if (!rtiNeed.classNeedsTypeArguments(cls)) return;
- assert(cls.typeVariables.length == expectedType.typeArguments.length);
- expectedType.typeArguments.forEach((ResolutionDartType argument) {
- inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
- sourceInformation: sourceInformation));
- });
- }
-
- /// In checked mode checks the [type] of [node] to be well-bounded. The method
- /// returns [:true:] if an error can be statically determined.
- bool checkTypeVariableBounds(
- ast.NewExpression node, ResolutionInterfaceType type) {
- if (!options.enableTypeAssertions) return false;
-
- Map<ResolutionDartType, Set<ResolutionDartType>> seenChecksMap =
- new Map<ResolutionDartType, Set<ResolutionDartType>>();
- bool definitelyFails = false;
-
- void addTypeVariableBoundCheck(
- InterfaceType _instance,
- DartType _typeArgument,
- TypeVariableType _typeVariable,
- DartType _bound) {
- if (definitelyFails) return;
- ResolutionInterfaceType instance = _instance;
- ResolutionDartType typeArgument = _typeArgument;
- ResolutionTypeVariableType typeVariable = _typeVariable;
- ResolutionDartType bound = _bound;
-
- int subtypeRelation = types.computeSubtypeRelation(typeArgument, bound);
- if (subtypeRelation == DartTypes.IS_SUBTYPE) return;
-
- String prefix = "Can't create an instance of malbounded type '$type': '";
- String infix = "' is not a subtype of bound '";
- String suffix;
-
- if (type == instance) {
- suffix = "' of type variable '${typeVariable}' of type "
- "'${type.element.thisType}'.";
- } else {
- suffix = "' of type variable '${typeVariable}' of type "
- "'${instance.element.thisType}' on the supertype "
- "'${instance}' of '${type}'.";
- }
-
- if (subtypeRelation == DartTypes.NOT_SUBTYPE) {
- String message = "TypeError: $prefix$typeArgument$infix$bound$suffix";
- generateTypeError(node, message);
- definitelyFails = true;
- return;
- } else if (subtypeRelation == DartTypes.MAYBE_SUBTYPE) {
- Set<ResolutionDartType> seenChecks = seenChecksMap.putIfAbsent(
- typeArgument, () => new Set<ResolutionDartType>());
- if (!seenChecks.contains(bound)) {
- seenChecks.add(bound);
- assertIsSubtype(node, typeArgument, bound, prefix, infix, suffix);
- }
- }
- }
-
- types.checkTypeVariableBounds(type, type.typeArguments,
- type.element.typeVariables, addTypeVariableBoundCheck);
- if (definitelyFails) {
- return true;
- }
- for (ResolutionInterfaceType supertype in type.element.allSupertypes) {
- ResolutionInterfaceType instance = type.asInstanceOf(supertype.element);
- types.checkTypeVariableBounds(instance, instance.typeArguments,
- instance.element.typeVariables, addTypeVariableBoundCheck);
- if (definitelyFails) {
- return true;
- }
- }
- return false;
- }
-
- visitStaticSend(ast.Send node) {
- internalError(node, "Unexpected visitStaticSend");
- }
-
- /// Generate an invocation to the static or top level [function].
- void generateStaticFunctionInvoke(
- ast.Send node, MethodElement function, CallStructure callStructure) {
- List<HInstruction> inputs =
- makeStaticArgumentList(callStructure, node.arguments, function);
- pushInvokeStatic(node, function, inputs,
- sourceInformation:
- sourceInformationBuilder.buildCall(node.selector, node.selector));
- }
-
- /// Generate an invocation to a static or top level function with the wrong
- /// number of arguments.
- void generateStaticFunctionIncompatibleInvoke(
- ast.Send node, Element element) {
- generateWrongArgumentCountError(node, element, node.arguments);
- }
-
- @override
- void visitStaticFieldInvoke(ast.Send node, FieldElement field,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateStaticFieldGet(node, field);
- generateCallInvoke(
- node,
- pop(),
- sourceInformationBuilder.buildCall(
- node.argumentsNode, node.argumentsNode));
- }
-
- @override
- void visitStaticFunctionInvoke(ast.Send node, MethodElement function,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateStaticFunctionInvoke(node, function, callStructure);
- }
-
- @override
- void visitStaticFunctionIncompatibleInvoke(
- ast.Send node,
- MethodElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- generateStaticFunctionIncompatibleInvoke(node, function);
- }
-
- @override
- void visitStaticGetterInvoke(ast.Send node, FunctionElement getter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateStaticGetterGet(node, getter);
- generateCallInvoke(node, pop(),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- void visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateStaticFieldGet(node, field);
- generateCallInvoke(node, pop(),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- void visitTopLevelFunctionInvoke(ast.Send node, MethodElement function,
- ast.NodeList arguments, CallStructure callStructure, _) {
- if (closedWorld.commonElements.isForeign(function)) {
- handleForeignSend(node, function);
- } else {
- generateStaticFunctionInvoke(node, function, callStructure);
- }
- }
-
- @override
- void visitTopLevelFunctionIncompatibleInvoke(
- ast.Send node,
- MethodElement function,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- generateStaticFunctionIncompatibleInvoke(node, function);
- }
-
- @override
- void visitTopLevelGetterInvoke(ast.Send node, FunctionElement getter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateStaticGetterGet(node, getter);
- generateCallInvoke(node, pop(),
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- @override
- void visitTopLevelSetterGet(ast.Send node, MethodElement setter, _) {
- handleInvalidStaticGet(node, setter);
- }
-
- @override
- void visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
- handleInvalidStaticGet(node, setter);
- }
-
- @override
- void visitUnresolvedGet(ast.Send node, Element element, _) {
- generateStaticUnresolvedGet(node, element);
- }
-
- void handleInvalidStaticInvoke(ast.Send node, Element element) {
- generateThrowNoSuchMethod(node, noSuchMethodTargetSymbolString(element),
- argumentNodes: node.arguments);
- }
-
- @override
- void visitStaticSetterInvoke(ast.Send node, MethodElement setter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- handleInvalidStaticInvoke(node, setter);
- }
-
- @override
- void visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
- ast.NodeList arguments, CallStructure callStructure, _) {
- handleInvalidStaticInvoke(node, setter);
- }
-
- @override
- void visitUnresolvedInvoke(ast.Send node, Element element,
- ast.NodeList arguments, Selector selector, _) {
- if (element is ErroneousElement) {
- // An erroneous element indicates that the function could not be
- // resolved (a warning has been issued).
- handleInvalidStaticInvoke(node, element);
- } else {
- // TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(closedWorld));
- }
- return;
- }
-
- HConstant addConstantString(String string) {
- return graph.addConstantString(string, closedWorld);
- }
-
- HConstant addConstantStringFromName(js.Name name) {
- return graph.addConstantStringFromName(name, closedWorld);
- }
-
- visitClassTypeLiteralGet(ast.Send node, ConstantExpression constant, _) {
- generateConstantTypeLiteral(node);
- }
-
- visitClassTypeLiteralInvoke(ast.Send node, ConstantExpression constant,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateConstantTypeLiteral(node);
- generateTypeLiteralCall(node);
- }
-
- visitTypedefTypeLiteralGet(ast.Send node, ConstantExpression constant, _) {
- generateConstantTypeLiteral(node);
- }
-
- visitTypedefTypeLiteralInvoke(ast.Send node, ConstantExpression constant,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateConstantTypeLiteral(node);
- generateTypeLiteralCall(node);
- }
-
- visitTypeVariableTypeLiteralGet(
- ast.Send node, TypeVariableElement element, _) {
- generateTypeVariableLiteral(node, element.type);
- }
-
- visitTypeVariableTypeLiteralInvoke(ast.Send node, TypeVariableElement element,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateTypeVariableLiteral(node, element.type);
- generateTypeLiteralCall(node);
- }
-
- visitDynamicTypeLiteralGet(ast.Send node, ConstantExpression constant, _) {
- generateConstantTypeLiteral(node);
- }
-
- visitDynamicTypeLiteralInvoke(ast.Send node, ConstantExpression constant,
- ast.NodeList arguments, CallStructure callStructure, _) {
- generateConstantTypeLiteral(node);
- generateTypeLiteralCall(node);
- }
-
- /// Generate the constant value for a constant type literal.
- void generateConstantTypeLiteral(ast.Send node) {
- // TODO(karlklose): add type representation
- if (node.isCall) {
- // The node itself is not a constant but we register the selector (the
- // identifier that refers to the class/typedef) as a constant.
- stack.add(addConstant(node.selector));
- } else {
- stack.add(addConstant(node));
- }
- }
-
- /// Generate the literal for [typeVariable] in the current context.
- void generateTypeVariableLiteral(
- ast.Send node, ResolutionTypeVariableType typeVariable) {
- // GENERIC_METHODS: This provides thin support for method type variables
- // by treating them as malformed when evaluated as a literal. For full
- // support of generic methods this must be revised.
- if (typeVariable is MethodTypeVariableType) {
- generateTypeError(node, "Method type variables are not reified");
- } else {
- ResolutionDartType type = localsHandler.substInContext(typeVariable);
- HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement,
- sourceInformation: sourceInformationBuilder.buildGet(node));
- pushInvokeStatic(node, commonElements.runtimeTypeToString, [value],
- typeMask: commonMasks.stringType);
- pushInvokeStatic(node, commonElements.createRuntimeType, [pop()]);
- }
- }
-
- /// Generate a call to a type literal.
- void generateTypeLiteralCall(ast.Send node) {
- // This send is of the form 'e(...)', where e is resolved to a type
- // reference. We create a regular closure call on the result of the type
- // reference instead of creating a NoSuchMethodError to avoid pulling it
- // in if it is not used (e.g., in a try/catch).
- HInstruction target = pop();
- generateCallInvoke(node, target,
- sourceInformationBuilder.buildCall(node, node.argumentsNode));
- }
-
- /// Generate a '.call' invocation on [target].
- void generateCallInvoke(
- ast.Send node, HInstruction target, SourceInformation sourceInformation) {
- Selector selector = elements.getSelector(node);
- List<HInstruction> inputs = <HInstruction>[target];
- addDynamicSendArgumentsToList(node, inputs);
- push(new HInvokeClosure(new Selector.callClosureFrom(selector), inputs,
- commonMasks.dynamicType, const <DartType>[])
- ..sourceInformation = sourceInformation);
- }
-
- visitGetterSend(ast.Send node) {
- internalError(node, "Unexpected visitGetterSend");
- }
-
- // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
- internalError(Spannable node, String reason) {
- reporter.internalError(node, reason);
- }
-
- void generateError(ast.Node node, String message, Element helper) {
- HInstruction errorMessage = addConstantString(message);
- pushInvokeStatic(node, helper, [errorMessage]);
- }
-
- void generateRuntimeError(ast.Node node, String message) {
- MethodElement helper = commonElements.throwRuntimeError;
- generateError(node, message, helper);
- }
-
- void generateUnsupportedError(ast.Node node, String message) {
- MethodElement helper = commonElements.throwUnsupportedError;
- generateError(node, message, helper);
- }
-
- void generateTypeError(ast.Node node, String message) {
- MethodElement helper = commonElements.throwTypeError;
- generateError(node, message, helper);
- }
-
- void generateAbstractClassInstantiationError(ast.Node node, String message) {
- MethodElement helper = commonElements.throwAbstractClassInstantiationError;
- generateError(node, message, helper);
- }
-
- void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName,
- {Link<ast.Node> argumentNodes,
- List<HInstruction> argumentValues,
- List<String> existingArguments,
- SourceInformation sourceInformation}) {
- MethodElement helper = commonElements.throwNoSuchMethod;
- ConstantValue receiverConstant = constantSystem.createString('');
- HInstruction receiver = graph.addConstant(receiverConstant, closedWorld);
- ConstantValue nameConstant = constantSystem.createString(methodName);
- HInstruction name = graph.addConstant(nameConstant, closedWorld);
- if (argumentValues == null) {
- argumentValues = <HInstruction>[];
- argumentNodes.forEach((argumentNode) {
- visit(argumentNode);
- HInstruction value = pop();
- argumentValues.add(value);
- });
- }
- HInstruction arguments = buildLiteralList(argumentValues);
- add(arguments);
- HInstruction existingNamesList;
- if (existingArguments != null) {
- List<HInstruction> existingNames = <HInstruction>[];
- for (String name in existingArguments) {
- HInstruction nameConstant = graph.addConstantString(name, closedWorld);
- existingNames.add(nameConstant);
- }
- existingNamesList = buildLiteralList(existingNames);
- add(existingNamesList);
- } else {
- existingNamesList = graph.addConstantNull(closedWorld);
- }
- pushInvokeStatic(
- diagnosticNode, helper, [receiver, name, arguments, existingNamesList],
- sourceInformation: sourceInformation);
- }
-
- /**
- * Generate code to throw a [NoSuchMethodError] exception for calling a
- * method with a wrong number of arguments or mismatching named optional
- * arguments.
- */
- void generateWrongArgumentCountError(ast.Node diagnosticNode,
- FunctionElement function, Link<ast.Node> argumentNodes) {
- List<String> existingArguments = <String>[];
- FunctionSignature signature = function.functionSignature;
- signature.forEachParameter((Element parameter) {
- existingArguments.add(parameter.name);
- });
- generateThrowNoSuchMethod(diagnosticNode, function.name,
- argumentNodes: argumentNodes, existingArguments: existingArguments);
- }
-
- @override
- void bulkHandleNode(ast.Node node, String message, _) {
- internalError(node, "Unexpected bulk handled node: $node");
- }
-
- @override
- void bulkHandleNew(ast.NewExpression node, [_]) {
- Element element = elements[node.send];
- if (!Elements.isMalformed(element)) {
- ConstructorElement function = element;
- element = function.effectiveTarget;
- }
- final bool isSymbolConstructor =
- element == commonElements.symbolConstructorTarget;
- if (Elements.isError(element)) {
- ErroneousElement error = element;
- if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR ||
- error.messageKind == MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR) {
- generateThrowNoSuchMethod(
- node.send, noSuchMethodTargetSymbolString(error, 'constructor'),
- argumentNodes: node.send.arguments);
- } else {
- MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind];
- Message message = template.message(error.messageArguments);
- generateRuntimeError(node.send, message.toString());
- }
- } else if (Elements.isMalformed(element)) {
- // TODO(ahe): Do something like [generateWrongArgumentCountError].
- stack.add(graph.addConstantNull(closedWorld));
- } else if (node.isConst) {
- stack.add(addConstant(node));
- if (isSymbolConstructor) {
- ConstructedConstantValue symbol = getConstantForNode(node);
- StringConstantValue stringConstant = symbol.fields.values.single;
- String nameString = stringConstant.stringValue;
- registry?.registerConstSymbol(nameString);
- }
- } else {
- handleNewSend(node);
- }
- }
-
- @override
- void errorNonConstantConstructorInvoke(
- ast.NewExpression node,
- Element element,
- ResolutionDartType type,
- ast.NodeList arguments,
- CallStructure callStructure,
- _) {
- bulkHandleNew(node);
- }
-
- void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask,
- List<HInstruction> arguments,
- {SourceInformation sourceInformation}) {
- // We prefer to not inline certain operations on indexables,
- // because the constant folder will handle them better and turn
- // them into simpler instructions that allow further
- // optimizations.
- bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
- bool isLength = selector.isGetter && selector.name == "length";
- if (isLength || selector.isIndex) {
- return closedWorld.isSubtypeOf(
- element.enclosingClass, commonElements.jsIndexableClass);
- } else if (selector.isIndexSet) {
- return closedWorld.isSubtypeOf(
- element.enclosingClass, commonElements.jsMutableIndexableClass);
- } else {
- return false;
- }
- }
-
- bool isOptimizableOperation(Selector selector, MemberElement element) {
- ClassElement cls = element.enclosingClass;
- if (isOptimizableOperationOnIndexable(selector, element)) return true;
- if (!interceptorData.interceptedClasses.contains(cls)) return false;
- if (selector.isOperator) return true;
- if (selector.isSetter) return true;
- if (selector.isIndex) return true;
- if (selector.isIndexSet) return true;
- if (element == commonElements.jsArrayAdd ||
- element == commonElements.jsArrayRemoveLast ||
- commonElements.isJsStringSplit(element)) {
- return true;
- }
- return false;
- }
-
- MemberElement element = closedWorld.locateSingleMember(selector, mask);
- if (element != null &&
- !element.isField &&
- !(element.isGetter && selector.isCall) &&
- !(element.isFunction && selector.isGetter) &&
- !isOptimizableOperation(selector, element)) {
- if (tryInlineMethod(element, selector, mask, arguments, node)) {
- return;
- }
- }
-
- HInstruction receiver = arguments[0];
- List<HInstruction> inputs = <HInstruction>[];
- bool isIntercepted = interceptorData.isInterceptedSelector(selector);
- if (isIntercepted) {
- inputs.add(invokeInterceptor(receiver));
- }
- inputs.addAll(arguments);
- TypeMask type = TypeMaskFactory.inferredTypeForSelector(
- selector, mask, globalInferenceResults);
- if (selector.isGetter) {
- push(new HInvokeDynamicGetter(selector, mask, null, inputs, isIntercepted,
- type, sourceInformation));
- } else if (selector.isSetter) {
- push(new HInvokeDynamicSetter(selector, mask, null, inputs, isIntercepted,
- type, sourceInformation));
- } else {
- push(new HInvokeDynamicMethod(
- selector, mask, inputs, type, const <DartType>[], sourceInformation,
- isIntercepted: isIntercepted));
- }
- }
-
- HForeignCode invokeJsInteropFunction(MethodElement element,
- List<HInstruction> arguments, SourceInformation sourceInformation) {
- assert(nativeData.isJsInteropMember(element));
- nativeEmitter.nativeMethods.add(element);
-
- if (element.isFactoryConstructor &&
- nativeData.isAnonymousJsInteropClass(element.contextClass)) {
- // Factory constructor that is syntactic sugar for creating a JavaScript
- // object literal.
- ConstructorElement constructor = element;
- FunctionSignature params = constructor.functionSignature;
- int i = 0;
- int positions = 0;
- var filteredArguments = <HInstruction>[];
- var parameterNameMap = new Map<String, js.Expression>();
- params.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- // TODO(jacobr): consider throwing if parameter names do not match
- // names of properties in the class.
- assert(parameter.isNamed);
- HInstruction argument = arguments[i];
- if (argument != null) {
- filteredArguments.add(argument);
- var jsName = nativeData.computeUnescapedJSInteropName(parameter.name);
- parameterNameMap[jsName] = new js.InterpolatedExpression(positions++);
- }
- i++;
- });
- var codeTemplate =
- new js.Template(null, js.objectLiteral(parameterNameMap));
-
- var nativeBehavior = new native.NativeBehavior()
- ..codeTemplate = codeTemplate;
- if (options.trustJSInteropTypeAnnotations) {
- nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType);
- }
- return new HForeignCode(
- codeTemplate, commonMasks.dynamicType, filteredArguments,
- nativeBehavior: nativeBehavior)
- ..sourceInformation = sourceInformation;
- }
- var target = new HForeignCode(
- js.js.parseForeignJS("${nativeData.getFixedBackendMethodPath(element)}."
- "${nativeData.getFixedBackendName(element)}"),
- commonMasks.dynamicType,
- <HInstruction>[]);
- add(target);
- // Strip off trailing arguments that were not specified.
- // we could assert that the trailing arguments are all null.
- // TODO(jacobr): rewrite named arguments to an object literal matching
- // the factory constructor case.
- arguments = arguments.where((arg) => arg != null).toList();
- var inputs = <HInstruction>[target]..addAll(arguments);
-
- var nativeBehavior = new native.NativeBehavior()
- ..sideEffects.setAllSideEffects();
-
- ResolutionDartType type = element.isConstructor
- ? element.enclosingClass.thisType
- : element.type.returnType;
- // Native behavior effects here are similar to native/behavior.dart.
- // The return type is dynamic if we don't trust js-interop type
- // declarations.
- nativeBehavior.typesReturned.add(options.trustJSInteropTypeAnnotations
- ? type
- : const ResolutionDynamicType());
-
- // The allocation effects include the declared type if it is native (which
- // includes js interop types).
- if (type is ResolutionInterfaceType &&
- nativeData.isNativeClass(type.element)) {
- nativeBehavior.typesInstantiated.add(type);
- }
-
- // It also includes any other JS interop type if we don't trust the
- // annotation or if is declared too broad.
- if (!options.trustJSInteropTypeAnnotations ||
- type.isObject ||
- type.isDynamic) {
- ClassElement cls = commonElements.jsJavaScriptObjectClass;
- nativeBehavior.typesInstantiated.add(cls.thisType);
- }
-
- String code;
- if (element.isGetter) {
- code = "#";
- } else if (element.isSetter) {
- code = "# = #";
- } else {
- var args = new List.filled(arguments.length, '#').join(',');
- code = element.isConstructor ? "new #($args)" : "#($args)";
- }
- js.Template codeTemplate = js.js.parseForeignJS(code);
- nativeBehavior.codeTemplate = codeTemplate;
-
- return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs,
- nativeBehavior: nativeBehavior)
- ..sourceInformation = sourceInformation;
- }
-
- void pushInvokeStatic(
- ast.Node location, MethodElement element, List<HInstruction> arguments,
- {TypeMask typeMask,
- ResolutionInterfaceType instanceType,
- SourceInformation sourceInformation}) {
- assert(element.isDeclaration);
- // TODO(johnniwinther): Use [sourceInformation] instead of [location].
- if (tryInlineMethod(element, null, null, arguments, location,
- instanceType: instanceType)) {
- return;
- }
-
- if (typeMask == null) {
- typeMask = TypeMaskFactory.inferredReturnTypeForElement(
- element, globalInferenceResults);
- }
- bool targetCanThrow = !closedWorld.getCannotThrow(element);
- // TODO(5346): Try to avoid the need for calling [declaration] before
- var instruction;
- if (nativeData.isJsInteropMember(element)) {
- instruction =
- invokeJsInteropFunction(element, arguments, sourceInformation);
- } else {
- // creating an [HInvokeStatic].
- instruction = new HInvokeStatic(
- element, arguments, typeMask, const <DartType>[],
- targetCanThrow: targetCanThrow)
- ..sourceInformation = sourceInformation;
- if (currentInlinedInstantiations.isNotEmpty) {
- instruction.instantiatedTypes = new List<ResolutionInterfaceType>.from(
- currentInlinedInstantiations);
- }
- instruction.sideEffects = closedWorld.getSideEffectsOfElement(element);
- }
- if (sourceInformation != null || location == null) {
- push(instruction);
- } else {
- pushWithPosition(instruction, location);
- }
- }
-
- HInstruction buildInvokeSuper(Selector selector, MemberElement element,
- List<HInstruction> arguments, SourceInformation sourceInformation) {
- HInstruction receiver =
- localsHandler.readThis(sourceInformation: sourceInformation);
- // TODO(5346): Try to avoid the need for calling [declaration] before
- // creating an [HStatic].
- List<HInstruction> inputs = <HInstruction>[];
- // Fields don't need an interceptor; consider generating HFieldGet/Set instead.
-
- bool isIntercepted = interceptorData.isInterceptedSelector(selector) &&
- element.kind != ElementKind.FIELD;
- if (isIntercepted) {
- inputs.add(invokeInterceptor(receiver));
- }
- inputs.add(receiver);
- inputs.addAll(arguments);
- TypeMask type;
- if (!element.isGetter && selector.isGetter) {
- type = TypeMaskFactory.inferredTypeForMember(
- element, globalInferenceResults);
- } else if (element.isFunction) {
- MethodElement method = element;
- type = TypeMaskFactory.inferredReturnTypeForElement(
- method, globalInferenceResults);
- } else {
- type = closedWorld.abstractValueDomain.dynamicType;
- }
- HInstruction instruction = new HInvokeSuper(
- element,
- currentNonClosureClass,
- selector,
- inputs,
- isIntercepted,
- type,
- const <DartType>[],
- sourceInformation,
- isSetter: selector.isSetter || selector.isIndexSet);
- instruction.sideEffects =
- closedWorld.getSideEffectsOfSelector(selector, null);
- return instruction;
- }
-
- void handleComplexOperatorSend(
- ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) {
- HInstruction rhs;
- if (node.isPrefix || node.isPostfix) {
- rhs = graph.addConstantInt(1, closedWorld);
- } else {
- visit(arguments.head);
- assert(arguments.tail.isEmpty);
- rhs = pop();
- }
- visitBinarySend(
- receiver,
- rhs,
- elements.getOperatorSelectorInComplexSendSet(node),
- elementInferenceResults.typeOfOperator(node),
- node,
- sourceInformation:
- sourceInformationBuilder.buildGeneric(node.assignmentOperator));
- }
-
- void handleSuperSendSet(ast.SendSet node) {
- MemberElement element = elements[node];
- List<HInstruction> setterInputs = <HInstruction>[];
- void generateSuperSendSet() {
- Selector setterSelector = elements.getSelector(node);
- if (Elements.isUnresolved(element) || !setterSelector.applies(element)) {
- generateSuperNoSuchMethodSend(node, setterSelector, setterInputs);
- pop();
- } else {
- add(buildInvokeSuper(setterSelector, element, setterInputs,
- sourceInformationBuilder.buildAssignment(node)));
- }
- }
-
- if (identical(node.assignmentOperator.source, '=')) {
- addDynamicSendArgumentsToList(node, setterInputs);
- generateSuperSendSet();
- stack.add(setterInputs.last);
- } else {
- Element getter = elements[node.selector];
- List<HInstruction> getterInputs = <HInstruction>[];
- Link<ast.Node> arguments = node.arguments;
- if (node.isIndex) {
- // If node is of the form [:super.foo[0] += 2:], the send has
- // two arguments: the index and the left hand side. We get
- // the index and add it as input of the getter and the
- // setter.
- visit(arguments.head);
- arguments = arguments.tail;
- HInstruction index = pop();
- getterInputs.add(index);
- setterInputs.add(index);
- }
- HInstruction getterInstruction;
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- if (Elements.isUnresolved(getter)) {
- generateSuperNoSuchMethodSend(node, getterSelector, getterInputs);
- getterInstruction = pop();
- } else {
- getterInstruction = buildInvokeSuper(getterSelector, getter,
- getterInputs, sourceInformationBuilder.buildGet(node));
- add(getterInstruction);
- }
-
- if (node.isIfNullAssignment) {
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleIfNull(() => stack.add(getterInstruction), () {
- addDynamicSendArgumentsToList(node, setterInputs);
- generateSuperSendSet();
- stack.add(setterInputs.last);
- });
- } else {
- handleComplexOperatorSend(node, getterInstruction, arguments);
- setterInputs.add(pop());
- generateSuperSendSet();
- stack.add(node.isPostfix ? getterInstruction : setterInputs.last);
- }
- }
- }
-
- @override
- void handleSuperCompounds(
- ast.SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- CompoundRhs rhs,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitFinalSuperFieldSet(
- ast.SendSet node, FieldElement field, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperFieldSet(
- ast.SendSet node, FieldElement field, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperGetterSet(
- ast.SendSet node, FunctionElement getter, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperIndexSet(ast.SendSet node, FunctionElement function,
- ast.Node index, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperMethodSet(
- ast.SendSet node, MethodElement method, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperSetterSet(
- ast.SendSet node, FunctionElement setter, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperIndexSet(ast.SendSet node, ErroneousElement element,
- ast.Node index, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperIndexPrefix(
- ast.Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- ast.Node index,
- IncDecOperator operator,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperIndexPostfix(
- ast.Send node,
- MethodElement indexFunction,
- MethodElement indexSetFunction,
- ast.Node index,
- IncDecOperator operator,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperGetterIndexPrefix(ast.SendSet node, Element element,
- MethodElement setter, ast.Node index, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperGetterIndexPostfix(ast.SendSet node, Element element,
- MethodElement setter, ast.Node index, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperSetterIndexPrefix(
- ast.SendSet node,
- MethodElement indexFunction,
- Element element,
- ast.Node index,
- IncDecOperator operator,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperSetterIndexPostfix(
- ast.SendSet node,
- MethodElement indexFunction,
- Element element,
- ast.Node index,
- IncDecOperator operator,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperIndexPrefix(ast.Send node, Element element,
- ast.Node index, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperIndexPostfix(ast.Send node, Element element,
- ast.Node index, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperCompoundIndexSet(
- ast.SendSet node,
- MethodElement getter,
- MethodElement setter,
- ast.Node index,
- AssignmentOperator operator,
- ast.Node rhs,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperGetterCompoundIndexSet(
- ast.SendSet node,
- Element element,
- MethodElement setter,
- ast.Node index,
- AssignmentOperator operator,
- ast.Node rhs,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperSetterCompoundIndexSet(
- ast.SendSet node,
- MethodElement getter,
- Element element,
- ast.Node index,
- AssignmentOperator operator,
- ast.Node rhs,
- _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperCompoundIndexSet(ast.SendSet node, Element element,
- ast.Node index, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperFieldCompound(ast.Send node, FieldElement field,
- AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitFinalSuperFieldCompound(ast.Send node, FieldElement field,
- AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitFinalSuperFieldPrefix(
- ast.Send node, FieldElement field, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperPrefix(
- ast.SendSet node, Element element, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperPostfix(
- ast.SendSet node, Element element, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperCompound(ast.Send node, Element element,
- AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitFinalSuperFieldPostfix(
- ast.Send node, FieldElement field, IncDecOperator operator, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperFieldFieldCompound(ast.Send node, FieldElement readField,
- FieldElement writtenField, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperGetterSetterCompound(ast.Send node, FunctionElement getter,
- FunctionElement setter, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperMethodSetterCompound(ast.Send node, FunctionElement method,
- FunctionElement setter, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperMethodCompound(ast.Send node, MethodElement method,
- AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperGetterCompound(ast.SendSet node, Element element,
- SetterElement setter, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitUnresolvedSuperSetterCompound(ast.Send node, GetterElement getter,
- Element element, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperFieldSetterCompound(ast.Send node, FieldElement field,
- FunctionElement setter, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitSuperGetterFieldCompound(ast.Send node, FunctionElement getter,
- FieldElement field, AssignmentOperator operator, ast.Node rhs, _) {
- handleSuperSendSet(node);
- }
-
- @override
- void visitIndexSet(
- ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
- generateDynamicSend(node);
- }
-
- @override
- void visitCompoundIndexSet(ast.SendSet node, ast.Node receiver,
- ast.Node index, AssignmentOperator operator, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- handleIndexSendSet(node);
- }
-
- @override
- void visitIndexPrefix(ast.Send node, ast.Node receiver, ast.Node index,
- IncDecOperator operator, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- handleIndexSendSet(node);
- }
-
- @override
- void visitIndexPostfix(ast.Send node, ast.Node receiver, ast.Node index,
- IncDecOperator operator, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- handleIndexSendSet(node);
- }
-
- void handleIndexSendSet(ast.SendSet node) {
- ast.Operator op = node.assignmentOperator;
- if ("=" == op.source) {
- internalError(node, "Unexpected index set.");
- } else {
- visit(node.receiver);
- HInstruction receiver = pop();
- Link<ast.Node> arguments = node.arguments;
- HInstruction index;
- if (node.isIndex) {
- visit(arguments.head);
- arguments = arguments.tail;
- index = pop();
- }
-
- pushInvokeDynamic(node, elements.getGetterSelectorInComplexSendSet(node),
- elementInferenceResults.typeOfGetter(node), [receiver, index]);
- HInstruction getterInstruction = pop();
- if (node.isIfNullAssignment) {
- // Compile x[i] ??= e as:
- // t1 = x[i]
- // if (t1 == null)
- // t1 = x[i] = e;
- // result = t1
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleIfNull(() => stack.add(getterInstruction), () {
- visit(arguments.head);
- HInstruction value = pop();
- pushInvokeDynamic(
- node,
- elements.getSelector(node),
- elementInferenceResults.typeOfSend(node),
- [receiver, index, value]);
- pop();
- stack.add(value);
- });
- } else {
- handleComplexOperatorSend(node, getterInstruction, arguments);
- HInstruction value = pop();
- pushInvokeDynamic(node, elements.getSelector(node),
- elementInferenceResults.typeOfSend(node), [receiver, index, value]);
- pop();
- if (node.isPostfix) {
- stack.add(getterInstruction);
- } else {
- stack.add(value);
- }
- }
- }
- }
-
- @override
- void visitThisPropertySet(ast.SendSet node, Name name, ast.Node rhs, _) {
- generateInstanceSetterWithCompiledReceiver(
- node,
- localsHandler.readThis(
- sourceInformation: sourceInformationBuilder.buildGet(node)),
- visitAndPop(rhs));
- }
-
- @override
- void visitDynamicPropertySet(
- ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) {
- generateInstanceSetterWithCompiledReceiver(
- node, generateInstanceSendReceiver(node), visitAndPop(rhs));
- }
-
- @override
- void visitIfNotNullDynamicPropertySet(
- ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) {
- // compile e?.x = e2 to:
- //
- // t1 = e
- // if (t1 == null)
- // result = t1 // same as result = null
- // else
- // result = e.x = e2
- HInstruction receiverInstruction;
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleConditional(
- () {
- receiverInstruction = generateInstanceSendReceiver(node);
- pushCheckNull(receiverInstruction);
- },
- () => stack.add(receiverInstruction),
- () {
- generateInstanceSetterWithCompiledReceiver(
- node, receiverInstruction, visitAndPop(rhs));
- });
- }
-
- @override
- void visitParameterSet(
- ast.SendSet node, ParameterElement parameter, ast.Node rhs, _) {
- generateNonInstanceSetter(node, parameter, visitAndPop(rhs));
- }
-
- @override
- void visitFinalParameterSet(
- ast.SendSet node, ParameterElement parameter, ast.Node rhs, _) {
- generateNoSuchSetter(node, parameter, visitAndPop(rhs));
- }
-
- @override
- void visitLocalVariableSet(
- ast.SendSet node, LocalVariableElement variable, ast.Node rhs, _) {
- generateNonInstanceSetter(node, variable, visitAndPop(rhs));
- }
-
- @override
- void visitFinalLocalVariableSet(
- ast.SendSet node, LocalVariableElement variable, ast.Node rhs, _) {
- generateNoSuchSetter(node, variable, visitAndPop(rhs));
- }
-
- @override
- void visitLocalFunctionSet(
- ast.SendSet node, LocalFunctionElement function, ast.Node rhs, _) {
- generateNoSuchSetter(node, function, visitAndPop(rhs));
- }
-
- @override
- void visitTopLevelFieldSet(
- ast.SendSet node, FieldElement field, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNonInstanceSetter(node, field, visitAndPop(rhs));
- }
-
- @override
- void visitFinalTopLevelFieldSet(
- ast.SendSet node, FieldElement field, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNoSuchSetter(node, field, visitAndPop(rhs));
- }
-
- @override
- void visitTopLevelGetterSet(
- ast.SendSet node, GetterElement getter, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNoSuchSetter(node, getter, visitAndPop(rhs));
- }
-
- @override
- void visitTopLevelSetterSet(
- ast.SendSet node, SetterElement setter, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNonInstanceSetter(node, setter, visitAndPop(rhs));
- }
-
- @override
- void visitTopLevelFunctionSet(
- ast.SendSet node, MethodElement function, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNoSuchSetter(node, function, visitAndPop(rhs));
- }
-
- @override
- void visitStaticFieldSet(
- ast.SendSet node, FieldElement field, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNonInstanceSetter(node, field, visitAndPop(rhs));
- }
-
- @override
- void visitFinalStaticFieldSet(
- ast.SendSet node, FieldElement field, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNoSuchSetter(node, field, visitAndPop(rhs));
- }
-
- @override
- void visitStaticGetterSet(
- ast.SendSet node, GetterElement getter, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNoSuchSetter(node, getter, visitAndPop(rhs));
- }
-
- @override
- void visitStaticSetterSet(
- ast.SendSet node, SetterElement setter, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNonInstanceSetter(node, setter, visitAndPop(rhs));
- }
-
- @override
- void visitStaticFunctionSet(
- ast.SendSet node, MethodElement function, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNoSuchSetter(node, function, visitAndPop(rhs));
- }
-
- @override
- void visitUnresolvedSet(ast.SendSet node, Element element, ast.Node rhs, _) {
- generateIsDeferredLoadedCheckOfSend(node);
- generateNonInstanceSetter(node, element, visitAndPop(rhs));
- }
-
- @override
- void visitClassTypeLiteralSet(
- ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
- generateThrowNoSuchMethod(node, constant.name,
- argumentNodes: node.arguments);
- }
-
- @override
- void visitTypedefTypeLiteralSet(
- ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
- generateThrowNoSuchMethod(node, constant.name,
- argumentNodes: node.arguments);
- }
-
- @override
- void visitDynamicTypeLiteralSet(
- ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
- generateThrowNoSuchMethod(node, constant.name,
- argumentNodes: node.arguments);
- }
-
- @override
- void visitTypeVariableTypeLiteralSet(
- ast.SendSet node, TypeVariableElement element, ast.Node rhs, _) {
- generateThrowNoSuchMethod(node, element.name,
- argumentNodes: node.arguments);
- }
-
- void handleCompoundSendSet(ast.SendSet node) {
- Element element = elements[node];
- Element getter = elements[node.selector];
-
- if (!Elements.isUnresolved(getter) && getter.impliesType) {
- if (node.isIfNullAssignment) {
- // C ??= x is compiled just as C.
- stack.add(addConstant(node.selector));
- } else {
- ast.Identifier selector = node.selector;
- generateThrowNoSuchMethod(node, selector.source,
- argumentNodes: node.arguments);
- }
- return;
- }
-
- if (Elements.isInstanceSend(node, elements)) {
- void generateAssignment(HInstruction receiver) {
- // desugars `e.x op= e2` to `e.x = e.x op e2`
- generateInstanceGetterWithCompiledReceiver(
- node,
- elements.getGetterSelectorInComplexSendSet(node),
- elementInferenceResults.typeOfGetter(node),
- receiver);
- HInstruction getterInstruction = pop();
- if (node.isIfNullAssignment) {
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleIfNull(() => stack.add(getterInstruction), () {
- visit(node.arguments.head);
- generateInstanceSetterWithCompiledReceiver(node, receiver, pop());
- });
- } else {
- handleComplexOperatorSend(node, getterInstruction, node.arguments);
- HInstruction value = pop();
- generateInstanceSetterWithCompiledReceiver(node, receiver, value);
- }
- if (node.isPostfix) {
- pop();
- stack.add(getterInstruction);
- }
- }
-
- if (node.isConditional) {
- // generate `e?.x op= e2` as:
- // t1 = e
- // t1 == null ? t1 : (t1.x = t1.x op e2);
- HInstruction receiver;
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleConditional(() {
- receiver = generateInstanceSendReceiver(node);
- pushCheckNull(receiver);
- }, () => stack.add(receiver), () => generateAssignment(receiver));
- } else {
- generateAssignment(generateInstanceSendReceiver(node));
- }
- return;
- }
-
- if (getter.isMalformed) {
- generateStaticUnresolvedGet(node, getter);
- } else if (getter.isField) {
- generateStaticFieldGet(node, getter);
- } else if (getter.isGetter) {
- generateStaticGetterGet(node, getter);
- } else if (getter.isFunction) {
- generateStaticFunctionGet(node, getter);
- } else if (getter.isLocal) {
- handleLocalGet(node, getter);
- } else {
- internalError(node, "Unexpected getter: $getter");
- }
- HInstruction getterInstruction = pop();
- if (node.isIfNullAssignment) {
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleIfNull(() => stack.add(getterInstruction), () {
- visit(node.arguments.head);
- generateNonInstanceSetter(node, element, pop());
- });
- } else {
- handleComplexOperatorSend(node, getterInstruction, node.arguments);
- HInstruction value = pop();
- generateNonInstanceSetter(node, element, value);
- }
- if (node.isPostfix) {
- pop();
- stack.add(getterInstruction);
- }
- }
-
- @override
- void handleDynamicCompounds(
- ast.Send node, ast.Node receiver, Name name, CompoundRhs rhs, _) {
- handleCompoundSendSet(node);
- }
-
- @override
- void handleLocalCompounds(
- ast.SendSet node, LocalElement local, CompoundRhs rhs, _,
- {bool isSetterValid}) {
- handleCompoundSendSet(node);
- }
-
- @override
- void handleStaticCompounds(
- ast.SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- CompoundRhs rhs,
- _) {
- handleCompoundSendSet(node);
- }
-
- @override
- handleDynamicSetIfNulls(
- ast.Send node, ast.Node receiver, Name name, ast.Node rhs, arg) {
- handleCompoundSendSet(node);
- }
-
- @override
- handleLocalSetIfNulls(ast.SendSet node, LocalElement local, ast.Node rhs, arg,
- {bool isSetterValid}) {
- handleCompoundSendSet(node);
- }
-
- @override
- handleStaticSetIfNulls(
- ast.SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- ast.Node rhs,
- arg) {
- handleCompoundSendSet(node);
- }
-
- @override
- handleSuperSetIfNulls(
- ast.SendSet node,
- Element getter,
- CompoundGetter getterKind,
- Element setter,
- CompoundSetter setterKind,
- ast.Node rhs,
- arg) {
- handleSuperSendSet(node);
- }
-
- @override
- handleSuperIndexSetIfNull(ast.SendSet node, Element indexFunction,
- Element indexSetFunction, ast.Node index, ast.Node rhs, arg,
- {bool isGetterValid, bool isSetterValid}) {
- handleCompoundSendSet(node);
- }
-
- @override
- visitIndexSetIfNull(
- ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, arg,
- {bool isGetterValid, bool isSetterValid}) {
- generateIsDeferredLoadedCheckOfSend(node);
- handleIndexSendSet(node);
- }
-
- @override
- handleTypeLiteralConstantSetIfNulls(
- ast.SendSet node, ConstantExpression constant, ast.Node rhs, arg) {
- // The type variable is never `null`.
- generateConstantTypeLiteral(node);
- }
-
- @override
- visitTypeVariableTypeLiteralSetIfNull(
- ast.Send node, TypeVariableElement element, ast.Node rhs, arg) {
- // The type variable is never `null`.
- generateTypeVariableLiteral(node, element.type);
- }
-
- void visitLiteralInt(ast.LiteralInt node) {
- stack.add(graph.addConstantInt(node.value, closedWorld));
- }
-
- void visitLiteralDouble(ast.LiteralDouble node) {
- stack.add(graph.addConstantDouble(node.value, closedWorld));
- }
-
- void visitLiteralBool(ast.LiteralBool node) {
- stack.add(graph.addConstantBool(node.value, closedWorld));
- }
-
- void visitLiteralString(ast.LiteralString node) {
- stack.add(
- graph.addConstantString(node.dartString.slowToString(), closedWorld));
- }
-
- void visitLiteralSymbol(ast.LiteralSymbol node) {
- stack.add(addConstant(node));
- registry?.registerConstSymbol(node.slowNameString);
- }
-
- void visitStringJuxtaposition(ast.StringJuxtaposition node) {
- if (!node.isInterpolation) {
- // This is a simple string with no interpolations.
- stack.add(
- graph.addConstantString(node.dartString.slowToString(), closedWorld));
- return;
- }
- StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
- stringBuilder.visit(node);
- stack.add(stringBuilder.result);
- }
-
- void visitLiteralNull(ast.LiteralNull node) {
- stack.add(graph.addConstantNull(closedWorld));
- }
-
- visitNodeList(ast.NodeList node) {
- for (Link<ast.Node> link = node.nodes; !link.isEmpty; link = link.tail) {
- if (isAborted()) {
- reporter.reportHintMessage(
- link.head, MessageKind.GENERIC, {'text': 'dead code'});
- } else {
- visit(link.head);
- }
- }
- }
-
- void visitParenthesizedExpression(ast.ParenthesizedExpression node) {
- visit(node.expression);
- }
-
- visitOperator(ast.Operator node) {
- // Operators are intercepted in their surrounding Send nodes.
- reporter.internalError(
- node, 'SsaBuilder.visitOperator should not be called.');
- }
-
- visitCascade(ast.Cascade node) {
- visit(node.expression);
- // Remove the result and reveal the duplicated receiver on the stack.
- pop();
- }
-
- visitCascadeReceiver(ast.CascadeReceiver node) {
- visit(node.expression);
- dup();
- }
-
- visitRethrow(ast.Rethrow node) {
- HInstruction exception = rethrowableException;
- if (exception == null) {
- exception = graph.addConstantNull(closedWorld);
- reporter.internalError(node, 'rethrowableException should not be null.');
- }
- handleInTryStatement();
- closeAndGotoExit(new HThrow(abstractValueDomain, exception,
- sourceInformationBuilder.buildThrow(node),
- isRethrow: true));
- }
-
- visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
- ConstructorElement targetConstructor =
- elements.getRedirectingTargetConstructor(node).implementation;
- ConstructorElement redirectingConstructor = sourceElement.implementation;
- List<HInstruction> inputs = <HInstruction>[];
- FunctionSignature targetSignature = targetConstructor.functionSignature;
- FunctionSignature redirectingSignature =
- redirectingConstructor.functionSignature;
-
- List<Element> targetRequireds = targetSignature.requiredParameters;
- List<Element> redirectingRequireds =
- redirectingSignature.requiredParameters;
-
- List<Element> targetOptionals = targetSignature.orderedOptionalParameters;
- List<Element> redirectingOptionals =
- redirectingSignature.orderedOptionalParameters;
-
- // TODO(25579): This code can do the wrong thing redirecting constructor and
- // the target do not correspond. It is correct if there is no
- // warning. Ideally the redirecting constructor and the target would be the
- // same function.
-
- void loadLocal(ParameterElement parameter) {
- inputs.add(localsHandler.readLocal(parameter));
- }
-
- void loadPosition(int position, ParameterElement optionalParameter) {
- if (position < redirectingRequireds.length) {
- loadLocal(redirectingRequireds[position]);
- } else if (position < redirectingSignature.parameterCount &&
- !redirectingSignature.optionalParametersAreNamed) {
- loadLocal(redirectingOptionals[position - redirectingRequireds.length]);
- } else if (optionalParameter != null) {
- inputs.add(handleConstantForOptionalParameter(optionalParameter));
- } else {
- // Wrong.
- inputs.add(graph.addConstantNull(closedWorld));
- }
- }
-
- int position = 0;
-
- for (ParameterElement _ in targetRequireds) {
- loadPosition(position++, null);
- }
-
- if (targetOptionals.isNotEmpty) {
- if (targetSignature.optionalParametersAreNamed) {
- for (ParameterElement parameter in targetOptionals) {
- ParameterElement redirectingParameter = redirectingOptionals
- .firstWhere((p) => p.name == parameter.name, orElse: () => null);
- if (redirectingParameter == null) {
- inputs.add(handleConstantForOptionalParameter(parameter));
- } else {
- inputs.add(localsHandler.readLocal(redirectingParameter));
- }
- }
- } else {
- for (ParameterElement parameter in targetOptionals) {
- loadPosition(position++, parameter);
- }
- }
- }
-
- ClassElement targetClass = targetConstructor.enclosingClass;
- if (rtiNeed.classNeedsTypeArguments(targetClass)) {
- ClassElement cls = redirectingConstructor.enclosingClass;
- ResolutionDartType targetType =
- redirectingConstructor.computeEffectiveTargetType(cls.thisType);
- targetType = localsHandler.substInContext(targetType);
- if (targetType is ResolutionInterfaceType) {
- targetType.typeArguments.forEach((ResolutionDartType argument) {
- inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
- });
- }
- }
- pushInvokeStatic(node, targetConstructor.declaration, inputs);
- HInstruction value = pop();
- emitReturn(value, node);
- }
-
- /// Returns true if the [type] is a valid return type for an asynchronous
- /// function.
- ///
- /// Asynchronous functions return a `Future`, and a valid return is thus
- /// either dynamic, Object, or Future.
- ///
- /// We do not accept the internal Future implementation class.
- bool isValidAsyncReturnType(ResolutionDartType type) {
- assert(isBuildingAsyncFunction);
- // TODO(sigurdm): In an internal library a function could be declared:
- //
- // _FutureImpl foo async => 1;
- //
- // This should be valid (because the actual value returned from an async
- // function is a `_FutureImpl`), but currently false is returned in this
- // case.
- return type.isDynamic ||
- type.isObject ||
- (type is ResolutionInterfaceType &&
- type.element == commonElements.futureClass);
- }
-
- visitReturn(ast.Return node) {
- if (identical(node.beginToken.stringValue, 'native')) {
- native.handleSsaNative(this, node.expression);
- return;
- }
- HInstruction value;
- if (node.expression == null) {
- value = graph.addConstantNull(closedWorld);
- } else {
- visit(node.expression);
- value = pop();
- if (isBuildingAsyncFunction) {
- if (options.enableTypeAssertions &&
- !isValidAsyncReturnType(returnType)) {
- String message = "Async function returned a Future, "
- "was declared to return a $returnType.";
- generateTypeError(node, message);
- pop();
- return;
- }
- } else {
- value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
- value, returnType);
- }
- }
-
- handleInTryStatement();
- emitReturn(value, node);
- }
-
- visitThrow(ast.Throw node) {
- visitThrowExpression(node.expression);
- if (isReachable) {
- handleInTryStatement();
- push(new HThrowExpression(abstractValueDomain, pop(),
- sourceInformationBuilder.buildThrow(node)));
- isReachable = false;
- }
- }
-
- visitYield(ast.Yield node) {
- visit(node.expression);
- HInstruction yielded = pop();
- add(new HYield(abstractValueDomain, yielded, node.hasStar,
- sourceInformationBuilder.buildYield(node)));
- }
-
- visitAwait(ast.Await node) {
- visit(node.expression);
- HInstruction awaited = pop();
- // TODO(herhut): Improve this type.
- push(new HAwait(
- awaited, new TypeMask.subclass(commonElements.objectClass, closedWorld))
- ..sourceInformation = sourceInformationBuilder.buildAwait(node));
- }
-
- visitTypeAnnotation(ast.TypeAnnotation node) {
- reporter.internalError(node, 'Visiting type annotation in SSA builder.');
- }
-
- visitVariableDefinitions(ast.VariableDefinitions node) {
- assert(isReachable);
- for (Link<ast.Node> link = node.definitions.nodes;
- !link.isEmpty;
- link = link.tail) {
- ast.Node definition = link.head;
- LocalElement local = elements[definition];
- if (definition is ast.Identifier) {
- HInstruction initialValue = graph.addConstantNull(closedWorld);
- localsHandler.updateLocal(local, initialValue);
- } else {
- ast.SendSet node = definition;
- generateNonInstanceSetter(
- node, local, visitAndPop(node.arguments.first));
- pop(); // Discard value.
- }
- }
- }
-
- HInstruction setRtiIfNeeded(
- HInstruction object, ast.Node node, SourceInformation sourceInformation) {
- ResolutionInterfaceType type =
- localsHandler.substInContext(elements.getType(node));
- if (!rtiNeed.classNeedsTypeArguments(type.element) || type.treatAsRaw) {
- return object;
- }
- List<HInstruction> arguments = <HInstruction>[];
- for (ResolutionDartType argument in type.typeArguments) {
- arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
- sourceInformation: sourceInformation));
- }
- // TODO(15489): Register at codegen.
- registry?.registerInstantiation(type);
- return callSetRuntimeTypeInfoWithTypeArguments(
- type, arguments, object, sourceInformation);
- }
-
- visitLiteralList(ast.LiteralList node) {
- HInstruction instruction;
-
- if (node.isConst) {
- instruction = addConstant(node);
- } else {
- List<HInstruction> inputs = <HInstruction>[];
- for (Link<ast.Node> link = node.elements.nodes;
- !link.isEmpty;
- link = link.tail) {
- visit(link.head);
- inputs.add(pop());
- }
- instruction = buildLiteralList(inputs);
- add(instruction);
- instruction = setRtiIfNeeded(
- instruction, node, sourceInformationBuilder.buildListLiteral(node));
- }
-
- TypeMask type = _inferredTypeOfListLiteral(node);
- if (!type.containsAll(closedWorld)) {
- instruction.instructionType = type;
- }
- stack.add(instruction);
- }
-
- _inferredTypeOfNewList(ast.Send node) =>
- _resultOf(sourceElement).typeOfNewList(node) ?? commonMasks.dynamicType;
-
- _inferredTypeOfListLiteral(ast.LiteralList node) =>
- _resultOf(sourceElement).typeOfListLiteral(node) ??
- commonMasks.dynamicType;
-
- visitConditional(ast.Conditional node) {
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
- brancher.handleConditional(() => visit(node.condition),
- () => visit(node.thenExpression), () => visit(node.elseExpression));
- }
-
- visitStringInterpolation(ast.StringInterpolation node) {
- StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
- stringBuilder.visit(node);
- stack.add(stringBuilder.result);
- }
-
- visitStringInterpolationPart(ast.StringInterpolationPart node) {
- // The parts are iterated in visitStringInterpolation.
- reporter.internalError(
- node, 'SsaBuilder.visitStringInterpolation should not be called.');
- }
-
- visitEmptyStatement(ast.EmptyStatement node) {
- // Do nothing, empty statement.
- }
-
- visitModifiers(ast.Modifiers node) {
- failedAt(node, 'SsaFromAstMixin.visitModifiers not implemented.');
- }
-
- visitBreakStatement(ast.BreakStatement node) {
- assert(!isAborted());
- handleInTryStatement();
- JumpTarget target = elements.getTargetOf(node);
- assert(target != null);
- JumpHandler handler = jumpTargets[target];
- assert(handler != null);
- if (node.target == null) {
- handler.generateBreak(sourceInformationBuilder.buildGoto(node));
- } else {
- LabelDefinition label = elements.getTargetLabel(node);
- handler.generateBreak(sourceInformationBuilder.buildGoto(node), label);
- }
- }
-
- visitContinueStatement(ast.ContinueStatement node) {
- handleInTryStatement();
- JumpTarget target = elements.getTargetOf(node);
- assert(target != null);
- JumpHandler handler = jumpTargets[target];
- assert(handler != null);
- if (node.target == null) {
- handler.generateContinue(sourceInformationBuilder.buildGoto(node));
- } else {
- LabelDefinition label = elements.getTargetLabel(node);
- assert(label != null);
- handler.generateContinue(sourceInformationBuilder.buildGoto(node), label);
- }
- }
-
- /**
- * Creates a [JumpHandler] for a statement. The node must be a jump
- * target. If there are no breaks or continues targeting the statement,
- * a special "null handler" is returned.
- *
- * [isLoopJump] is [:true:] when the jump handler is for a loop. This is used
- * to distinguish the synthesized loop created for a switch statement with
- * continue statements from simple switch statements.
- */
- JumpHandler createJumpHandler(ast.Statement node, JumpTarget jumpTarget,
- {bool isLoopJump}) {
- if (jumpTarget == null || !identical(jumpTarget.statement, node)) {
- // No breaks or continues to this node.
- return new NullJumpHandler(reporter);
- }
- if (isLoopJump && node is ast.SwitchStatement) {
- // Create a special jump handler for loops created for switch statements
- // with continue statements.
- return new AstSwitchCaseJumpHandler(this, jumpTarget, node);
- }
- return new JumpHandler(this, jumpTarget);
- }
-
- visitAsyncForIn(ast.AsyncForIn node) {
- // The async-for is implemented with a StreamIterator.
- HInstruction streamIterator;
-
- visit(node.expression);
- HInstruction expression = pop();
- ConstructorElement constructor = commonElements.streamIteratorConstructor;
- pushInvokeStatic(
- node, constructor, [expression, graph.addConstantNull(closedWorld)]);
- streamIterator = pop();
-
- void buildInitializer() {}
-
- HInstruction buildCondition() {
- Selector selector = Selectors.moveNext;
- TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node);
- pushInvokeDynamic(node, selector, mask, [streamIterator]);
- HInstruction future = pop();
- push(new HAwait(future,
- new TypeMask.subclass(commonElements.objectClass, closedWorld)));
- return popBoolified();
- }
-
- void buildBody() {
- Selector call = Selectors.current;
- TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node);
- pushInvokeDynamic(node, call, callMask, [streamIterator]);
-
- ast.Node identifier = node.declaredIdentifier;
- Element variable = elements.getForInVariable(node);
- Selector selector = elements.getSelector(identifier);
- HInstruction value = pop();
- if (identifier.asSend() != null &&
- Elements.isInstanceSend(identifier, elements)) {
- TypeMask mask = elementInferenceResults.typeOfSend(identifier);
- HInstruction receiver = generateInstanceSendReceiver(identifier);
- assert(receiver != null);
- generateInstanceSetterWithCompiledReceiver(null, receiver, value,
- selector: selector, mask: mask, location: identifier);
- } else {
- generateNonInstanceSetter(null, variable, value, location: identifier);
- }
- pop(); // Pop the value pushed by the setter call.
-
- visit(node.body);
- }
-
- void buildUpdate() {}
-
- buildProtectedByFinally(() {
- loopHandler.handleLoop(
- node,
- closureDataLookup.getCapturedLoopScope(node),
- elements.getTargetDefinition(node),
- buildInitializer,
- buildCondition,
- buildUpdate,
- buildBody,
- sourceInformationBuilder.buildLoop(node));
- }, () {
- pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]);
- add(new HAwait(pop(),
- new TypeMask.subclass(commonElements.objectClass, closedWorld)));
- });
- }
-
- visitSyncForIn(ast.SyncForIn node) {
- // The 'get iterator' selector for this node has the inferred receiver type.
- // If the receiver supports JavaScript indexing we generate an indexing loop
- // instead of allocating an iterator object.
-
- // This scheme recognizes for-in on direct lists. It does not recognize all
- // uses of ArrayIterator. They still occur when the receiver is an Iterable
- // with a `get iterator` method that delegates to another Iterable and the
- // method is inlined. We would require full scalar replacement in that
- // case.
-
- TypeMask mask = elementInferenceResults.typeOfIterator(node);
-
- if (mask != null &&
- mask.satisfies(commonElements.jsIndexableClass, closedWorld) &&
- // String is indexable but not iterable.
- !mask.satisfies(commonElements.jsStringClass, closedWorld)) {
- return buildSyncForInIndexable(node, mask);
- }
- buildSyncForInIterator(node);
- }
-
- buildSyncForInIterator(ast.SyncForIn node) {
- // Generate a structure equivalent to:
- // Iterator<E> $iter = <iterable>.iterator;
- // while ($iter.moveNext()) {
- // <declaredIdentifier> = $iter.current;
- // <body>
- // }
-
- // The iterator is shared between initializer, condition and body.
- HInstruction iterator;
-
- void buildInitializer() {
- Selector selector = Selectors.iterator;
- TypeMask mask = elementInferenceResults.typeOfIterator(node);
- visit(node.expression);
- HInstruction receiver = pop();
- pushInvokeDynamic(node, selector, mask, [receiver],
- sourceInformation: sourceInformationBuilder.buildForInIterator(node));
- iterator = pop();
- }
-
- HInstruction buildCondition() {
- Selector selector = Selectors.moveNext;
- TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node);
- pushInvokeDynamic(node, selector, mask, [iterator],
- sourceInformation: sourceInformationBuilder.buildForInMoveNext(node));
- return popBoolified();
- }
-
- void buildBody() {
- Selector call = Selectors.current;
- TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node);
- pushInvokeDynamic(node, call, mask, [iterator],
- sourceInformation: sourceInformationBuilder.buildForInCurrent(node));
- buildAssignLoopVariable(node, pop());
- visit(node.body);
- }
-
- loopHandler.handleLoop(
- node,
- closureDataLookup.getCapturedLoopScope(node),
- elements.getTargetDefinition(node),
- buildInitializer,
- buildCondition,
- () {},
- buildBody,
- sourceInformationBuilder.buildLoop(node));
- }
-
- buildAssignLoopVariable(ast.ForIn node, HInstruction value) {
- ast.Node identifier = node.declaredIdentifier;
- Element variable = elements.getForInVariable(node);
- Selector selector = elements.getSelector(identifier);
-
- if (identifier.asSend() != null &&
- Elements.isInstanceSend(identifier, elements)) {
- TypeMask mask = elementInferenceResults.typeOfSend(identifier);
- HInstruction receiver = generateInstanceSendReceiver(identifier);
- assert(receiver != null);
- generateInstanceSetterWithCompiledReceiver(null, receiver, value,
- selector: selector, mask: mask, location: identifier);
- } else {
- generateNonInstanceSetter(null, variable, value, location: identifier);
- }
- pop(); // Discard the value pushed by the setter call.
- }
-
- buildSyncForInIndexable(ast.ForIn node, TypeMask arrayType) {
- // Generate a structure equivalent to:
- //
- // int end = a.length;
- // for (int i = 0;
- // i < a.length;
- // checkConcurrentModificationError(a.length == end, a), ++i) {
- // <declaredIdentifier> = a[i];
- // <body>
- // }
- ExecutableElement loopVariable = elements.getForInVariable(node);
- SyntheticLocal indexVariable =
- new SyntheticLocal('_i', loopVariable, target);
- TypeMask boolType = commonMasks.boolType;
-
- // These variables are shared by initializer, condition, body and update.
- HInstruction array; // Set in buildInitializer.
- bool isFixed; // Set in buildInitializer.
- HInstruction originalLength = null; // Set for growable lists.
-
- HInstruction buildGetLength() {
- HInstruction result = new HGetLength(array, commonMasks.positiveIntType,
- isAssignable: !isFixed);
- add(result);
- return result;
- }
-
- void buildConcurrentModificationErrorCheck() {
- if (originalLength == null) return;
- // The static call checkConcurrentModificationError() is expanded in
- // codegen to:
- //
- // array.length == _end || throwConcurrentModificationError(array)
- //
- HInstruction length = buildGetLength();
- push(new HIdentity(length, originalLength, null, boolType));
- pushInvokeStatic(node, commonElements.checkConcurrentModificationError,
- [pop(), array]);
- pop();
- }
-
- void buildInitializer() {
- visit(node.expression);
- array = pop();
- isFixed = isFixedLength(array.instructionType, closedWorld);
- localsHandler.updateLocal(
- indexVariable, graph.addConstantInt(0, closedWorld));
- originalLength = buildGetLength();
- }
-
- HInstruction buildCondition() {
- HInstruction index = localsHandler.readLocal(indexVariable);
- HInstruction length = buildGetLength();
- HInstruction compare = new HLess(index, length, null, boolType);
- add(compare);
- return compare;
- }
-
- void buildBody() {
- // If we had mechanically inlined ArrayIterator.moveNext(), it would have
- // inserted the ConcurrentModificationError check as part of the
- // condition. It is not necessary on the first iteration since there is
- // no code between calls to `get iterator` and `moveNext`, so the test is
- // moved to the loop update.
-
- // Find a type for the element. Use the element type of the indexer of the
- // array, as this is stronger than the iterator's `get current` type, for
- // example, `get current` includes null.
- // TODO(sra): The element type of a container type mask might be better.
- Selector selector = new Selector.index();
- TypeMask type = TypeMaskFactory.inferredTypeForSelector(
- selector, arrayType, globalInferenceResults);
-
- HInstruction index = localsHandler.readLocal(indexVariable);
- HInstruction value = new HIndex(array, index, null, type);
- add(value);
-
- buildAssignLoopVariable(node, value);
- visit(node.body);
- }
-
- void buildUpdate() {
- // See buildBody as to why we check here.
- buildConcurrentModificationErrorCheck();
-
- // TODO(sra): It would be slightly shorter to generate `a[i++]` in the
- // body (and that more closely follows what an inlined iterator would do)
- // but the code is horrible as `i+1` is carried around the loop in an
- // additional variable.
- HInstruction index = localsHandler.readLocal(indexVariable);
- HInstruction one = graph.addConstantInt(1, closedWorld);
- HInstruction addInstruction =
- new HAdd(index, one, null, commonMasks.positiveIntType);
- add(addInstruction);
- localsHandler.updateLocal(indexVariable, addInstruction);
- }
-
- loopHandler.handleLoop(
- node,
- closureDataLookup.getCapturedLoopScope(node),
- elements.getTargetDefinition(node),
- buildInitializer,
- buildCondition,
- buildUpdate,
- buildBody,
- sourceInformationBuilder.buildLoop(node));
- }
-
- visitLabel(ast.Label node) {
- reporter.internalError(node, 'SsaFromAstMixin.visitLabel.');
- }
-
- visitLabeledStatement(ast.LabeledStatement node) {
- ast.Statement body = node.statement;
- if (body is ast.Loop ||
- body is ast.SwitchStatement ||
- Elements.isUnusedLabel(node, elements)) {
- // Loops and switches handle their own labels.
- visit(body);
- return;
- }
- JumpTarget targetElement = elements.getTargetDefinition(body);
- LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler);
- assert(targetElement.isBreakTarget);
- JumpHandler handler = new JumpHandler(this, targetElement);
- // Introduce a new basic block.
- HBasicBlock entryBlock = openNewBlock();
- visit(body);
- SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
-
- HBasicBlock joinBlock = graph.addNewBlock();
- List<LocalsHandler> breakHandlers = <LocalsHandler>[];
- handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
- breakInstruction.block.addSuccessor(joinBlock);
- breakHandlers.add(locals);
- });
- bool hasBreak = breakHandlers.length > 0;
- if (!isAborted()) {
- goto(current, joinBlock);
- breakHandlers.add(localsHandler);
- }
- open(joinBlock);
- localsHandler = beforeLocals.mergeMultiple(breakHandlers, joinBlock);
-
- if (hasBreak) {
- // There was at least one reachable break, so the label is needed.
- entryBlock.setBlockFlow(
- new HLabeledBlockInformation(
- new HSubGraphBlockInformation(bodyGraph), handler.labels),
- joinBlock);
- }
- handler.close();
- }
-
- visitLiteralMap(ast.LiteralMap node) {
- if (node.isConst) {
- stack.add(addConstant(node));
- return;
- }
- List<HInstruction> listInputs = <HInstruction>[];
- for (Link<ast.Node> link = node.entries.nodes;
- !link.isEmpty;
- link = link.tail) {
- visit(link.head);
- listInputs.add(pop());
- listInputs.add(pop());
- }
-
- ConstructorElement listConstructor;
- List<HInstruction> inputs = <HInstruction>[];
-
- if (listInputs.isEmpty) {
- listConstructor = commonElements.mapLiteralConstructorEmpty;
- } else {
- listConstructor = commonElements.mapLiteralConstructor;
- HLiteralList keyValuePairs = buildLiteralList(listInputs);
- add(keyValuePairs);
- inputs.add(keyValuePairs);
- }
-
- assert(listConstructor.isFactoryConstructor);
-
- ConstructorElement constructorElement = listConstructor;
- listConstructor = constructorElement.effectiveTarget;
-
- ResolutionInterfaceType type = elements.getType(node);
- ResolutionDartType expectedType =
- constructorElement.computeEffectiveTargetType(type);
- expectedType = localsHandler.substInContext(expectedType);
-
- ClassElement cls = listConstructor.enclosingClass;
-
- MethodElement createFunction = listConstructor;
- if (expectedType is ResolutionInterfaceType &&
- rtiNeed.classNeedsTypeArguments(cls)) {
- List<HInstruction> typeInputs = <HInstruction>[];
- expectedType.typeArguments.forEach((ResolutionDartType argument) {
- typeInputs
- .add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
- });
-
- // We lift this common call pattern into a helper function to save space
- // in the output.
- if (typeInputs
- .every((HInstruction input) => input.isNull(abstractValueDomain))) {
- if (listInputs.isEmpty) {
- createFunction = commonElements.mapLiteralUntypedEmptyMaker;
- } else {
- createFunction = commonElements.mapLiteralUntypedMaker;
- }
- } else {
- inputs.addAll(typeInputs);
- }
- }
-
- // If rti is needed and the map literal has no type parameters,
- // 'constructor' is a static function that forwards the call to the factory
- // constructor without type parameters.
- assert(createFunction is ConstructorElement ||
- createFunction is FunctionElement);
-
- // The instruction type will always be a subtype of the mapLiteralClass, but
- // type inference might discover a more specific type, or find nothing (in
- // dart2js unit tests).
- TypeMask mapType = new TypeMask.nonNullSubtype(
- commonElements.mapLiteralClass, closedWorld);
- TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
- createFunction, globalInferenceResults);
- TypeMask instructionType =
- mapType.intersection(returnTypeMask, closedWorld);
-
- addInlinedInstantiation(expectedType);
- pushInvokeStatic(node, createFunction, inputs,
- typeMask: instructionType, instanceType: expectedType);
- removeInlinedInstantiation(expectedType);
- }
-
- visitLiteralMapEntry(ast.LiteralMapEntry node) {
- visit(node.value);
- visit(node.key);
- }
-
- visitNamedArgument(ast.NamedArgument node) {
- visit(node.expression);
- }
-
- Map<ast.CaseMatch, ConstantValue> buildSwitchCaseConstants(
- ast.SwitchStatement node) {
- Map<ast.CaseMatch, ConstantValue> constants =
- new Map<ast.CaseMatch, ConstantValue>();
- for (ast.SwitchCase switchCase in node.cases) {
- for (ast.Node labelOrCase in switchCase.labelsAndCases) {
- if (labelOrCase is ast.CaseMatch) {
- ast.CaseMatch match = labelOrCase;
- ConstantValue constant = getConstantForNode(match.expression);
- constants[labelOrCase] = constant;
- }
- }
- }
- return constants;
- }
-
- visitSwitchStatement(ast.SwitchStatement node) {
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildSwitch(node);
- Map<ast.CaseMatch, ConstantValue> constants =
- buildSwitchCaseConstants(node);
-
- // The switch case indices must match those computed in
- // [SwitchCaseJumpHandler].
- bool hasContinue = false;
- Map<ast.SwitchCase, int> caseIndex = new Map<ast.SwitchCase, int>();
- int switchIndex = 1;
- bool hasDefault = false;
- for (ast.SwitchCase switchCase in node.cases) {
- for (ast.Node labelOrCase in switchCase.labelsAndCases) {
- ast.Node label = labelOrCase.asLabel();
- if (label != null) {
- LabelDefinition labelElement = elements.getLabelDefinition(label);
- if (labelElement != null && labelElement.isContinueTarget) {
- hasContinue = true;
- }
- }
- }
- if (switchCase.isDefaultCase) {
- hasDefault = true;
- }
- caseIndex[switchCase] = switchIndex;
- switchIndex++;
- }
- if (!hasContinue) {
- // If the switch statement has no switch cases targeted by continue
- // statements we encode the switch statement directly.
- buildSimpleSwitchStatement(node, constants, sourceInformation);
- } else {
- buildComplexSwitchStatement(
- node, constants, caseIndex, hasDefault, sourceInformation);
- }
- }
-
- /**
- * Builds a simple switch statement which does not handle uses of continue
- * statements to labeled switch cases.
- */
- void buildSimpleSwitchStatement(
- ast.SwitchStatement node,
- Map<ast.CaseMatch, ConstantValue> constants,
- SourceInformation sourceInformation) {
- JumpHandler jumpHandler = createJumpHandler(
- node, elements.getTargetDefinition(node),
- isLoopJump: false);
- HInstruction buildExpression() {
- visit(node.expression);
- return pop();
- }
-
- Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
- List<ConstantValue> constantList = <ConstantValue>[];
- for (ast.Node labelOrCase in switchCase.labelsAndCases) {
- if (labelOrCase is ast.CaseMatch) {
- constantList.add(constants[labelOrCase]);
- }
- }
- return constantList;
- }
-
- bool isDefaultCase(ast.SwitchCase switchCase) {
- return switchCase.isDefaultCase;
- }
-
- void buildSwitchCase(ast.SwitchCase node) {
- visit(node.statements);
- }
-
- handleSwitch(node, jumpHandler, buildExpression, node.cases, getConstants,
- isDefaultCase, buildSwitchCase, sourceInformation);
- jumpHandler.close();
- }
-
- /**
- * Builds a switch statement that can handle arbitrary uses of continue
- * statements to labeled switch cases.
- */
- void buildComplexSwitchStatement(
- ast.SwitchStatement node,
- Map<ast.CaseMatch, ConstantValue> constants,
- Map<ast.SwitchCase, int> caseIndex,
- bool hasDefault,
- SourceInformation sourceInformation) {
- // If the switch statement has switch cases targeted by continue
- // statements we create the following encoding:
- //
- // switch (e) {
- // l_1: case e0: s_1; break;
- // l_2: case e1: s_2; continue l_i;
- // ...
- // l_n: default: s_n; continue l_j;
- // }
- //
- // is encoded as
- //
- // var target;
- // switch (e) {
- // case e1: target = 1; break;
- // case e2: target = 2; break;
- // ...
- // default: target = n; break;
- // }
- // l: while (true) {
- // switch (target) {
- // case 1: s_1; break l;
- // case 2: s_2; target = i; continue l;
- // ...
- // case n: s_n; target = j; continue l;
- // }
- // }
-
- JumpTarget switchTarget = elements.getTargetDefinition(node);
- HInstruction initialValue = graph.addConstantNull(closedWorld);
- localsHandler.updateLocal(switchTarget, initialValue);
-
- JumpHandler jumpHandler =
- createJumpHandler(node, switchTarget, isLoopJump: false);
- dynamic switchCases = node.cases;
- if (!hasDefault) {
- // Use [:null:] as the marker for a synthetic default clause.
- // The synthetic default is added because otherwise, there would be no
- // good place to give a default value to the local.
- switchCases = node.cases.nodes.toList()..add(null);
- }
- HInstruction buildExpression() {
- visit(node.expression);
- return pop();
- }
-
- Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
- List<ConstantValue> constantList = <ConstantValue>[];
- if (switchCase != null) {
- for (ast.Node labelOrCase in switchCase.labelsAndCases) {
- if (labelOrCase is ast.CaseMatch) {
- constantList.add(constants[labelOrCase]);
- }
- }
- }
- return constantList;
- }
-
- bool isDefaultCase(ast.SwitchCase switchCase) {
- return switchCase == null || switchCase.isDefaultCase;
- }
-
- void buildSwitchCase(ast.SwitchCase switchCase) {
- SourceInformation caseSourceInformation = sourceInformation;
- if (switchCase != null) {
- caseSourceInformation = sourceInformationBuilder.buildGoto(switchCase);
- // Generate 'target = i; break;' for switch case i.
- int index = caseIndex[switchCase];
- HInstruction value = graph.addConstantInt(index, closedWorld);
- localsHandler.updateLocal(switchTarget, value,
- sourceInformation: caseSourceInformation);
- } else {
- // Generate synthetic default case 'target = null; break;'.
- HInstruction value = graph.addConstantNull(closedWorld);
- localsHandler.updateLocal(switchTarget, value,
- sourceInformation: caseSourceInformation);
- }
- jumpTargets[switchTarget].generateBreak(caseSourceInformation);
- }
-
- handleSwitch(node, jumpHandler, buildExpression, switchCases, getConstants,
- isDefaultCase, buildSwitchCase, sourceInformation);
- jumpHandler.close();
-
- HInstruction buildCondition() => graph.addConstantBool(true, closedWorld);
-
- void buildSwitch() {
- HInstruction buildExpression() {
- return localsHandler.readLocal(switchTarget);
- }
-
- Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
- return <ConstantValue>[constantSystem.createInt(caseIndex[switchCase])];
- }
-
- void buildSwitchCase(ast.SwitchCase switchCase) {
- visit(switchCase.statements);
- if (!isAborted()) {
- // Ensure that we break the loop if the case falls through. (This
- // is only possible for the last case.)
- jumpTargets[switchTarget].generateBreak(sourceInformation);
- }
- }
-
- // Pass a [NullJumpHandler] because the target for the contained break
- // is not the generated switch statement but instead the loop generated
- // in the call to [handleLoop] below.
- handleSwitch(
- node,
- new NullJumpHandler(reporter),
- buildExpression,
- node.cases,
- getConstants,
- (_) => false, // No case is default.
- buildSwitchCase,
- sourceInformation);
- }
-
- void buildLoop() {
- loopHandler.handleLoop(
- node,
- closureDataLookup.getCapturedLoopScope(node),
- switchTarget,
- () {},
- buildCondition,
- () {},
- buildSwitch,
- sourceInformationBuilder.buildLoop(node));
- }
-
- if (hasDefault) {
- buildLoop();
- } else {
- // If the switch statement has no default case, surround the loop with
- // a test of the target.
- void buildCondition() {
- js.Template code = js.js.parseForeignJS('#');
- push(new HForeignCode(
- code, commonMasks.boolType, [localsHandler.readLocal(switchTarget)],
- nativeBehavior: native.NativeBehavior.PURE));
- }
-
- handleIf(
- node: node,
- visitCondition: buildCondition,
- visitThen: buildLoop,
- visitElse: () => {},
- sourceInformation: sourceInformation);
- }
- }
-
- /**
- * Creates a switch statement.
- *
- * [jumpHandler] is the [JumpHandler] for the created switch statement.
- * [buildExpression] creates the switch expression.
- * [switchCases] must be either an [Iterable] of [ast.SwitchCase] nodes or
- * a [Link] or a [ast.NodeList] of [ast.SwitchCase] nodes.
- * [getConstants] returns the set of constants for a switch case.
- * [isDefaultCase] returns true if the provided switch case should be
- * considered default for the created switch statement.
- * [buildSwitchCase] creates the statements for the switch case.
- */
- void handleSwitch(
- ast.Node errorNode,
- JumpHandler jumpHandler,
- HInstruction buildExpression(),
- var switchCases,
- Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase),
- bool isDefaultCase(ast.SwitchCase switchCase),
- void buildSwitchCase(ast.SwitchCase switchCase),
- SourceInformation sourceInformation) {
- HBasicBlock expressionStart = openNewBlock();
- HInstruction expression = buildExpression();
- if (switchCases.isEmpty) {
- return;
- }
-
- HSwitch switchInstruction =
- new HSwitch(abstractValueDomain, <HInstruction>[expression]);
- HBasicBlock expressionEnd = close(switchInstruction);
- LocalsHandler savedLocals = localsHandler;
-
- List<HStatementInformation> statements = <HStatementInformation>[];
- bool hasDefault = false;
- HasNextIterator<ast.Node> caseIterator =
- new HasNextIterator<ast.Node>(switchCases.iterator);
- while (caseIterator.hasNext) {
- ast.SwitchCase switchCase = caseIterator.next();
- HBasicBlock block = graph.addNewBlock();
- for (ConstantValue constant in getConstants(switchCase)) {
- HConstant hConstant = graph.addConstant(constant, closedWorld);
- switchInstruction.inputs.add(hConstant);
- hConstant.usedBy.add(switchInstruction);
- expressionEnd.addSuccessor(block);
- }
-
- if (isDefaultCase(switchCase)) {
- // An HSwitch has n inputs and n+1 successors, the last being the
- // default case.
- expressionEnd.addSuccessor(block);
- hasDefault = true;
- }
- open(block);
- localsHandler = new LocalsHandler.from(savedLocals);
- buildSwitchCase(switchCase);
- if (!isAborted()) {
- if (caseIterator.hasNext && isReachable) {
- pushInvokeStatic(switchCase, commonElements.fallThroughError, []);
- HInstruction error = pop();
- closeAndGotoExit(
- new HThrow(abstractValueDomain, error, error.sourceInformation));
- } else if (!isDefaultCase(switchCase)) {
- // If there is no default, we will add one later to avoid
- // the critical edge. So we generate a break statement to make
- // sure the last case does not fall through to the default case.
- jumpHandler.generateBreak(sourceInformation);
- }
- }
- statements.add(
- new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock)));
- }
-
- // Add a join-block if necessary.
- // We create [joinBlock] early, and then go through the cases that might
- // want to jump to it. In each case, if we add [joinBlock] as a successor
- // of another block, we also add an element to [caseHandlers] that is used
- // to create the phis in [joinBlock].
- // If we never jump to the join block, [caseHandlers] will stay empty, and
- // the join block is never added to the graph.
- HBasicBlock joinBlock = new HBasicBlock();
- List<LocalsHandler> caseHandlers = <LocalsHandler>[];
- jumpHandler.forEachBreak((HBreak instruction, LocalsHandler locals) {
- instruction.block.addSuccessor(joinBlock);
- caseHandlers.add(locals);
- });
- jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) {
- assert(false, failedAt(errorNode, 'Continue cannot target a switch.'));
- });
- if (!isAborted()) {
- current.close(new HGoto(abstractValueDomain));
- lastOpenedBlock.addSuccessor(joinBlock);
- caseHandlers.add(localsHandler);
- }
- if (!hasDefault) {
- // Always create a default case, to avoid a critical edge in the
- // graph.
- HBasicBlock defaultCase = addNewBlock();
- expressionEnd.addSuccessor(defaultCase);
- open(defaultCase);
- close(new HGoto(abstractValueDomain));
- defaultCase.addSuccessor(joinBlock);
- caseHandlers.add(savedLocals);
- statements.add(new HSubGraphBlockInformation(
- new SubGraph(defaultCase, defaultCase)));
- }
- assert(caseHandlers.length == joinBlock.predecessors.length);
- if (caseHandlers.length != 0) {
- graph.addBlock(joinBlock);
- open(joinBlock);
- if (caseHandlers.length == 1) {
- localsHandler = caseHandlers[0];
- } else {
- localsHandler = savedLocals.mergeMultiple(caseHandlers, joinBlock);
- }
- } else {
- // The joinblock is not used.
- joinBlock = null;
- }
-
- HSubExpressionBlockInformation expressionInfo =
- new HSubExpressionBlockInformation(
- new SubExpression(expressionStart, expressionEnd));
- expressionStart.setBlockFlow(
- new HSwitchBlockInformation(expressionInfo, statements,
- jumpHandler.target, jumpHandler.labels, sourceInformation),
- joinBlock);
-
- jumpHandler.close();
- }
-
- visitSwitchCase(ast.SwitchCase node) {
- reporter.internalError(node, 'SsaFromAstMixin.visitSwitchCase.');
- }
-
- visitCaseMatch(ast.CaseMatch node) {
- reporter.internalError(node, 'SsaFromAstMixin.visitCaseMatch.');
- }
-
- /// Calls [buildTry] inside a synthetic try block with [buildFinally] in the
- /// finally block.
- ///
- /// Note that to get the right locals behavior, the code visited by [buildTry]
- /// and [buildFinally] must have been analyzed as if inside a try-statement by
- /// [ClosureTranslator].
- void buildProtectedByFinally(void buildTry(), void buildFinally()) {
- // Save the current locals. The finally block must not reuse the existing
- // locals handler. None of the variables that have been defined in the
- // body-block will be used, but for loops we will add (unnecessary) phis
- // that will reference the body variables. This makes it look as if the
- // variables were used in a non-dominated block.
- LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
- HBasicBlock enterBlock = openNewBlock();
- HTry tryInstruction = new HTry(abstractValueDomain);
- close(tryInstruction);
- bool oldInTryStatement = inTryStatement;
- inTryStatement = true;
-
- HBasicBlock startTryBlock;
- HBasicBlock endTryBlock;
- HBasicBlock startFinallyBlock;
- HBasicBlock endFinallyBlock;
-
- startTryBlock = graph.addNewBlock();
- open(startTryBlock);
- buildTry();
- // We use a [HExitTry] instead of a [HGoto] for the try block
- // because it will have two successors: the join block, and
- // the finally block.
- if (!isAborted()) endTryBlock = close(new HExitTry(abstractValueDomain));
- SubGraph bodyGraph = new SubGraph(startTryBlock, lastOpenedBlock);
-
- SubGraph finallyGraph = null;
-
- localsHandler = new LocalsHandler.from(savedLocals);
- startFinallyBlock = graph.addNewBlock();
- open(startFinallyBlock);
- buildFinally();
- if (!isAborted()) endFinallyBlock = close(new HGoto(abstractValueDomain));
- tryInstruction.finallyBlock = startFinallyBlock;
- finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock);
-
- HBasicBlock exitBlock = graph.addNewBlock();
-
- void addExitTrySuccessor(HBasicBlock successor) {
- // Iterate over all blocks created inside this try/catch, and
- // attach successor information to blocks that end with
- // [HExitTry].
- for (int i = startTryBlock.id; i < successor.id; i++) {
- HBasicBlock block = graph.blocks[i];
- var last = block.last;
- if (last is HExitTry) {
- block.addSuccessor(successor);
- }
- }
- }
-
- // Setup all successors. The entry block that contains the [HTry]
- // has 1) the body 2) the finally, and 4) the exit
- // blocks as successors.
- enterBlock.addSuccessor(startTryBlock);
- enterBlock.addSuccessor(startFinallyBlock);
- enterBlock.addSuccessor(exitBlock);
-
- // The body has the finally block as successor.
- if (endTryBlock != null) {
- endTryBlock.addSuccessor(startFinallyBlock);
- endTryBlock.addSuccessor(exitBlock);
- }
-
- // The finally block has the exit block as successor.
- endFinallyBlock.addSuccessor(exitBlock);
-
- // If a block inside try/catch aborts (eg with a return statement),
- // we explicitly mark this block a predecessor of the catch
- // block and the finally block.
- addExitTrySuccessor(startFinallyBlock);
-
- // Use the locals handler not altered by the catch and finally
- // blocks.
- // TODO(sigurdm): We can probably do this, because try-variables are boxed.
- // Need to verify.
- localsHandler = savedLocals;
- open(exitBlock);
- enterBlock.setBlockFlow(
- new HTryBlockInformation(
- wrapStatementGraph(bodyGraph),
- null, // No catch-variable.
- null, // No catchGraph.
- wrapStatementGraph(finallyGraph)),
- exitBlock);
- inTryStatement = oldInTryStatement;
- }
-
- visitTryStatement(ast.TryStatement node) {
- // Save the current locals. The catch block and the finally block
- // must not reuse the existing locals handler. None of the variables
- // that have been defined in the body-block will be used, but for
- // loops we will add (unnecessary) phis that will reference the body
- // variables. This makes it look as if the variables were used
- // in a non-dominated block.
- LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
- HBasicBlock enterBlock = openNewBlock();
- HTry tryInstruction = new HTry(abstractValueDomain);
- close(tryInstruction);
- bool oldInTryStatement = inTryStatement;
- inTryStatement = true;
-
- HBasicBlock startTryBlock;
- HBasicBlock endTryBlock;
- HBasicBlock startCatchBlock;
- HBasicBlock endCatchBlock;
- HBasicBlock startFinallyBlock;
- HBasicBlock endFinallyBlock;
-
- startTryBlock = graph.addNewBlock();
- open(startTryBlock);
- visit(node.tryBlock);
- // We use a [HExitTry] instead of a [HGoto] for the try block
- // because it will have multiple successors: the join block, and
- // the catch or finally block.
- if (!isAborted()) endTryBlock = close(new HExitTry(abstractValueDomain));
- SubGraph bodyGraph = new SubGraph(startTryBlock, lastOpenedBlock);
- SubGraph catchGraph = null;
- HLocalValue exception = null;
-
- if (!node.catchBlocks.isEmpty) {
- localsHandler = new LocalsHandler.from(savedLocals);
- startCatchBlock = graph.addNewBlock();
- open(startCatchBlock);
- // Note that the name of this local is irrelevant.
- SyntheticLocal local = localsHandler.createLocal('exception');
- SourceInformation trySourceInformation =
- sourceInformationBuilder.buildTry(node);
- exception = new HLocalValue(local, commonMasks.nonNullType)
- ..sourceInformation = trySourceInformation;
- add(exception);
- HInstruction oldRethrowableException = rethrowableException;
- rethrowableException = exception;
-
- pushInvokeStatic(node, commonElements.exceptionUnwrapper, [exception],
- sourceInformation: trySourceInformation);
- HInvokeStatic unwrappedException = pop();
- tryInstruction.exception = exception;
- Link<ast.Node> link = node.catchBlocks.nodes;
-
- void pushCondition(ast.CatchBlock catchBlock) {
- if (catchBlock.onKeyword != null) {
- ResolutionDartType type = elements.getType(catchBlock.type);
- if (type == null) {
- reporter.internalError(catchBlock.type, 'On with no type.');
- }
- HInstruction condition = buildIsNode(
- catchBlock.type,
- type,
- unwrappedException,
- sourceInformationBuilder.buildCatch(catchBlock.type));
- push(condition);
- } else {
- ast.VariableDefinitions declaration = catchBlock.formals.nodes.head;
- HInstruction condition = null;
- if (declaration.type == null) {
- condition = graph.addConstantBool(true, closedWorld);
- stack.add(condition);
- } else {
- // TODO(aprelev@gmail.com): Once old catch syntax is removed
- // "if" condition above and this "else" branch should be deleted as
- // type of declared variable won't matter for the catch
- // condition.
- ResolutionDartType type = elements.getType(declaration.type);
- if (type == null) {
- reporter.internalError(catchBlock, 'Catch with unresolved type.');
- }
- condition = buildIsNode(declaration.type, type, unwrappedException,
- sourceInformationBuilder.buildCatch(declaration));
- push(condition);
- }
- }
- }
-
- void visitThen() {
- ast.CatchBlock catchBlock = link.head;
- link = link.tail;
- if (catchBlock.exception != null) {
- LocalVariableElement exceptionVariable =
- elements[catchBlock.exception];
- localsHandler.updateLocal(exceptionVariable, unwrappedException,
- sourceInformation:
- sourceInformationBuilder.buildCatch(catchBlock.exception));
- }
- ast.Node trace = catchBlock.trace;
- if (trace != null) {
- pushInvokeStatic(
- trace, commonElements.traceFromException, [exception]);
- HInstruction traceInstruction = pop();
- LocalVariableElement traceVariable = elements[trace];
- localsHandler.updateLocal(traceVariable, traceInstruction);
- }
- visit(catchBlock);
- }
-
- void visitElse() {
- if (link.isEmpty) {
- closeAndGotoExit(new HThrow(
- abstractValueDomain, exception, exception.sourceInformation,
- isRethrow: true));
- } else {
- ast.CatchBlock newBlock = link.head;
- handleIf(
- node: node,
- visitCondition: () {
- pushCondition(newBlock);
- },
- visitThen: visitThen,
- visitElse: visitElse,
- sourceInformation: sourceInformationBuilder.buildCatch(newBlock));
- }
- }
-
- ast.CatchBlock firstBlock = link.head;
- handleIf(
- node: node,
- visitCondition: () {
- pushCondition(firstBlock);
- },
- visitThen: visitThen,
- visitElse: visitElse,
- sourceInformation: sourceInformationBuilder.buildCatch(firstBlock));
- if (!isAborted()) endCatchBlock = close(new HGoto(abstractValueDomain));
-
- rethrowableException = oldRethrowableException;
- tryInstruction.catchBlock = startCatchBlock;
- catchGraph = new SubGraph(startCatchBlock, lastOpenedBlock);
- }
-
- SubGraph finallyGraph = null;
- if (node.finallyBlock != null) {
- localsHandler = new LocalsHandler.from(savedLocals);
- startFinallyBlock = graph.addNewBlock();
- open(startFinallyBlock);
- visit(node.finallyBlock);
- if (!isAborted()) endFinallyBlock = close(new HGoto(abstractValueDomain));
- tryInstruction.finallyBlock = startFinallyBlock;
- finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock);
- }
-
- HBasicBlock exitBlock = graph.addNewBlock();
-
- addOptionalSuccessor(b1, b2) {
- if (b2 != null) b1.addSuccessor(b2);
- }
-
- addExitTrySuccessor(successor) {
- if (successor == null) return;
- // Iterate over all blocks created inside this try/catch, and
- // attach successor information to blocks that end with
- // [HExitTry].
- for (int i = startTryBlock.id; i < successor.id; i++) {
- HBasicBlock block = graph.blocks[i];
- var last = block.last;
- if (last is HExitTry) {
- block.addSuccessor(successor);
- }
- }
- }
-
- // Setup all successors. The entry block that contains the [HTry]
- // has 1) the body, 2) the catch, 3) the finally, and 4) the exit
- // blocks as successors.
- enterBlock.addSuccessor(startTryBlock);
- addOptionalSuccessor(enterBlock, startCatchBlock);
- addOptionalSuccessor(enterBlock, startFinallyBlock);
- enterBlock.addSuccessor(exitBlock);
-
- // The body has either the catch or the finally block as successor.
- if (endTryBlock != null) {
- assert(startCatchBlock != null || startFinallyBlock != null);
- endTryBlock.addSuccessor(
- startCatchBlock != null ? startCatchBlock : startFinallyBlock);
- endTryBlock.addSuccessor(exitBlock);
- }
-
- // The catch block has either the finally or the exit block as
- // successor.
- if (endCatchBlock != null) {
- endCatchBlock.addSuccessor(
- startFinallyBlock != null ? startFinallyBlock : exitBlock);
- }
-
- // The finally block has the exit block as successor.
- if (endFinallyBlock != null) {
- endFinallyBlock.addSuccessor(exitBlock);
- }
-
- // If a block inside try/catch aborts (eg with a return statement),
- // we explicitly mark this block a predecessor of the catch
- // block and the finally block.
- addExitTrySuccessor(startCatchBlock);
- addExitTrySuccessor(startFinallyBlock);
-
- // Use the locals handler not altered by the catch and finally
- // blocks.
- localsHandler = savedLocals;
- open(exitBlock);
- enterBlock.setBlockFlow(
- new HTryBlockInformation(wrapStatementGraph(bodyGraph), exception,
- wrapStatementGraph(catchGraph), wrapStatementGraph(finallyGraph)),
- exitBlock);
- inTryStatement = oldInTryStatement;
- }
-
- visitCatchBlock(ast.CatchBlock node) {
- visit(node.block);
- }
-
- visitTypedef(ast.Typedef node) {
- failedAt(node, 'SsaFromAstMixin.visitTypedef not implemented.');
- }
-
- visitTypeVariable(ast.TypeVariable node) {
- failedAt(node, 'SsaFromAstMixin.visitTypeVariable not implemented.');
- }
-
- /**
- * This method is invoked before inlining the body of [function] into this
- * [SsaBuilder].
- */
- void enterInlinedMethod(
- MethodElement function,
- ResolvedAst functionResolvedAst,
- List<HInstruction> compiledArguments,
- ResolutionInterfaceType instanceType) {
- AstInliningState state = new AstInliningState(
- function,
- returnLocal,
- returnType,
- resolvedAst,
- stack,
- localsHandler,
- inTryStatement,
- isCalledOnce(functionResolvedAst.element),
- elementInferenceResults);
- resolvedAst = functionResolvedAst;
- elementInferenceResults = _resultOf(functionResolvedAst.element);
- inliningStack.add(state);
-
- // Setting up the state of the (AST) builder is performed even when the
- // inlined function is in IR, because the irInliner uses the [returnElement]
- // of the AST builder.
- setupStateForInlining(function, compiledArguments,
- instanceType: instanceType);
- }
-
- void leaveInlinedMethod() {
- HInstruction result = localsHandler.readLocal(returnLocal);
- AstInliningState state = inliningStack.removeLast();
- restoreState(state);
- stack.add(result);
- }
-
- void doInline(ResolvedAst resolvedAst) {
- visitInlinedFunction(resolvedAst);
- }
-
- void emitReturn(HInstruction value, ast.Node node) {
- if (inliningStack.isEmpty) {
- closeAndGotoExit(new HReturn(abstractValueDomain, value,
- sourceInformationBuilder.buildReturn(node)));
- } else {
- localsHandler.updateLocal(returnLocal, value);
- }
- }
-
- @override
- void handleTypeLiteralConstantCompounds(
- ast.SendSet node, ConstantExpression constant, CompoundRhs rhs, _) {
- handleTypeLiteralCompound(node);
- }
-
- @override
- void handleTypeVariableTypeLiteralCompounds(
- ast.SendSet node, TypeVariableElement typeVariable, CompoundRhs rhs, _) {
- handleTypeLiteralCompound(node);
- }
-
- void handleTypeLiteralCompound(ast.SendSet node) {
- generateIsDeferredLoadedCheckOfSend(node);
- ast.Identifier selector = node.selector;
- generateThrowNoSuchMethod(node, selector.source,
- argumentNodes: node.arguments);
- }
-
- @override
- void visitConstantGet(ast.Send node, ConstantExpression constant, _) {
- visitNode(node);
- }
-
- @override
- void visitConstantInvoke(ast.Send node, ConstantExpression constant,
- ast.NodeList arguments, CallStructure callStreucture, _) {
- visitNode(node);
- }
-
- @override
- void errorUndefinedBinaryExpression(
- ast.Send node, ast.Node left, ast.Operator operator, ast.Node right, _) {
- visitNode(node);
- }
-
- @override
- void errorUndefinedUnaryExpression(
- ast.Send node, ast.Operator operator, ast.Node expression, _) {
- visitNode(node);
- }
-
- @override
- void bulkHandleError(ast.Node node, ErroneousElement error, _) {
- // TODO(johnniwinther): Use an uncatchable error when supported.
- generateRuntimeError(node, error.message);
- }
-}
-
-/**
- * Visitor that handles generation of string literals (LiteralString,
- * StringInterpolation), and otherwise delegates to the given visitor for
- * non-literal subexpressions.
- */
-class StringBuilderVisitor extends ast.Visitor {
- final SsaAstGraphBuilder builder;
- final ast.Node diagnosticNode;
-
- /**
- * The string value generated so far.
- */
- HInstruction result = null;
-
- StringBuilderVisitor(this.builder, this.diagnosticNode);
-
- void visit(ast.Node node) {
- node.accept(this);
- }
-
- visitNode(ast.Node node) {
- builder.reporter.internalError(node, 'Unexpected node.');
- }
-
- void visitExpression(ast.Node node) {
- node.accept(builder);
- HInstruction expression = builder.pop();
-
- // We want to use HStringify when:
- // 1. The value is known to be a primitive type, because it might get
- // constant-folded and codegen has some tricks with JavaScript
- // conversions.
- // 2. The value can be primitive, because the library stringifier has
- // fast-path code for most primitives.
- if (expression.canBePrimitive(builder.abstractValueDomain)) {
- append(stringify(node, expression));
- return;
- }
-
- // If the `toString` method is guaranteed to return a string we can call it
- // directly.
- Selector selector = Selectors.toString_;
- TypeMask type = TypeMaskFactory.inferredTypeForSelector(
- selector, expression.instructionType, builder.globalInferenceResults);
- if (type.containsOnlyString(builder.closedWorld)) {
- builder.pushInvokeDynamic(node, selector, expression.instructionType,
- <HInstruction>[expression]);
- append(builder.pop());
- return;
- }
-
- append(stringify(node, expression));
- }
-
- void visitStringInterpolation(ast.StringInterpolation node) {
- node.visitChildren(this);
- }
-
- void visitStringInterpolationPart(ast.StringInterpolationPart node) {
- visit(node.expression);
- visit(node.string);
- }
-
- void visitStringJuxtaposition(ast.StringJuxtaposition node) {
- node.visitChildren(this);
- }
-
- void visitNodeList(ast.NodeList node) {
- node.visitChildren(this);
- }
-
- void append(HInstruction expression) {
- result = (result == null) ? expression : concat(result, expression);
- }
-
- HInstruction concat(HInstruction left, HInstruction right) {
- HInstruction instruction =
- new HStringConcat(left, right, builder.commonMasks.stringType);
- builder.add(instruction);
- return instruction;
- }
-
- HInstruction stringify(ast.Node node, HInstruction expression) {
- HInstruction instruction =
- new HStringify(expression, builder.commonMasks.stringType)
- ..sourceInformation = expression.sourceInformation;
- builder.add(instruction);
- return instruction;
- }
-}
-
-/**
- * This class visits the method that is a candidate for inlining and
- * finds whether it is too difficult to inline.
- */
-// TODO(karlklose): refactor to make it possible to distinguish between
-// implementation restrictions (for example, we *can't* inline multiple returns)
-// and heuristics (we *shouldn't* inline large functions).
-class InlineWeeder extends ast.Visitor {
- // Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP*
- static const INLINING_NODES_OUTSIDE_LOOP = 18;
- static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3;
- static const INLINING_NODES_INSIDE_LOOP = 42;
- static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4;
-
- bool seenReturn = false;
- String tooDifficultReason;
- int nodeCount = 0;
- final int maxInliningNodes; // `null` for unbounded.
- final bool allowLoops;
- final bool enableUserAssertions;
- final TreeElements elements;
-
- InlineWeeder._(this.elements, this.maxInliningNodes, this.allowLoops,
- this.enableUserAssertions);
-
- bool get tooDifficult => tooDifficultReason != null;
-
- static bool canBeInlined(ResolvedAst resolvedAst, int maxInliningNodes,
- {bool allowLoops: false, bool enableUserAssertions: null}) {
- return cannotBeInlinedReason(resolvedAst, maxInliningNodes,
- allowLoops: allowLoops,
- enableUserAssertions: enableUserAssertions) ==
- null;
- }
-
- static String cannotBeInlinedReason(
- ResolvedAst resolvedAst, int maxInliningNodes,
- {bool allowLoops: false, bool enableUserAssertions: null}) {
- assert(enableUserAssertions is bool); // Ensure we passed it.
- if (resolvedAst.elements.containsTryStatement) return 'try';
-
- InlineWeeder weeder = new InlineWeeder._(resolvedAst.elements,
- maxInliningNodes, allowLoops, enableUserAssertions);
- ast.FunctionExpression functionExpression = resolvedAst.node;
-
- weeder.visit(functionExpression.initializers);
- weeder.visit(functionExpression.body);
- weeder.visit(functionExpression.asyncModifier);
- return weeder.tooDifficultReason;
- }
-
- bool registerNode() {
- if (maxInliningNodes == null) return true;
- if (nodeCount++ > maxInliningNodes) {
- tooDifficultReason = 'too many nodes';
- return false;
- } else {
- return true;
- }
- }
-
- void visit(ast.Node node) {
- if (node != null) node.accept(this);
- }
-
- void visitNode(ast.Node node) {
- if (!registerNode()) return;
- if (seenReturn) {
- tooDifficultReason = 'code after return';
- } else {
- node.visitChildren(this);
- }
- }
-
- @override
- void visitAssert(ast.Assert node) {
- if (enableUserAssertions) {
- visitNode(node);
- }
- }
-
- @override
- void visitAsyncModifier(ast.AsyncModifier node) {
- if (node.isYielding || node.isAsynchronous) {
- tooDifficultReason = 'async/await';
- }
- }
-
- void visitFunctionExpression(ast.Node node) {
- if (!registerNode()) return;
- tooDifficultReason = 'closure';
- }
-
- void visitFunctionDeclaration(ast.Node node) {
- if (!registerNode()) return;
- tooDifficultReason = 'closure';
- }
-
- void visitSend(ast.Send node) {
- // TODO(sra): Investigate following, and possibly count occurrences, since
- // repeated references might cause a temporary to be assigned.
- //
- // Element element = elements[node];
- // if (element != null && element.isParameter) {
- // // Don't count as additional node, since it's likely that passing
- // // the argument would cost us as much space as we inline.
- // return;
- // }
- if (!registerNode()) return;
- node.visitChildren(this);
- }
-
- visitLoop(ast.Node node) {
- // It's actually not difficult to inline a method with a loop, but
- // our measurements show that it's currently better to not inline a
- // method that contains a loop.
- if (!allowLoops) {
- tooDifficultReason = 'loop';
- }
- }
-
- void visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
- if (!registerNode()) return;
- tooDifficultReason = 'redirecting factory';
- }
-
- void visitConditional(ast.Conditional node) {
- // Heuristic: In "parameter ? A : B" there is a high probability that
- // parameter is a constant. Assuming the parameter is constant, we can
- // compute a count that is bounded by the largest arm rather than the sum of
- // both arms.
- visit(node.condition);
- if (tooDifficult) return;
- int commonPrefixCount = nodeCount;
-
- visit(node.thenExpression);
- if (tooDifficult) return;
- int thenCount = nodeCount - commonPrefixCount;
-
- nodeCount = commonPrefixCount;
- visit(node.elseExpression);
- if (tooDifficult) return;
- int elseCount = nodeCount - commonPrefixCount;
-
- nodeCount = commonPrefixCount + thenCount + elseCount;
- if (node.condition.asSend() != null &&
- elements[node.condition]?.isParameter == true) {
- nodeCount =
- commonPrefixCount + (thenCount > elseCount ? thenCount : elseCount);
- }
- // This is last so that [tooDifficult] is always updated.
- if (!registerNode()) return;
- }
-
- void visitRethrow(ast.Rethrow node) {
- if (!registerNode()) return;
- tooDifficultReason = 'rethrow';
- }
-
- void visitReturn(ast.Return node) {
- if (!registerNode()) return;
- if (seenReturn || identical(node.beginToken.stringValue, 'native')) {
- tooDifficultReason = 'code after return';
- return;
- }
- node.visitChildren(this);
- seenReturn = true;
- }
-
- void visitThrow(ast.Throw node) {
- if (!registerNode()) return;
- // For now, we don't want to handle throw after a return even if
- // it is in an "if".
- if (seenReturn) {
- tooDifficultReason = 'code after return';
- } else {
- node.visitChildren(this);
- }
- }
-}
-
-abstract class InliningState {
- /**
- * Invariant: [function] must be an implementation element.
- */
- final MethodElement function;
-
- InliningState(this.function) {
- assert(function.isImplementation);
- }
-}
-
-class AstInliningState extends InliningState {
- final Local oldReturnLocal;
- final ResolutionDartType oldReturnType;
- final ResolvedAst oldResolvedAst;
- final List<HInstruction> oldStack;
- final LocalsHandler oldLocalsHandler;
- final bool inTryStatement;
- final bool allFunctionsCalledOnce;
- final GlobalTypeInferenceElementResult oldElementInferenceResults;
-
- AstInliningState(
- MethodElement function,
- this.oldReturnLocal,
- this.oldReturnType,
- this.oldResolvedAst,
- this.oldStack,
- this.oldLocalsHandler,
- this.inTryStatement,
- this.allFunctionsCalledOnce,
- this.oldElementInferenceResults)
- : super(function);
-}
-
-class AstTypeBuilder extends TypeBuilder {
- AstTypeBuilder(GraphBuilder builder) : super(builder);
-
- ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member) {
- bool isClosure = member.enclosingClass.isClosure;
- if (isClosure) {
- ClosureClassElement closureClass = member.enclosingClass;
- LocalFunctionElement localFunction = closureClass.methodElement;
- member = localFunction.memberContext;
- }
- bool isInConstructorContext =
- member.isConstructor || member is ConstructorBodyEntity;
- if (isClosure) {
- if ((member is ConstructorEntity && member.isFactoryConstructor) ||
- (isInConstructorContext)) {
- // The type variable is used from a closure in a factory constructor.
- // The value of the type argument is stored as a local on the closure
- // itself.
- return ClassTypeVariableAccess.parameter;
- } else if (member.isFunction ||
- member.isGetter ||
- member.isSetter ||
- isInConstructorContext) {
- // The type variable is stored on the "enclosing object" and needs to be
- // accessed using the this-reference in the closure.
- return ClassTypeVariableAccess.property;
- } else {
- assert(member.isField);
- // The type variable is stored in a parameter of the method.
- return ClassTypeVariableAccess.parameter;
- }
- } else if (isInConstructorContext) {
- // The type variable is stored in a parameter of the method.
- return ClassTypeVariableAccess.parameter;
- } else if (member.isInstanceMember) {
- if (member.isField) {
- // The type variable is stored in a parameter or on `this` depending
- // on the context.
- return ClassTypeVariableAccess.instanceField;
- } else {
- // The type variable is stored on the object.
- return ClassTypeVariableAccess.property;
- }
- } else {
- return ClassTypeVariableAccess.none;
- }
- }
-
- /// In checked mode, generate type tests for the parameters of the inlined
- /// function.
- void potentiallyCheckInlinedParameterTypes(covariant MethodElement function) {
- if (!checkOrTrustTypes) return;
-
- FunctionSignature signature = function.functionSignature;
- signature.forEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- HInstruction argument = builder.localsHandler.readLocal(parameter);
- potentiallyCheckOrTrustTypeOfParameter(argument, parameter.type);
- });
- }
-}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 6836904..26834cf 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -17,11 +17,8 @@
StringConstantValue,
TypeConstantValue;
import '../dump_info.dart';
-import '../elements/elements.dart' show ErroneousElement;
import '../elements/entities.dart';
import '../elements/jumps.dart';
-import '../elements/resolution_types.dart'
- show MalformedType, MethodTypeVariableType;
import '../elements/types.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
@@ -34,7 +31,6 @@
import '../kernel/element_map.dart';
import '../kernel/kernel_backend_strategy.dart';
import '../native/native.dart' as native;
-import '../resolution/tree_elements.dart';
import '../types/masks.dart';
import '../types/types.dart';
import '../universe/call_structure.dart';
@@ -97,10 +93,6 @@
@override
JavaScriptBackend get backend => compiler.backend;
- @override
- TreeElements get elements =>
- throw new UnsupportedError('KernelSsaGraphBuilder.elements');
-
final SourceInformationStrategy<ir.Node> _sourceInformationStrategy;
final KernelToElementMapForBuilding _elementMap;
final GlobalTypeInferenceResults _globalInferenceResults;
@@ -335,7 +327,7 @@
// Use dynamic type because the type computed by the inferrer is
// narrowed to the type annotation.
HInstruction parameter =
- new HParameterValue(field, commonMasks.dynamicType);
+ new HParameterValue(field, abstractValueDomain.dynamicType);
// Add the parameter as the last instruction of the entry block.
// If the method is intercepted, we want the actual receiver
// to be the first parameter.
@@ -377,7 +369,7 @@
return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type,
kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
}
- HInstruction result = new HBoolify(value, commonMasks.boolType);
+ HInstruction result = new HBoolify(value, abstractValueDomain.boolType);
add(result);
return result;
}
@@ -400,7 +392,8 @@
TypeVariableType typeVariableType = _typeVariable;
HInstruction param;
if (needsTypeArguments) {
- param = addParameter(typeVariableType.element, commonMasks.nonNullType);
+ param = addParameter(
+ typeVariableType.element, abstractValueDomain.nonNullType);
} else {
// Unused, so bind to `dynamic`.
param = graph.addConstantNull(closedWorld);
@@ -428,7 +421,8 @@
typeVariables.forEach((TypeVariableType typeVariableType) {
HInstruction param;
if (needsTypeArguments) {
- param = addParameter(typeVariableType.element, commonMasks.nonNullType);
+ param = addParameter(
+ typeVariableType.element, abstractValueDomain.nonNullType);
} else {
// Unused, so bind to `dynamic`.
param = graph.addConstantNull(closedWorld);
@@ -515,7 +509,7 @@
// Null guard ensures an error if we are being called from an explicit
// 'new' of the constructor instead of via an upgrade. It is optimized out
// if there are field initializers.
- add(new HFieldGet(null, newObject, commonMasks.dynamicType,
+ add(new HFieldGet(null, newObject, abstractValueDomain.dynamicType,
isAssignable: false));
for (int i = 0; i < fields.length; i++) {
add(new HFieldSet(abstractValueDomain, fields[i], newObject,
@@ -541,7 +535,7 @@
TypeInfoExpressionKind.INSTANCE,
thisType,
typeArguments,
- commonMasks.dynamicType);
+ abstractValueDomain.dynamicType);
add(typeInfo);
constructorArguments.add(typeInfo);
}
@@ -645,8 +639,8 @@
void _invokeConstructorBody(ir.Constructor constructor,
List<HInstruction> inputs, SourceInformation sourceInformation) {
MemberEntity constructorBody = _elementMap.getConstructorBody(constructor);
- HInvokeConstructorBody invoke = new HInvokeConstructorBody(
- constructorBody, inputs, commonMasks.nonNullType, sourceInformation);
+ HInvokeConstructorBody invoke = new HInvokeConstructorBody(constructorBody,
+ inputs, abstractValueDomain.nonNullType, sourceInformation);
add(invoke);
}
@@ -941,7 +935,7 @@
TypeInfoExpressionKind.COMPLETE,
_elementMap.getFunctionType(originalClosureNode),
typeArguments,
- commonMasks.functionType));
+ abstractValueDomain.functionType));
HInstruction value = pop();
close(new HReturn(abstractValueDomain, value,
_sourceInformationBuilder.buildReturn(originalClosureNode)))
@@ -978,7 +972,7 @@
visitCondition: () {
HParameterValue parameter = parameters.values.first;
push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
- null, commonMasks.boolType));
+ null, abstractValueDomain.boolType));
},
visitThen: () {
closeAndGotoExit(new HReturn(
@@ -990,10 +984,35 @@
sourceInformation: _sourceInformationBuilder.buildIf(functionNode));
}
}
+ if (const bool.fromEnvironment('unreachable-throw')) {
+ var emptyParameters = parameters.values
+ .where((p) => abstractValueDomain.isEmpty(p.instructionType));
+ if (emptyParameters.length > 0) {
+ addComment('${emptyParameters} inferred as [empty]');
+ add(new HInvokeStatic(
+ commonElements.assertUnreachableMethod,
+ <HInstruction>[],
+ abstractValueDomain.dynamicType,
+ const <DartType>[]));
+ closeFunction();
+ return;
+ }
+ }
functionNode.body.accept(this);
closeFunction();
}
+ /// Adds a JavaScript comment to the output. The comment will be omitted in
+ /// minified mode. Each line in [text] is preceded with `//` and indented.
+ /// Use sparingly. In order for the comment to be retained it is modeled as
+ /// having side effects which will inhibit code motion.
+ // TODO(sra): Figure out how to keep comment anchored without effects.
+ void addComment(String text) {
+ add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)),
+ abstractValueDomain.dynamicType, <HInstruction>[],
+ isStatement: true));
+ }
+
/// Builds a SSA graph for a sync*/async/async* generator.
void buildGenerator(FunctionEntity function, ir.FunctionNode functionNode) {
// TODO(sra): Optimize by generating a merged entry + body when (1) there
@@ -1047,7 +1066,7 @@
push(new HInvokeGeneratorBody(
body,
inputs,
- commonMasks.dynamicType, // TODO: better type.
+ abstractValueDomain.dynamicType, // TODO: better type.
sourceInformation));
closeAndGotoExit(
@@ -1071,6 +1090,9 @@
// because that is where the type guards will also be inserted.
// This way we ensure that a type guard will dominate the type
// check.
+
+ checkTypeVariableBounds(targetElement);
+
MemberDefinition definition =
_elementMap.getMemberDefinition(targetElement);
bool nodeIsConstructorBody = definition.kind == MemberKind.constructorBody;
@@ -1092,8 +1114,6 @@
function.positionalParameters.forEach(_handleParameter);
function.namedParameters.toList()..forEach(_handleParameter);
-
- checkTypeVariableBounds(targetElement);
}
void checkTypeVariableBounds(FunctionEntity method) {
@@ -1157,7 +1177,7 @@
_pushStaticInvocation(
_commonElements.closureConverter,
[argument, graph.addConstantInt(arity, closedWorld)],
- commonMasks.dynamicType,
+ abstractValueDomain.dynamicType,
const <DartType>[]);
argument = pop();
}
@@ -1167,7 +1187,7 @@
String arguments = templateArguments.join(',');
// TODO(sra): Use declared type or NativeBehavior type.
- TypeMask typeMask = commonMasks.dynamicType;
+ TypeMask typeMask = abstractValueDomain.dynamicType;
String template;
if (targetElement.isGetter) {
template = '${templateReceiver}$nativeName';
@@ -1265,8 +1285,10 @@
void _trap(String message) {
HInstruction nullValue = graph.addConstantNull(closedWorld);
HInstruction errorMessage = graph.addConstantString(message, closedWorld);
- HInstruction trap = new HForeignCode(js.js.parseForeignJS("#.#"),
- commonMasks.dynamicType, <HInstruction>[nullValue, errorMessage]);
+ HInstruction trap = new HForeignCode(
+ js.js.parseForeignJS("#.#"),
+ abstractValueDomain.dynamicType,
+ <HInstruction>[nullValue, errorMessage]);
trap.sideEffects
..setAllSideEffects()
..setDependsOnSomething();
@@ -1307,7 +1329,7 @@
push(new HInvokeStatic(
commonElements.loadDeferredLibrary,
[graph.addConstantString(loadId, closedWorld)],
- commonMasks.nonNullType,
+ abstractValueDomain.nonNullType,
const <DartType>[],
targetCanThrow: false));
}
@@ -1482,7 +1504,8 @@
HInstruction originalLength = null; // Set for growable lists.
HInstruction buildGetLength(SourceInformation sourceInformation) {
- HGetLength result = new HGetLength(array, commonMasks.positiveIntType,
+ HGetLength result = new HGetLength(
+ array, abstractValueDomain.positiveIntType,
isAssignable: !isFixed)
..sourceInformation = sourceInformation;
add(result);
@@ -1499,7 +1522,8 @@
SourceInformation sourceInformation =
_sourceInformationBuilder.buildForInMoveNext(node);
HInstruction length = buildGetLength(sourceInformation);
- push(new HIdentity(length, originalLength, null, commonMasks.boolType)
+ push(new HIdentity(
+ length, originalLength, null, abstractValueDomain.boolType)
..sourceInformation = sourceInformation);
_pushStaticInvocation(
_commonElements.checkConcurrentModificationError,
@@ -1532,7 +1556,7 @@
sourceInformation: sourceInformation);
HInstruction length = buildGetLength(sourceInformation);
HInstruction compare =
- new HLess(index, length, null, commonMasks.boolType)
+ new HLess(index, length, null, abstractValueDomain.boolType)
..sourceInformation = sourceInformation;
add(compare);
return compare;
@@ -1584,7 +1608,7 @@
sourceInformation: sourceInformation);
HInstruction one = graph.addConstantInt(1, closedWorld);
HInstruction addInstruction =
- new HAdd(index, one, null, commonMasks.positiveIntType)
+ new HAdd(index, one, null, abstractValueDomain.positiveIntType)
..sourceInformation = sourceInformation;
add(addInstruction);
localsHandler.updateLocal(indexVariable, addInstruction,
@@ -1759,7 +1783,7 @@
FunctionEntity typeInfoSetterFn = _commonElements.setRuntimeTypeInfo;
// TODO(efortuna): Insert source information in this static invocation.
_pushStaticInvocation(typeInfoSetterFn, <HInstruction>[newObject, typeInfo],
- commonMasks.dynamicType, const <DartType>[],
+ abstractValueDomain.dynamicType, const <DartType>[],
sourceInformation: sourceInformation);
// The new object will now be referenced through the
@@ -1972,17 +1996,7 @@
}
DartType type = _elementMap.getDartType(node.type);
- if (type.isMalformed) {
- // TODO(johnniwinther): This branch is no longer needed.
- if (type is MalformedType) {
- ErroneousElement element = type.element;
- generateTypeError(element.message, sourceInformation);
- } else {
- assert(type is MethodTypeVariableType);
- stack.add(expressionInstruction);
- }
- } else if (!node.isTypeError ||
- options.implicitDowncastCheckPolicy.isEmitted) {
+ if (!node.isTypeError || options.implicitDowncastCheckPolicy.isEmitted) {
HInstruction converted = typeBuilder.buildTypeConversion(
expressionInstruction,
localsHandler.substInContext(type),
@@ -2394,8 +2408,8 @@
// null, so we don't drop into the while loop.
void buildCondition() {
js.Template code = js.js.parseForeignJS('#');
- push(new HForeignCode(
- code, commonMasks.boolType, [localsHandler.readLocal(switchTarget)],
+ push(new HForeignCode(code, abstractValueDomain.boolType,
+ [localsHandler.readLocal(switchTarget)],
nativeBehavior: native.NativeBehavior.PURE));
}
@@ -2773,8 +2787,11 @@
HInstruction value = typeBuilder.analyzeTypeArgument(
dartType, sourceElement,
sourceInformation: sourceInformation);
- _pushStaticInvocation(_commonElements.runtimeTypeToString,
- <HInstruction>[value], commonMasks.stringType, const <DartType>[],
+ _pushStaticInvocation(
+ _commonElements.runtimeTypeToString,
+ <HInstruction>[value],
+ abstractValueDomain.stringType,
+ const <DartType>[],
sourceInformation: sourceInformation);
_pushStaticInvocation(
_commonElements.createRuntimeType,
@@ -3291,7 +3308,7 @@
return globalInferenceResults
.resultOfMember(element)
.typeOfNewList(node) ??
- commonMasks.dynamicType;
+ abstractValueDomain.dynamicType;
}
if (isFixedListConstructorCall) {
@@ -3307,7 +3324,7 @@
HTypeConversion conversion = new HTypeConversion(
null,
HTypeConversion.ARGUMENT_TYPE_CHECK,
- commonMasks.numType,
+ abstractValueDomain.numType,
lengthInput,
sourceInformation);
add(conversion);
@@ -3331,8 +3348,8 @@
}
var inferredType = _inferredTypeOfNewList(invocation);
- resultType = inferredType.containsAll(closedWorld)
- ? commonMasks.fixedListType
+ resultType = abstractValueDomain.containsAll(inferredType)
+ ? abstractValueDomain.fixedListType
: inferredType;
HForeignCode foreign = new HForeignCode(
code, resultType, <HInstruction>[lengthInput],
@@ -3349,14 +3366,14 @@
js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
// We set the instruction as [canThrow] to avoid it being dead code.
// We need a finer grained side effect.
- add(new HForeignCode(code, commonMasks.nullType, [stack.last],
+ add(new HForeignCode(code, abstractValueDomain.nullType, [stack.last],
throwBehavior: native.NativeThrowBehavior.MAY));
}
} else if (isGrowableListConstructorCall) {
push(buildLiteralList(<HInstruction>[]));
var inferredType = _inferredTypeOfNewList(invocation);
- resultType = inferredType.containsAll(closedWorld)
- ? commonMasks.growableListType
+ resultType = abstractValueDomain.containsAll(inferredType)
+ ? abstractValueDomain.growableListType
: inferredType;
stack.last.instructionType = resultType;
} else if (isJSArrayTypedConstructor) {
@@ -3459,7 +3476,7 @@
TypeVariableType variable = _typeVariable;
typeArguments.add(variable);
HInstruction readType = new HTypeInfoReadVariable.intercepted(
- variable, interceptor, object, commonMasks.dynamicType);
+ variable, interceptor, object, abstractValueDomain.dynamicType);
add(readType);
inputs.add(readType);
});
@@ -3470,7 +3487,7 @@
Selector selector =
new Selector.callClosure(0, const <String>[], typeArguments.length);
push(new HInvokeClosure(
- selector, inputs, commonMasks.dynamicType, typeArguments));
+ selector, inputs, abstractValueDomain.dynamicType, typeArguments));
return true;
}
@@ -3480,10 +3497,6 @@
String name = target.name.name;
if (name == 'JS') {
handleForeignJs(invocation);
- } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
- // TODO(sigmund): delete. The only reference left to this foreign function
- // is from the deprecated dart:mirrors code.
- handleForeignJsCurrentIsolateContext(invocation);
} else if (name == 'DART_CLOSURE_TO_JS') {
handleForeignDartClosureToJs(invocation, 'DART_CLOSURE_TO_JS');
} else if (name == 'RAW_DART_FUNCTION_REF') {
@@ -3588,22 +3601,6 @@
return stringConstant.stringValue;
}
- void handleForeignJsCurrentIsolateContext(ir.StaticInvocation invocation) {
- if (_unexpectedForeignArguments(invocation,
- minPositional: 0, maxPositional: 0)) {
- // Result expected on stack.
- stack.add(graph.addConstantNull(closedWorld));
- return;
- }
-
- // Isolates cannot be spawned, so we just generate code to fetch the static
- // state.
- String name = namer.staticStateHolder;
- push(new HForeignCode(
- js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
- nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
- }
-
void handleForeignDartClosureToJs(
ir.StaticInvocation invocation, String name) {
// TODO(sra): Do we need to wrap the closure in something that saves the
@@ -3634,7 +3631,7 @@
push(new HForeignCode(
js.js.expressionTemplateYielding(emitter
.staticFunctionAccess(_elementMap.getMethod(staticTarget))),
- commonMasks.dynamicType,
+ abstractValueDomain.dynamicType,
<HInstruction>[],
nativeBehavior: native.NativeBehavior.PURE,
foreignFunction: _elementMap.getMethod(staticTarget)));
@@ -3667,7 +3664,7 @@
SideEffects sideEffects = new SideEffects.empty();
sideEffects.setAllSideEffects();
push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
- commonMasks.dynamicType, inputs,
+ abstractValueDomain.dynamicType, inputs,
nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
effects: sideEffects));
}
@@ -3681,7 +3678,7 @@
}
push(new HForeignCode(js.js.parseForeignJS(namer.staticStateHolder),
- commonMasks.dynamicType, <HInstruction>[],
+ abstractValueDomain.dynamicType, <HInstruction>[],
nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
}
@@ -3918,7 +3915,8 @@
return;
}
List<HInstruction> inputs = _visitPositionalArguments(invocation.arguments);
- push(new HStringConcat(inputs[0], inputs[1], commonMasks.stringType));
+ push(new HStringConcat(
+ inputs[0], inputs[1], abstractValueDomain.stringType));
}
void _pushStaticInvocation(MemberEntity target, List<HInstruction> arguments,
@@ -4068,14 +4066,14 @@
}
// TODO(efortuna): Source information.
return new HForeignCode(
- codeTemplate, commonMasks.dynamicType, filteredArguments,
+ codeTemplate, abstractValueDomain.dynamicType, filteredArguments,
nativeBehavior: nativeBehavior);
}
var target = new HForeignCode(
js.js.parseForeignJS("${nativeData.getFixedBackendMethodPath(element)}."
"${nativeData.getFixedBackendName(element)}"),
- commonMasks.dynamicType,
+ abstractValueDomain.dynamicType,
<HInstruction>[]);
add(target);
// Strip off trailing arguments that were not specified.
@@ -4125,7 +4123,8 @@
nativeBehavior.codeTemplate = codeTemplate;
// TODO(efortuna): Add source information.
- return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs,
+ return new HForeignCode(
+ codeTemplate, abstractValueDomain.dynamicType, inputs,
nativeBehavior: nativeBehavior);
}
@@ -4186,7 +4185,7 @@
return;
}
HInstruction instruction = new HInvokeStatic(
- target, arguments, commonMasks.functionType, <DartType>[],
+ target, arguments, abstractValueDomain.functionType, <DartType>[],
targetCanThrow: targetCanThrow);
// TODO(sra): ..sourceInformation = sourceInformation
instruction.sideEffects
@@ -4225,7 +4224,7 @@
HInterceptor _interceptorFor(
HInstruction intercepted, SourceInformation sourceInformation) {
HInterceptor interceptor =
- new HInterceptor(intercepted, commonMasks.nonNullType)
+ new HInterceptor(intercepted, abstractValueDomain.nonNullType)
..sourceInformation = sourceInformation;
add(interceptor);
return interceptor;
@@ -4291,7 +4290,7 @@
argumentNamesInstruction,
graph.addConstantInt(typeArguments.length, closedWorld),
],
- commonMasks.dynamicType,
+ abstractValueDomain.dynamicType,
typeArguments);
_buildInvokeSuper(Selectors.noSuchMethod_, containingClass, noSuchMethod,
@@ -4589,11 +4588,11 @@
representation,
];
_pushStaticInvocation(_commonElements.functionTypeTest, inputs,
- commonMasks.boolType, const <DartType>[],
+ abstractValueDomain.boolType, const <DartType>[],
sourceInformation: sourceInformation);
HInstruction call = pop();
- push(new HIs.compound(typeValue, expression, call, commonMasks.boolType,
- sourceInformation));
+ push(new HIs.compound(typeValue, expression, call,
+ abstractValueDomain.boolType, sourceInformation));
return;
}
@@ -4605,11 +4604,11 @@
representation,
];
_pushStaticInvocation(_commonElements.futureOrTest, inputs,
- commonMasks.boolType, const <DartType>[],
+ abstractValueDomain.boolType, const <DartType>[],
sourceInformation: sourceInformation);
HInstruction call = pop();
- push(new HIs.compound(typeValue, expression, call, commonMasks.boolType,
- sourceInformation));
+ push(new HIs.compound(typeValue, expression, call,
+ abstractValueDomain.boolType, sourceInformation));
return;
}
@@ -4619,11 +4618,11 @@
_pushStaticInvocation(
_commonElements.checkSubtypeOfRuntimeType,
<HInstruction>[expression, runtimeType],
- commonMasks.boolType,
+ abstractValueDomain.boolType,
const <DartType>[],
sourceInformation: sourceInformation);
- push(new HIs.variable(typeValue, expression, pop(), commonMasks.boolType,
- sourceInformation));
+ push(new HIs.variable(typeValue, expression, pop(),
+ abstractValueDomain.boolType, sourceInformation));
return;
}
@@ -4648,16 +4647,16 @@
asFieldName
];
_pushStaticInvocation(_commonElements.checkSubtype, inputs,
- commonMasks.boolType, const <DartType>[],
+ abstractValueDomain.boolType, const <DartType>[],
sourceInformation: sourceInformation);
- push(new HIs.compound(typeValue, expression, pop(), commonMasks.boolType,
- sourceInformation));
+ push(new HIs.compound(typeValue, expression, pop(),
+ abstractValueDomain.boolType, sourceInformation));
return;
}
if (backend.hasDirectCheckFor(closedWorld.commonElements, typeValue)) {
- push(new HIs.direct(
- typeValue, expression, commonMasks.boolType, sourceInformation));
+ push(new HIs.direct(typeValue, expression, abstractValueDomain.boolType,
+ sourceInformation));
return;
}
// The interceptor is not always needed. It is removed by optimization
@@ -4666,7 +4665,7 @@
typeValue,
expression,
_interceptorFor(expression, sourceInformation),
- commonMasks.boolType,
+ abstractValueDomain.boolType,
sourceInformation));
return;
}
@@ -4736,7 +4735,7 @@
@override
void visitNot(ir.Not node) {
node.operand.accept(this);
- push(new HNot(popBoolified(), commonMasks.boolType)
+ push(new HNot(popBoolified(), abstractValueDomain.boolType)
..sourceInformation = _sourceInformationBuilder.buildUnary(node));
}
@@ -4969,7 +4968,8 @@
if (function.isInstanceMember &&
function is! ConstructorBodyEntity &&
(mask == null || mask.isNullable)) {
- add(new HFieldGet(null, providedArguments[0], commonMasks.dynamicType,
+ add(new HFieldGet(
+ null, providedArguments[0], abstractValueDomain.dynamicType,
isAssignable: false)
..sourceInformation = sourceInformation);
}
@@ -5259,7 +5259,7 @@
/// Run this builder on the body of the [function] to be inlined.
void _visitInlinedFunction(FunctionEntity function) {
- typeBuilder.potentiallyCheckInlinedParameterTypes(function);
+ _potentiallyCheckInlinedParameterTypes(function);
MemberDefinition definition = _elementMap.getMemberDefinition(function);
switch (definition.kind) {
@@ -5296,6 +5296,44 @@
failedAt(function, "Unexpected inlined function: $definition");
}
+ /// Generates type tests for the parameters of the inlined function.
+ void _potentiallyCheckInlinedParameterTypes(FunctionEntity function) {
+ if (!typeBuilder.checkOrTrustTypes) return;
+
+ // TODO(sra): Incorporate properties of call site to help determine which
+ // type parameters and value parameters need to be checked.
+ bool trusted = false;
+ if (options.strongMode) {
+ if (function.isStatic ||
+ function.isTopLevel ||
+ function.isConstructor ||
+ function is ConstructorBodyEntity) {
+ // We inline static methods, top-level methods, constructors and
+ // constructor bodies only from direct call sites.
+ trusted = true;
+ }
+ }
+
+ if (!trusted) {
+ checkTypeVariableBounds(function);
+ }
+
+ KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(function);
+ forEachOrderedParameter(_globalLocalsMap, _elementMap, function,
+ (Local parameter) {
+ HInstruction argument = localsHandler.readLocal(parameter);
+ DartType type = localsMap.getLocalType(_elementMap, parameter);
+ HInstruction checkedOrTrusted;
+ if (trusted) {
+ checkedOrTrusted = typeBuilder.trustTypeOfParameter(argument, type);
+ } else {
+ checkedOrTrusted =
+ typeBuilder.potentiallyCheckOrTrustTypeOfParameter(argument, type);
+ }
+ localsHandler.updateLocal(parameter, checkedOrTrusted);
+ });
+ }
+
bool get _allInlinedFunctionsCalledOnce {
return _inliningStack.isEmpty || _inliningStack.last.allFunctionsCalledOnce;
}
@@ -5320,7 +5358,7 @@
add(new HInvokeStatic(
commonElements.traceHelper,
<HInstruction>[nameConstant],
- commonMasks.dynamicType,
+ abstractValueDomain.dynamicType,
const <DartType>[]));
}
}
@@ -5336,7 +5374,7 @@
add(new HInvokeStatic(
commonElements.traceHelper,
<HInstruction>[idConstant, nameConstant],
- commonMasks.dynamicType,
+ abstractValueDomain.dynamicType,
const <DartType>[]));
}
}
@@ -5696,8 +5734,9 @@
kernelBuilder.open(startCatchBlock);
// Note that the name of this local is irrelevant.
SyntheticLocal local = kernelBuilder.localsHandler.createLocal('exception');
- exception = new HLocalValue(local, kernelBuilder.commonMasks.nonNullType)
- ..sourceInformation = trySourceInformation;
+ exception =
+ new HLocalValue(local, kernelBuilder.abstractValueDomain.nonNullType)
+ ..sourceInformation = trySourceInformation;
kernelBuilder.add(exception);
HInstruction oldRethrowableException = kernelBuilder.rethrowableException;
kernelBuilder.rethrowableException = exception;
@@ -5818,21 +5857,6 @@
ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member) {
return _elementMap.getClassTypeVariableAccessForMember(member);
}
-
- /// In checked mode, generate type tests for the parameters of the inlined
- /// function.
- void potentiallyCheckInlinedParameterTypes(FunctionEntity function) {
- if (!checkOrTrustTypes) return;
-
- KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(function);
- forEachOrderedParameter(_globalLocalsMap, _elementMap, function,
- (Local parameter) {
- HInstruction argument = builder.localsHandler.readLocal(parameter);
- potentiallyCheckOrTrustTypeOfParameter(
- argument, localsMap.getLocalType(_elementMap, parameter));
- });
- builder.checkTypeVariableBounds(function);
- }
}
class _ErroneousInitializerVisitor extends ir.Visitor<bool> {
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 49cf09b..5d70634 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -10,7 +10,6 @@
import '../constants/constant_system.dart';
import '../constants/values.dart';
import '../common_elements.dart' show CommonElements;
-import '../elements/elements.dart' show MethodElement;
import '../elements/entities.dart';
import '../elements/jumps.dart';
import '../elements/types.dart';
@@ -27,7 +26,7 @@
import '../native/native.dart' as native;
import '../options.dart';
import '../types/abstract_value_domain.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
import '../universe/use.dart'
@@ -2443,17 +2442,8 @@
pushStatement(
new js.Throw(value).withSourceInformation(sourceInformation));
} else {
- Entity element = _work.element;
- if (element is MethodElement && element.asyncMarker.isYielding) {
- // `return <expr>;` is illegal in a sync* or async* function.
- // To have the async-translator working, we avoid introducing
- // `return` nodes.
- pushStatement(new js.ExpressionStatement(value)
- .withSourceInformation(sourceInformation));
- } else {
- pushStatement(
- new js.Return(value).withSourceInformation(sourceInformation));
- }
+ pushStatement(
+ new js.Return(value).withSourceInformation(sourceInformation));
}
}
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index d7194b8..bfa7fb2 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -8,7 +8,7 @@
import '../js_backend/interceptor_data.dart';
import '../options.dart';
import '../types/abstract_value_domain.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
import '../universe/selector.dart' show Selector;
import '../world.dart' show ClosedWorld;
import 'nodes.dart';
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index 4215366..6dc7c0a 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -20,12 +20,11 @@
import '../js_backend/native_data.dart';
import '../js_backend/js_interop_analysis.dart';
import '../js_backend/interceptor_data.dart';
-import '../js_backend/mirrors_data.dart';
import '../js_backend/runtime_types.dart';
import '../js_emitter/code_emitter_task.dart';
import '../options.dart';
-import '../resolution/tree_elements.dart';
import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../world.dart' show ClosedWorld;
import 'jump_handler.dart';
@@ -50,9 +49,6 @@
/// breaks.
bool inTryStatement = false;
- /// The tree elements for the element being built into an SSA graph.
- TreeElements get elements;
-
/// The JavaScript backend we are targeting in this compilation.
JavaScriptBackend get backend;
@@ -63,8 +59,6 @@
AbstractValueDomain get abstractValueDomain =>
closedWorld.abstractValueDomain;
- CommonMasks get commonMasks => closedWorld.abstractValueDomain;
-
DiagnosticReporter get reporter => backend.reporter;
CompilerOptions get options => compiler.options;
@@ -97,8 +91,6 @@
FunctionInlineCache get inlineCache => backend.inlineCache;
- MirrorsData get mirrorsData => backend.mirrorsData;
-
JsInteropAnalysis get jsInteropAnalysis => backend.jsInteropAnalysis;
DeferredLoadTask get deferredLoadTask => compiler.deferredLoadTask;
@@ -250,7 +242,7 @@
MemberEntity get sourceElement;
HLiteralList buildLiteralList(List<HInstruction> inputs) {
- return new HLiteralList(inputs, commonMasks.growableListType);
+ return new HLiteralList(inputs, abstractValueDomain.growableListType);
}
HInstruction callSetRuntimeTypeInfoWithTypeArguments(
@@ -266,7 +258,7 @@
TypeInfoExpressionKind.INSTANCE,
closedWorld.elementEnvironment.getThisType(type.element),
rtiInputs,
- closedWorld.abstractValueDomain.dynamicType);
+ abstractValueDomain.dynamicType);
add(typeInfo);
return callSetRuntimeTypeInfo(typeInfo, newObject, sourceInformation);
}
@@ -298,7 +290,7 @@
bool getFlagValue(String flagName) {
switch (flagName) {
case 'MUST_RETAIN_METADATA':
- return mirrorsData.mustRetainMetadata;
+ return false;
case 'USE_CONTENT_SECURITY_POLICY':
return options.useContentSecurityPolicy;
case 'IS_FULL_EMITTER':
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 11b98a0..a3ec846 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -8,7 +8,7 @@
import '../elements/entities.dart';
import '../js_backend/interceptor_data.dart';
import '../types/abstract_value_domain.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
import '../universe/selector.dart' show Selector;
import '../world.dart' show ClosedWorld;
import 'nodes.dart';
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 0ca17d5..ac8576f 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -8,6 +8,7 @@
import '../elements/entities.dart';
import '../elements/names.dart';
import '../options.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../universe/call_structure.dart';
import '../universe/selector.dart';
diff --git a/pkg/compiler/lib/src/ssa/jump_handler.dart b/pkg/compiler/lib/src/ssa/jump_handler.dart
index 3687961..20d604b0 100644
--- a/pkg/compiler/lib/src/ssa/jump_handler.dart
+++ b/pkg/compiler/lib/src/ssa/jump_handler.dart
@@ -5,7 +5,6 @@
import '../common.dart';
import '../elements/jumps.dart';
import '../io/source_information.dart';
-import '../tree/tree.dart' as ast;
import 'graph_builder.dart';
import 'locals_handler.dart';
@@ -221,33 +220,3 @@
super.close();
}
}
-
-/// Special [JumpHandler] implementation used to handle continue statements
-/// targeting switch cases.
-class AstSwitchCaseJumpHandler extends SwitchCaseJumpHandler {
- AstSwitchCaseJumpHandler(
- GraphBuilder builder, JumpTarget target, ast.SwitchStatement node)
- : super(builder, target) {
- // The switch case indices must match those computed in
- // [SsaFromAstMixin.buildSwitchCaseConstants].
- // Switch indices are 1-based so we can bypass the synthetic loop when no
- // cases match simply by branching on the index (which defaults to null).
- int switchIndex = 1;
- for (ast.SwitchCase switchCase in node.cases) {
- for (ast.Node labelOrCase in switchCase.labelsAndCases) {
- ast.Node label = labelOrCase.asLabel();
- if (label != null) {
- LabelDefinition labelElement =
- builder.elements.getLabelDefinition(label);
- if (labelElement != null && labelElement.isContinueTarget) {
- JumpTarget continueTarget = labelElement.target;
- targetIndexMap[continueTarget] = switchIndex;
- assert(builder.jumpTargets[continueTarget] == null);
- builder.jumpTargets[continueTarget] = this;
- }
- }
- }
- switchIndex++;
- }
- }
-}
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index 7b93861..28185e0 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -295,11 +295,20 @@
isEmpty: literal.entries.isEmpty));
}
+ @override
void visitMapEntry(ir.MapEntry entry) {
visitNode(entry.key);
visitNode(entry.value);
}
+ @override
+ void visitConditionalExpression(ir.ConditionalExpression node) {
+ visitNode(node.condition);
+ visitNode(node.then);
+ visitNode(node.otherwise);
+ // Don't visit the static type.
+ }
+
List<DartType> _visitArguments(ir.Arguments arguments) {
arguments.positional.forEach(visitNode);
arguments.named.forEach(visitNode);
diff --git a/pkg/compiler/lib/src/ssa/kernel_string_builder.dart b/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
index 92e4b4d..3b52451 100644
--- a/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
@@ -57,14 +57,14 @@
HInstruction concat(HInstruction left, HInstruction right) {
HInstruction instruction =
- new HStringConcat(left, right, builder.commonMasks.stringType);
+ new HStringConcat(left, right, builder.abstractValueDomain.stringType);
builder.add(instruction);
return instruction;
}
HInstruction stringify(HInstruction expression) {
HInstruction instruction =
- new HStringify(expression, builder.commonMasks.stringType)
+ new HStringify(expression, builder.abstractValueDomain.stringType)
..sourceInformation = expression.sourceInformation;
builder.add(instruction);
return instruction;
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index 2f3973b..bf5b34b 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -4,7 +4,6 @@
import '../closure.dart';
import '../common.dart';
-import '../elements/elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../io/source_information.dart';
@@ -12,7 +11,8 @@
import '../js_backend/interceptor_data.dart';
import '../js_model/closure.dart' show JRecordField, JClosureField;
import '../js_model/locals.dart' show JLocal;
-import '../tree/tree.dart' as ast;
+import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../world.dart' show ClosedWorld;
@@ -68,7 +68,8 @@
ClosedWorld get closedWorld => builder.closedWorld;
- CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+ AbstractValueDomain get _abstractValueDomain =>
+ closedWorld.abstractValueDomain;
GlobalTypeInferenceResults get _globalInferenceResults =>
builder.globalInferenceResults;
@@ -118,7 +119,7 @@
}
HInstruction createBox(SourceInformation sourceInformation) {
- HInstruction box = new HCreateBox(commonMasks.nonNullType)
+ HInstruction box = new HCreateBox(_abstractValueDomain.nonNullType)
..sourceInformation = sourceInformation;
builder.add(box);
return box;
@@ -137,7 +138,8 @@
if (forGenerativeConstructorBody) {
// The box is passed as a parameter to a generative
// constructor body.
- box = builder.addParameter(closureInfo.context, commonMasks.nonNullType);
+ box = builder.addParameter(
+ closureInfo.context, _abstractValueDomain.nonNullType);
} else {
box = createBox(sourceInformation);
}
@@ -148,12 +150,8 @@
closureInfo.forEachBoxedVariable((Local from, FieldEntity to) {
// The [from] can only be a parameter for function-scopes and not
// loop scopes.
- bool isParameter;
- if (from is JLocal) {
- isParameter = from.isRegularParameter;
- } else if (from is LocalVariableElement) {
- isParameter = from.isRegularParameter;
- }
+ JLocal jFrom = from;
+ bool isParameter = jFrom.isRegularParameter;
assert(isParameter != null);
if (isParameter && !forGenerativeConstructorBody) {
// Now that the redirection is set up, the update to the local will
@@ -201,8 +199,6 @@
Map<Local, TypeMask> parameters,
SourceInformation sourceInformation,
{bool isGenerativeConstructorBody}) {
- assert(!(element is MemberElement && !element.isImplementation),
- failedAt(element));
this.scopeInfo = scopeInfo;
parameters.forEach((Local local, TypeMask typeMask) {
@@ -234,7 +230,7 @@
});
// Inside closure redirect references to itself to [:this:].
HThis thisInstruction =
- new HThis(closureData.thisLocal, commonMasks.nonNullType);
+ new HThis(closureData.thisLocal, _abstractValueDomain.nonNullType);
builder.graph.thisInstruction = thisInstruction;
builder.graph.entry.addAtEntry(thisInstruction);
updateLocal(closureData.closureEntity, thisInstruction);
@@ -304,8 +300,7 @@
if (scopeInfo is! ClosureRepresentationInfo) return false;
FieldEntity redirectTarget = redirectionMapping[local];
if (redirectTarget == null) return false;
- return redirectTarget is ClosureFieldElement ||
- redirectTarget is JClosureField;
+ return redirectTarget is JClosureField;
}
bool isBoxed(Local local) {
@@ -347,7 +342,7 @@
FieldEntity redirect = redirectionMapping[local];
HInstruction receiver = readLocal(closureData.closureEntity);
TypeMask type = local is BoxLocal
- ? commonMasks.nonNullType
+ ? _abstractValueDomain.nonNullType
: getTypeOfCapturedVariable(redirect);
HInstruction fieldGet = new HFieldGet(redirect, receiver, type);
builder.add(fieldGet);
@@ -360,9 +355,7 @@
// accessed through a closure-field.
// Calling [readLocal] makes sure we generate the correct code to get
// the box.
- if (redirect is BoxFieldElement) {
- localBox = redirect.box;
- } else if (redirect is JRecordField) {
+ if (redirect is JRecordField) {
localBox = redirect.box;
}
assert(localBox != null);
@@ -375,8 +368,8 @@
} else {
assert(_isUsedInTryOrGenerator(local));
HLocalValue localValue = getLocal(local);
- HInstruction instruction = new HLocalGet(
- local, localValue, commonMasks.dynamicType, sourceInformation);
+ HInstruction instruction = new HLocalGet(local, localValue,
+ _abstractValueDomain.dynamicType, sourceInformation);
builder.add(instruction);
return instruction;
}
@@ -402,8 +395,9 @@
}
return activationVariables.putIfAbsent(local, () {
- HLocalValue localValue = new HLocalValue(local, commonMasks.nonNullType)
- ..sourceInformation = sourceInformation;
+ HLocalValue localValue =
+ new HLocalValue(local, _abstractValueDomain.nonNullType)
+ ..sourceInformation = sourceInformation;
builder.graph.entry.addAtExit(localValue);
return localValue;
});
@@ -431,9 +425,7 @@
FieldEntity redirect = redirectionMapping[local];
assert(redirect != null);
BoxLocal localBox;
- if (redirect is BoxFieldElement) {
- localBox = redirect.box;
- } else if (redirect is JRecordField) {
+ if (redirect is JRecordField) {
localBox = redirect.box;
}
assert(localBox != null);
@@ -522,8 +514,8 @@
if (isAccessedDirectly(local)) {
// We know 'this' cannot be modified.
if (local != scopeInfo.thisLocal) {
- HPhi phi =
- new HPhi.singleInput(local, instruction, commonMasks.dynamicType);
+ HPhi phi = new HPhi.singleInput(
+ local, instruction, _abstractValueDomain.dynamicType);
loopEntry.addPhi(phi);
directLocals[local] = phi;
} else {
@@ -590,8 +582,10 @@
if (identical(instruction, mine)) {
joinedLocals[local] = instruction;
} else {
- HInstruction phi = new HPhi.manyInputs(local,
- <HInstruction>[mine, instruction], commonMasks.dynamicType);
+ HInstruction phi = new HPhi.manyInputs(
+ local,
+ <HInstruction>[mine, instruction],
+ _abstractValueDomain.dynamicType);
joinBlock.addPhi(phi);
joinedLocals[local] = phi;
}
@@ -613,7 +607,7 @@
HInstruction thisValue = null;
directLocals.forEach((Local local, HInstruction instruction) {
if (local != scopeInfo.thisLocal) {
- HPhi phi = new HPhi.noInputs(local, commonMasks.dynamicType);
+ HPhi phi = new HPhi.noInputs(local, _abstractValueDomain.dynamicType);
joinedLocals[local] = phi;
joinBlock.addPhi(phi);
} else {
diff --git a/pkg/compiler/lib/src/ssa/loop_handler.dart b/pkg/compiler/lib/src/ssa/loop_handler.dart
index 89ea833..77c2882 100644
--- a/pkg/compiler/lib/src/ssa/loop_handler.dart
+++ b/pkg/compiler/lib/src/ssa/loop_handler.dart
@@ -7,9 +7,7 @@
import '../closure.dart' show CapturedLoopScope;
import '../elements/jumps.dart';
import '../io/source_information.dart';
-import '../tree/tree.dart' as ast;
-import 'builder.dart';
import 'builder_kernel.dart';
import 'graph_builder.dart';
import 'jump_handler.dart';
@@ -312,35 +310,6 @@
{bool isLoopJump});
}
-/// A loop handler for the builder that just uses AST nodes directly.
-class SsaLoopHandler extends LoopHandler<ast.Node> {
- final SsaAstGraphBuilder builder;
-
- SsaLoopHandler(SsaAstGraphBuilder builder)
- : this.builder = builder,
- super(builder);
-
- @override
- int loopKind(ast.Node node) => node.accept(const _SsaLoopTypeVisitor());
-
- @override
- JumpHandler createJumpHandler(ast.Node node, JumpTarget jumpTarget,
- {bool isLoopJump}) =>
- builder.createJumpHandler(node, jumpTarget, isLoopJump: isLoopJump);
-}
-
-class _SsaLoopTypeVisitor extends ast.Visitor {
- const _SsaLoopTypeVisitor();
- int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
- int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
- int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
- int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
- int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
- int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
- int visitSwitchStatement(ast.SwitchStatement node) =>
- HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
-}
-
// TODO(het): Since kernel simplifies loop breaks and continues, we should
// rewrite the loop handler from scratch to account for the simplified structure
class KernelLoopHandler extends LoopHandler<ir.TreeNode> {
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 170afb3..f521421 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -18,6 +18,7 @@
import '../native/native.dart' as native;
import '../options.dart';
import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../universe/selector.dart' show Selector;
import '../universe/side_effects.dart' show SideEffects;
diff --git a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
index f628a1e..f6bfb90 100644
--- a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
@@ -161,8 +161,9 @@
boolifiedLeft = builder.popBoolified();
builder.stack.add(boolifiedLeft);
if (!isAnd) {
- builder.push(new HNot(builder.pop(), builder.commonMasks.boolType)
- ..sourceInformation = sourceInformation);
+ builder.push(
+ new HNot(builder.pop(), builder.abstractValueDomain.boolType)
+ ..sourceInformation = sourceInformation);
}
}
@@ -178,7 +179,7 @@
HPhi result = new HPhi.manyInputs(
null,
<HInstruction>[boolifiedRight, notIsAnd],
- builder.commonMasks.dynamicType)
+ builder.abstractValueDomain.dynamicType)
..sourceInformation = sourceInformation;
builder.current.addPhi(result);
builder.stack.add(result);
@@ -205,7 +206,7 @@
if (isExpression) {
assert(thenValue != null && elseValue != null);
HPhi phi = new HPhi.manyInputs(null, <HInstruction>[thenValue, elseValue],
- builder.commonMasks.dynamicType);
+ builder.abstractValueDomain.dynamicType);
joinBranch.block.addPhi(phi);
builder.stack.add(phi);
}
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index c9b456e..81268b8 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -7,7 +7,7 @@
import '../elements/entities.dart';
import '../elements/types.dart';
import '../io/source_information.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
import '../universe/use.dart' show TypeUse;
/// Enum that defines how a member has access to the current type variables.
@@ -75,6 +75,14 @@
return other;
}
+ HInstruction trustTypeOfParameter(HInstruction original, DartType type) {
+ if (type == null) return original;
+ HInstruction trusted = _trustType(original, type);
+ if (trusted == original) return original;
+ builder.add(trusted);
+ return trusted;
+ }
+
HInstruction potentiallyCheckOrTrustTypeOfParameter(
HInstruction original, DartType type) {
if (type == null) return original;
@@ -171,11 +179,11 @@
HInstruction target =
builder.localsHandler.readThis(sourceInformation: sourceInformation);
HInstruction interceptor =
- new HInterceptor(target, builder.commonMasks.nonNullType)
+ new HInterceptor(target, builder.abstractValueDomain.nonNullType)
..sourceInformation = sourceInformation;
builder.add(interceptor);
builder.push(new HTypeInfoReadVariable.intercepted(
- variable, interceptor, target, builder.commonMasks.dynamicType)
+ variable, interceptor, target, builder.abstractValueDomain.dynamicType)
..sourceInformation = sourceInformation);
return builder.pop();
}
@@ -197,7 +205,7 @@
TypeInfoExpressionKind.INSTANCE,
builder.closedWorld.elementEnvironment.getThisType(interface.element),
inputs,
- builder.commonMasks.dynamicType)
+ builder.abstractValueDomain.dynamicType)
..sourceInformation = sourceInformation;
return representation;
}
@@ -229,16 +237,12 @@
TypeInfoExpressionKind.COMPLETE,
argument,
inputs,
- builder.commonMasks.dynamicType)
+ builder.abstractValueDomain.dynamicType)
..sourceInformation = sourceInformation;
builder.add(result);
return result;
}
- /// In checked mode, generate type tests for the parameters of the inlined
- /// function.
- void potentiallyCheckInlinedParameterTypes(FunctionEntity function);
-
bool get checkOrTrustTypes =>
builder.options.strongMode ||
builder.options.enableTypeAssertions ||
@@ -254,10 +258,9 @@
if (type == null) return original;
if (type.isTypeVariable) {
TypeVariableType typeVariable = type;
- // GENERIC_METHODS: The following statement was added for parsing and
- // ignoring method type variables; must be generalized for full support of
- // generic methods.
- if (typeVariable.element.typeDeclaration is! ClassEntity) {
+ // In Dart 1, method type variables are ignored.
+ if (!builder.options.strongMode &&
+ typeVariable.element.typeDeclaration is! ClassEntity) {
type = const DynamicType();
}
}
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index d93488d..9e938c4 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -5,6 +5,7 @@
import '../common_elements.dart' show CommonElements;
import '../elements/entities.dart';
import '../native/native.dart' as native;
+import '../types/masks.dart';
import '../types/types.dart';
import '../universe/selector.dart' show Selector;
import '../world.dart' show ClosedWorld;
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index f5e50bb..d0a0f44 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -6,6 +6,7 @@
import '../elements/entities.dart';
import '../options.dart';
import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
import '../types/types.dart';
import '../universe/selector.dart' show Selector;
import '../world.dart' show ClosedWorld;
diff --git a/pkg/compiler/lib/src/string_validator.dart b/pkg/compiler/lib/src/string_validator.dart
deleted file mode 100644
index 75f59f5..0000000
--- a/pkg/compiler/lib/src/string_validator.dart
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check the validity of string literals.
-
-library stringvalidator;
-
-import 'dart:collection';
-
-import 'common.dart';
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'tree/dartstring.dart' show DartString;
-import 'tree/nodes.dart' show StringQuoting;
-import 'package:front_end/src/fasta/scanner/characters.dart';
-
-class StringValidator {
- final DiagnosticReporter reporter;
-
- StringValidator(this.reporter);
-
- DartString validateInterpolationPart(Token token, StringQuoting quoting,
- {bool isFirst: false, bool isLast: false}) {
- String source = token.lexeme;
- int leftQuote = 0;
- int rightQuote = 0;
- if (isFirst) leftQuote = quoting.leftQuoteLength;
- if (isLast) rightQuote = quoting.rightQuoteLength;
- String content = copyWithoutQuotes(source, leftQuote, rightQuote);
- return validateString(
- token, token.charOffset + leftQuote, content, quoting);
- }
-
- static StringQuoting quotingFromString(String sourceString) {
- Iterator<int> source = sourceString.codeUnits.iterator;
- bool raw = false;
- int leftQuoteLength = 1;
- source.moveNext();
- int quoteChar = source.current;
- if (quoteChar == $r) {
- raw = true;
- source.moveNext();
- quoteChar = source.current;
- }
- assert(quoteChar == $SQ || quoteChar == $DQ);
- // String has at least one quote. Check it if has three.
- // If it only has two, the string must be an empty string literal,
- // and end after the second quote.
- if (source.moveNext() && source.current == quoteChar && source.moveNext()) {
- int code = source.current;
- assert(code == quoteChar); // If not, there is a bug in the parser.
- leftQuoteLength = 3;
-
- // Check if a multiline string starts with optional whitespace followed by
- // a newline (CR, LF or CR+LF).
- // We also accept if these characters are escaped by a backslash.
- int newLineLength = 1;
- while (true) {
- // Due to string-interpolations we are not guaranteed to see the
- // trailing quoting characters. The invocations to `moveNext()` may
- // therefore return false and the `current`-getter return `null`. The
- // code does not need to handle this specially (as it will not find the
- // newline characters).
- source.moveNext();
- code = source.current;
- if (code == $BACKSLASH) {
- newLineLength++;
- source.moveNext();
- code = source.current;
- }
- if (code == $TAB || code == $SPACE) {
- newLineLength++;
- continue;
- }
- if (code == $CR) {
- if (source.moveNext() && source.current == $LF) {
- newLineLength++;
- }
- leftQuoteLength += newLineLength;
- } else if (code == $LF) {
- leftQuoteLength += newLineLength;
- }
- break;
- }
- }
- return StringQuoting.getQuoting(quoteChar, raw, leftQuoteLength);
- }
-
- /**
- * Return the string [string] witout its [initial] first and [terminal] last
- * characters. This is intended to be used to remove quotes from string
- * literals (including an initial 'r' for raw strings).
- */
- String copyWithoutQuotes(String string, int initial, int terminal) {
- assert(0 <= initial);
- assert(0 <= terminal);
- assert(initial + terminal <= string.length);
- return string.substring(initial, string.length - terminal);
- }
-
- void stringParseError(String message, Token token, int offset) {
- reporter.reportErrorMessage(reporter.spanFromToken(token),
- MessageKind.GENERIC, {'text': "$message @ $offset"});
- }
-
- /**
- * Validates the escape sequences and special characters of a string literal.
- * Returns a DartString if valid, and null if not.
- */
- DartString validateString(
- Token token, int startOffset, String string, StringQuoting quoting) {
- // We need to check for invalid x and u escapes, for line
- // terminators in non-multiline strings, and for invalid Unicode
- // code points (either directly or as u-escape values).
- int length = 0;
- int index = startOffset;
- bool containsEscape = false;
- var stringIter = string.codeUnits.iterator;
- for (HasNextIterator<int> iter = new HasNextIterator(stringIter);
- iter.hasNext;
- length++) {
- index++;
- int code = iter.next();
- if (code == $BACKSLASH) {
- if (quoting.raw) continue;
- containsEscape = true;
- if (!iter.hasNext) {
- stringParseError("Incomplete escape sequence", token, index);
- return null;
- }
- index++;
- code = iter.next();
- if (code == $x) {
- for (int i = 0; i < 2; i++) {
- if (!iter.hasNext) {
- stringParseError("Incomplete escape sequence", token, index);
- return null;
- }
- index++;
- code = iter.next();
- if (!isHexDigit(code)) {
- stringParseError(
- "Invalid character in escape sequence", token, index);
- return null;
- }
- }
- // A two-byte hex escape can't generate an invalid value.
- continue;
- } else if (code == $u) {
- index++;
- code = iter.hasNext ? iter.next() : 0;
- int value = 0;
- if (code == $OPEN_CURLY_BRACKET) {
- // expect 1-6 hex digits.
- int count = 0;
- while (iter.hasNext) {
- code = iter.next();
- index++;
- if (code == $CLOSE_CURLY_BRACKET) {
- break;
- }
- if (!isHexDigit(code)) {
- stringParseError(
- "Invalid character in escape sequence", token, index);
- return null;
- }
- count++;
- value = value * 16 + hexDigitValue(code);
- }
- if (code != $CLOSE_CURLY_BRACKET || count == 0 || count > 6) {
- int errorPosition = index - count;
- if (count > 6) errorPosition += 6;
- stringParseError(
- "Invalid character in escape sequence", token, errorPosition);
- return null;
- }
- } else {
- // Expect four hex digits, including the one just read.
- for (int i = 0; i < 4; i++) {
- if (i > 0) {
- if (iter.hasNext) {
- index++;
- code = iter.next();
- } else {
- code = 0;
- }
- }
- if (!isHexDigit(code)) {
- stringParseError(
- "Invalid character in escape sequence", token, index);
- return null;
- }
- value = value * 16 + hexDigitValue(code);
- }
- }
- code = value;
- }
- }
- if (code >= 0x10000) {
- length++;
- if (code > 0x10FFFF) {
- stringParseError("Invalid code point", token, index);
- return null;
- }
- }
- }
- // String literal successfully validated.
- if (quoting.raw || !containsEscape) {
- // A string without escapes could just as well have been raw.
- return new DartString.rawString(string, length);
- }
- return new DartString.escapedString(string, length);
- }
-}
diff --git a/pkg/compiler/lib/src/tree/dartstring.dart b/pkg/compiler/lib/src/tree/dartstring.dart
deleted file mode 100644
index 6df4af8..0000000
--- a/pkg/compiler/lib/src/tree/dartstring.dart
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:front_end/src/fasta/scanner/characters.dart';
-
-/**
- * The [DartString] type represents a Dart string value as a sequence of Unicode
- * Scalar Values.
- * After parsing, any valid [LiteralString] will contain a [DartString]
- * representing its content after removing quotes and resolving escapes in
- * its source.
- */
-abstract class DartString extends IterableBase<int> {
- factory DartString.empty() => const LiteralDartString("");
- // This is a convenience constructor. If you need a const literal DartString,
- // use [const LiteralDartString(string)] directly.
- factory DartString.literal(String string) => new LiteralDartString(string);
- factory DartString.rawString(String source, int length) =>
- new RawSourceDartString(source, length);
- factory DartString.escapedString(String source, int length) =>
- new EscapedSourceDartString(source, length);
- factory DartString.concat(DartString first, DartString second) {
- if (first.isEmpty) return second;
- if (second.isEmpty) return first;
- return new ConsDartString(first, second);
- }
- const DartString();
-
- /**
- * The length of this [DartString], which is the string length after
- * escapes have been resolved.
- */
- int get length;
- bool get isEmpty => length == 0;
-
- Iterator<int> get iterator;
-
- /**
- * The string represented by this [DartString].
- */
- String slowToString();
-
- bool operator ==(var other) {
- if (other is! DartString) return false;
- DartString otherString = other;
- if (length != otherString.length) return false;
- Iterator it1 = iterator;
- Iterator it2 = otherString.iterator;
- while (it1.moveNext()) {
- if (!it2.moveNext()) return false;
- if (it1.current != it2.current) return false;
- }
- return true;
- }
-
- int get hashCode => throw new UnsupportedError('DartString.hashCode');
-
- /**
- * A textual representation of this [DartString] with some debugging
- * information.
- */
- String toString() => "DartString#${length}:${slowToString()}";
-}
-
-/**
- * A [DartString] where the content is represented by an actual [String].
- */
-class LiteralDartString extends DartString {
- final String string;
- const LiteralDartString(this.string);
- int get length => string.length;
- Iterator<int> get iterator => string.codeUnits.iterator;
- String slowToString() => string;
-}
-
-/**
- * A [DartString] whereSource the content comes from a slice of the program
- * source.
- */
-abstract class SourceBasedDartString extends DartString {
- /**
- * The source string containing explicit escapes from which this [DartString]
- * is built.
- */
- final String source;
- final int length;
- SourceBasedDartString(this.source, this.length);
- Iterator<int> get iterator;
-}
-
-/**
- * Special case of a [SourceBasedDartString] where we know the source doesn't
- * contain any escapes.
- */
-class RawSourceDartString extends SourceBasedDartString {
- RawSourceDartString(source, length) : super(source, length);
- Iterator<int> get iterator => source.codeUnits.iterator;
- String slowToString() => source;
-}
-
-/**
- * General case of a [SourceBasedDartString] where the source might contain
- * escapes.
- */
-class EscapedSourceDartString extends SourceBasedDartString {
- String toStringCache;
- EscapedSourceDartString(source, length) : super(source, length);
- Iterator<int> get iterator {
- if (toStringCache != null) return toStringCache.codeUnits.iterator;
- return new StringEscapeIterator(source);
- }
-
- String slowToString() {
- if (toStringCache != null) return toStringCache;
- StringBuffer buffer = new StringBuffer();
- StringEscapeIterator it = new StringEscapeIterator(source);
- while (it.moveNext()) {
- buffer.writeCharCode(it.current);
- }
- toStringCache = buffer.toString();
- return toStringCache;
- }
-}
-
-/**
- * The concatenation of two [DartString]s.
- */
-class ConsDartString extends DartString {
- final DartString left;
- final DartString right;
- final int length;
- String toStringCache;
- ConsDartString(DartString left, DartString right)
- : this.left = left,
- this.right = right,
- length = left.length + right.length;
-
- Iterator<int> get iterator => new ConsDartStringIterator(this);
-
- String slowToString() {
- if (toStringCache != null) return toStringCache;
- toStringCache = left.slowToString() + right.slowToString();
- return toStringCache;
- }
-
- String get source => slowToString();
-}
-
-class ConsDartStringIterator implements Iterator<int> {
- HasNextIterator<int> currentIterator;
- DartString right;
- bool hasNextLookAhead;
- int _current = null;
-
- ConsDartStringIterator(ConsDartString cons)
- : currentIterator = new HasNextIterator<int>(cons.left.iterator),
- right = cons.right {
- hasNextLookAhead = currentIterator.hasNext;
- if (!hasNextLookAhead) {
- nextPart();
- }
- }
-
- int get current => _current;
-
- bool moveNext() {
- if (!hasNextLookAhead) {
- _current = null;
- return false;
- }
- _current = currentIterator.next();
- hasNextLookAhead = currentIterator.hasNext;
- if (!hasNextLookAhead) {
- nextPart();
- }
- return true;
- }
-
- void nextPart() {
- if (right != null) {
- currentIterator = new HasNextIterator<int>(right.iterator);
- right = null;
- hasNextLookAhead = currentIterator.hasNext;
- }
- }
-}
-
-/**
- *Iterator that returns the actual string contents of a string with escapes.
- */
-class StringEscapeIterator implements Iterator<int> {
- final Iterator<int> source;
- int _current = null;
-
- StringEscapeIterator(String source) : this.source = source.codeUnits.iterator;
-
- int get current => _current;
-
- bool moveNext() {
- if (!source.moveNext()) {
- _current = null;
- return false;
- }
- int code = source.current;
- if (code != $BACKSLASH) {
- _current = code;
- return true;
- }
- source.moveNext();
- code = source.current;
- switch (code) {
- case $n:
- _current = $LF;
- break;
- case $r:
- _current = $CR;
- break;
- case $t:
- _current = $TAB;
- break;
- case $b:
- _current = $BS;
- break;
- case $f:
- _current = $FF;
- break;
- case $v:
- _current = $VTAB;
- break;
- case $x:
- source.moveNext();
- int value = hexDigitValue(source.current);
- source.moveNext();
- value = value * 16 + hexDigitValue(source.current);
- _current = value;
- break;
- case $u:
- int value = 0;
- source.moveNext();
- code = source.current;
- if (code == $OPEN_CURLY_BRACKET) {
- source.moveNext();
- while (source.current != $CLOSE_CURLY_BRACKET) {
- value = value * 16 + hexDigitValue(source.current);
- source.moveNext();
- }
- _current = value;
- break;
- }
- // Four digit hex value.
- value = hexDigitValue(code);
- for (int i = 0; i < 3; i++) {
- source.moveNext();
- value = value * 16 + hexDigitValue(source.current);
- }
- _current = value;
- break;
- default:
- _current = code;
- }
- return true;
- }
-}
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
deleted file mode 100644
index d83c8d4..0000000
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ /dev/null
@@ -1,3370 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection' show IterableMixin;
-
-import 'package:front_end/src/fasta/fasta_codes.dart' show Message;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
- show PLUS_TOKEN;
-import 'package:front_end/src/fasta/scanner/characters.dart';
-import 'package:front_end/src/scanner/token.dart' show BeginToken, TokenType;
-
-import '../common.dart';
-import '../elements/elements.dart' show MetadataAnnotation;
-import '../util/util.dart';
-import 'dartstring.dart';
-import 'prettyprint.dart';
-import 'unparser.dart';
-
-abstract class Visitor<R> {
- const Visitor();
-
- R visitNode(Node node);
-
- R visitAssert(Assert node) => visitStatement(node);
- R visitAsyncForIn(AsyncForIn node) => visitForIn(node);
- R visitAsyncModifier(AsyncModifier node) => visitNode(node);
- R visitAwait(Await node) => visitExpression(node);
- R visitBlock(Block node) => visitStatement(node);
- R visitBreakStatement(BreakStatement node) => visitGotoStatement(node);
- R visitCascade(Cascade node) => visitExpression(node);
- R visitCascadeReceiver(CascadeReceiver node) => visitExpression(node);
- R visitCaseMatch(CaseMatch node) => visitNode(node);
- R visitCatchBlock(CatchBlock node) => visitNode(node);
- 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);
- R visitExport(Export node) => visitLibraryDependency(node);
- R visitExpression(Expression node) => visitNode(node);
- R visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
- R visitFor(For node) => visitLoop(node);
- R visitForIn(ForIn node) => visitLoop(node);
- R visitFunctionDeclaration(FunctionDeclaration node) => visitStatement(node);
- R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
- R visitFunctionTypeAnnotation(FunctionTypeAnnotation node) {
- return visitTypeAnnotation(node);
- }
-
- R visitGotoStatement(GotoStatement node) => visitStatement(node);
- R visitIdentifier(Identifier node) => visitExpression(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);
- R visitLibraryName(LibraryName node) => visitLibraryTag(node);
- R visitLibraryTag(LibraryTag node) => visitNode(node);
- R visitLiteral(Literal node) => visitExpression(node);
- R visitLiteralBool(LiteralBool node) => visitLiteral(node);
- R visitLiteralDouble(LiteralDouble node) => visitLiteral(node);
- R visitLiteralInt(LiteralInt node) => visitLiteral(node);
- R visitLiteralList(LiteralList node) => visitExpression(node);
- R visitLiteralMap(LiteralMap node) => visitExpression(node);
- R visitLiteralMapEntry(LiteralMapEntry node) => visitNode(node);
- R visitLiteralNull(LiteralNull node) => visitLiteral(node);
- R visitLiteralString(LiteralString node) => visitStringNode(node);
- R visitStringJuxtaposition(StringJuxtaposition node) => visitStringNode(node);
- R visitSyncForIn(SyncForIn node) => visitForIn(node);
- R visitLoop(Loop node) => visitStatement(node);
- R visitMetadata(Metadata node) => visitNode(node);
- R visitMixinApplication(MixinApplication node) => visitNode(node);
- R visitModifiers(Modifiers node) => visitNode(node);
- R visitNamedArgument(NamedArgument node) => visitExpression(node);
- R visitNamedMixinApplication(NamedMixinApplication node) {
- return visitMixinApplication(node);
- }
-
- R visitNewExpression(NewExpression node) => visitExpression(node);
- R visitNodeList(NodeList node) => visitNode(node);
- R visitNominalTypeAnnotation(NominalTypeAnnotation node) {
- return visitTypeAnnotation(node);
- }
-
- R visitOperator(Operator node) => visitIdentifier(node);
- R visitParenthesizedExpression(ParenthesizedExpression node) {
- return visitExpression(node);
- }
-
- R visitPart(Part node) => visitLibraryTag(node);
- R visitPartOf(PartOf node) => visitNode(node);
- R visitPostfix(Postfix node) => visitNodeList(node);
- R visitPrefix(Prefix node) => visitNodeList(node);
- R visitRedirectingFactoryBody(RedirectingFactoryBody node) {
- return visitStatement(node);
- }
-
- R visitRethrow(Rethrow node) => visitStatement(node);
- R visitReturn(Return node) => visitStatement(node);
- R visitSend(Send node) => visitExpression(node);
- R visitSendSet(SendSet node) => visitSend(node);
- R visitStatement(Statement node) => visitNode(node);
- R visitStringNode(StringNode node) => visitExpression(node);
- R visitStringInterpolation(StringInterpolation node) => visitStringNode(node);
- R visitStringInterpolationPart(StringInterpolationPart node) {
- return visitNode(node);
- }
-
- R visitSwitchCase(SwitchCase node) => visitNode(node);
- R visitSwitchStatement(SwitchStatement node) => visitStatement(node);
- R visitLiteralSymbol(LiteralSymbol node) => visitExpression(node);
- R visitThrow(Throw node) => visitExpression(node);
- R visitTryStatement(TryStatement node) => visitStatement(node);
- R visitTypeAnnotation(TypeAnnotation node) => visitNode(node);
- R visitTypedef(Typedef node) => visitNode(node);
- R visitTypeVariable(TypeVariable node) => visitNode(node);
- R visitVariableDefinitions(VariableDefinitions node) => visitStatement(node);
- R visitWhile(While node) => visitLoop(node);
- R visitYield(Yield node) => visitStatement(node);
-}
-
-/// Visitor for [Node]s that take an additional argument of type [A] and returns
-/// a value of type [R].
-abstract class Visitor1<R, A> {
- const Visitor1();
-
- R visitNode(Node node, A arg);
-
- R visitAssert(Assert node, A arg) => visitStatement(node, arg);
- R visitAsyncForIn(AsyncForIn node, A arg) => visitForIn(node, arg);
- R visitAsyncModifier(AsyncModifier node, A arg) => visitNode(node, arg);
- R visitAwait(Await node, A arg) => visitExpression(node, arg);
- R visitBlock(Block node, A arg) => visitStatement(node, arg);
- R visitBreakStatement(BreakStatement node, A arg) {
- return visitGotoStatement(node, arg);
- }
-
- R visitCascade(Cascade node, A arg) => visitExpression(node, arg);
- R visitCascadeReceiver(CascadeReceiver node, A arg) {
- return visitExpression(node, arg);
- }
-
- R visitCaseMatch(CaseMatch node, A arg) => visitNode(node, arg);
- R visitCatchBlock(CatchBlock node, A arg) => visitNode(node, arg);
- R visitClassNode(ClassNode node, A arg) => visitNode(node, arg);
- R visitCombinator(Combinator node, A arg) => visitNode(node, arg);
- R visitConditional(Conditional node, A arg) => visitExpression(node, arg);
- R visitConditionalUri(ConditionalUri node, A arg) {
- return visitNode(node, arg);
- }
-
- R visitContinueStatement(ContinueStatement node, A arg) {
- return visitGotoStatement(node, arg);
- }
-
- R visitDottedName(DottedName node, A arg) {
- return visitExpression(node, arg);
- }
-
- R visitDoWhile(DoWhile node, A arg) => visitLoop(node, arg);
- R visitEmptyStatement(EmptyStatement node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitEnum(Enum node, A arg) => visitNode(node, arg);
- R visitExport(Export node, A arg) => visitLibraryDependency(node, arg);
- R visitExpression(Expression node, A arg) => visitNode(node, arg);
- R visitExpressionStatement(ExpressionStatement node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitFor(For node, A arg) => visitLoop(node, arg);
- R visitForIn(ForIn node, A arg) => visitLoop(node, arg);
- R visitFunctionDeclaration(FunctionDeclaration node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitFunctionExpression(FunctionExpression node, A arg) {
- return visitExpression(node, arg);
- }
-
- R visitFunctionTypeAnnotation(FunctionTypeAnnotation node, A arg) {
- return visitTypeAnnotation(node, arg);
- }
-
- R visitGotoStatement(GotoStatement node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitIdentifier(Identifier node, A arg) {
- return visitExpression(node, arg);
- }
-
- R visitImport(Import node, A arg) {
- return visitLibraryDependency(node, arg);
- }
-
- R visitIf(If node, A arg) => visitStatement(node, arg);
- R visitLabel(Label node, A arg) => visitNode(node, arg);
- R visitLabeledStatement(LabeledStatement node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitLibraryDependency(LibraryDependency node, A arg) {
- return visitLibraryTag(node, arg);
- }
-
- R visitLibraryName(LibraryName node, A arg) => visitLibraryTag(node, arg);
- R visitLibraryTag(LibraryTag node, A arg) => visitNode(node, arg);
- R visitLiteral(Literal node, A arg) => visitExpression(node, arg);
- R visitLiteralBool(LiteralBool node, A arg) => visitLiteral(node, arg);
- R visitLiteralDouble(LiteralDouble node, A arg) => visitLiteral(node, arg);
- R visitLiteralInt(LiteralInt node, A arg) => visitLiteral(node, arg);
- R visitLiteralList(LiteralList node, A arg) => visitExpression(node, arg);
- R visitLiteralMap(LiteralMap node, A arg) => visitExpression(node, arg);
- R visitLiteralMapEntry(LiteralMapEntry node, A arg) => visitNode(node, arg);
- R visitLiteralNull(LiteralNull node, A arg) => visitLiteral(node, arg);
- R visitLiteralString(LiteralString node, A arg) => visitStringNode(node, arg);
- R visitStringJuxtaposition(StringJuxtaposition node, A arg) {
- return visitStringNode(node, arg);
- }
-
- R visitSyncForIn(SyncForIn node, A arg) => visitForIn(node, arg);
- R visitLoop(Loop node, A arg) => visitStatement(node, arg);
- R visitMetadata(Metadata node, A arg) => visitNode(node, arg);
- R visitMixinApplication(MixinApplication node, A arg) => visitNode(node, arg);
- R visitModifiers(Modifiers node, A arg) => visitNode(node, arg);
- R visitNamedArgument(NamedArgument node, A arg) => visitExpression(node, arg);
- R visitNamedMixinApplication(NamedMixinApplication node, A arg) {
- return visitMixinApplication(node, arg);
- }
-
- R visitNewExpression(NewExpression node, A arg) => visitExpression(node, arg);
- R visitNodeList(NodeList node, A arg) => visitNode(node, arg);
- R visitNominalTypeAnnotation(NominalTypeAnnotation node, A arg) {
- return visitTypeAnnotation(node, arg);
- }
-
- R visitOperator(Operator node, A arg) => visitIdentifier(node, arg);
- R visitParenthesizedExpression(ParenthesizedExpression node, A arg) {
- return visitExpression(node, arg);
- }
-
- R visitPart(Part node, A arg) => visitLibraryTag(node, arg);
- R visitPartOf(PartOf node, A arg) => visitNode(node, arg);
- R visitPostfix(Postfix node, A arg) => visitNodeList(node, arg);
- R visitPrefix(Prefix node, A arg) => visitNodeList(node, arg);
- R visitRedirectingFactoryBody(RedirectingFactoryBody node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitRethrow(Rethrow node, A arg) => visitStatement(node, arg);
- R visitReturn(Return node, A arg) => visitStatement(node, arg);
- R visitSend(Send node, A arg) => visitExpression(node, arg);
- R visitSendSet(SendSet node, A arg) => visitSend(node, arg);
- R visitStatement(Statement node, A arg) => visitNode(node, arg);
- R visitStringNode(StringNode node, A arg) => visitExpression(node, arg);
- R visitStringInterpolation(StringInterpolation node, A arg) {
- return visitStringNode(node, arg);
- }
-
- R visitStringInterpolationPart(StringInterpolationPart node, A arg) {
- return visitNode(node, arg);
- }
-
- R visitSwitchCase(SwitchCase node, A arg) => visitNode(node, arg);
- R visitSwitchStatement(SwitchStatement node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitLiteralSymbol(LiteralSymbol node, A arg) => visitExpression(node, arg);
- R visitThrow(Throw node, A arg) => visitExpression(node, arg);
- R visitTryStatement(TryStatement node, A arg) => visitStatement(node, arg);
- R visitTypedef(Typedef node, A arg) => visitNode(node, arg);
- R visitTypeAnnotation(TypeAnnotation node, A arg) => visitNode(node, arg);
- R visitTypeVariable(TypeVariable node, A arg) => visitNode(node, arg);
- R visitVariableDefinitions(VariableDefinitions node, A arg) {
- return visitStatement(node, arg);
- }
-
- R visitWhile(While node, A arg) => visitLoop(node, arg);
- R visitYield(Yield node, A arg) => visitStatement(node, arg);
-}
-
-Token firstBeginToken(Node first, Node second) {
- Token token = null;
- if (first != null) {
- token = first.getBeginToken();
- }
- if (token == null && second != null) {
- // [token] might be null even when [first] is not, e.g. for empty Modifiers.
- token = second.getBeginToken();
- }
- return token;
-}
-
-/**
- * A node in a syntax tree.
- *
- * The abstract part of "abstract syntax tree" is invalidated when
- * supporting tools such as code formatting. These tools need concrete
- * syntax such as parentheses and no constant folding.
- *
- * We support these tools by storing additional references back to the
- * token stream. These references are stored in fields ending with
- * "Token".
- */
-abstract class Node extends NullTreeElementMixin implements Spannable {
- final int hashCode = _HASH_COUNTER = (_HASH_COUNTER + 1).toUnsigned(30);
- static int _HASH_COUNTER = 0;
-
- Node();
-
- accept(Visitor visitor);
-
- accept1(Visitor1 visitor, arg);
-
- visitChildren(Visitor visitor);
-
- visitChildren1(Visitor1 visitor, arg);
-
- /**
- * Returns this node unparsed to Dart source string.
- */
- toString() => unparse(this);
-
- /**
- * Returns Xml-like tree representation of this node.
- */
- toDebugString() {
- return PrettyPrinter.prettyPrint(this);
- }
-
- String getObjectDescription() => super.toString();
-
- Token getBeginToken();
-
- /// Returns the token that ends the 'prefix' of this node.
- ///
- /// For instance the end of the parameters in a [FunctionExpression] or the
- /// last token before the start of a class body for a [ClassNode].
- Token getPrefixEndToken() => getEndToken();
-
- Token getEndToken();
-
- Assert asAssert() => null;
- AsyncModifier asAsyncModifier() => null;
- Await asAwait() => null;
- Block asBlock() => null;
- BreakStatement asBreakStatement() => null;
- Cascade asCascade() => null;
- CascadeReceiver asCascadeReceiver() => null;
- CaseMatch asCaseMatch() => null;
- CatchBlock asCatchBlock() => null;
- 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;
- ErrorExpression asErrorExpression() => null;
- Export asExport() => null;
- Expression asExpression() => null;
- ExpressionStatement asExpressionStatement() => null;
- For asFor() => null;
- SyncForIn asSyncForIn() => null;
- AsyncForIn asAsyncForIn() => null;
- ForIn asForIn() => null;
- FunctionDeclaration asFunctionDeclaration() => null;
- FunctionExpression asFunctionExpression() => null;
- FunctionTypeAnnotation asFunctionTypeAnnotation() => null;
- Identifier asIdentifier() => null;
- If asIf() => null;
- Import asImport() => null;
- Label asLabel() => null;
- LabeledStatement asLabeledStatement() => null;
- LibraryName asLibraryName() => null;
- LibraryDependency asLibraryDependency() => null;
- LiteralBool asLiteralBool() => null;
- LiteralDouble asLiteralDouble() => null;
- LiteralInt asLiteralInt() => null;
- LiteralList asLiteralList() => null;
- LiteralMap asLiteralMap() => null;
- LiteralMapEntry asLiteralMapEntry() => null;
- LiteralNull asLiteralNull() => null;
- LiteralString asLiteralString() => null;
- LiteralSymbol asLiteralSymbol() => null;
- Metadata asMetadata() => null;
- MixinApplication asMixinApplication() => null;
- Modifiers asModifiers() => null;
- NamedArgument asNamedArgument() => null;
- NamedMixinApplication asNamedMixinApplication() => null;
- NewExpression asNewExpression() => null;
- NodeList asNodeList() => null;
- NominalTypeAnnotation asNominalTypeAnnotation() => null;
- Operator asOperator() => null;
- ParenthesizedExpression asParenthesizedExpression() => null;
- Part asPart() => null;
- PartOf asPartOf() => null;
- RedirectingFactoryBody asRedirectingFactoryBody() => null;
- Rethrow asRethrow() => null;
- Return asReturn() => null;
- Send asSend() => null;
- SendSet asSendSet() => null;
- Statement asStatement() => null;
- StringInterpolation asStringInterpolation() => null;
- StringInterpolationPart asStringInterpolationPart() => null;
- StringJuxtaposition asStringJuxtaposition() => null;
- StringNode asStringNode() => null;
- SwitchCase asSwitchCase() => null;
- SwitchStatement asSwitchStatement() => null;
- Throw asThrow() => null;
- TryStatement asTryStatement() => null;
- TypeVariable asTypeVariable() => null;
- Typedef asTypedef() => null;
- VariableDefinitions asVariableDefinitions() => null;
- While asWhile() => null;
- Yield asYield() => null;
-
- bool isValidBreakTarget() => false;
- bool isValidContinueTarget() => false;
- bool isThis() => false;
- bool isSuper() => false;
-
- bool get isErroneous => false;
-}
-
-// Used for caching boolean values on the stack
-class Flag extends Node {
- static final TRUE = new Flag._(true);
- static final FALSE = new Flag._(false);
-
- final bool value;
-
- Flag._(this.value);
-
- @override
- accept(Visitor visitor) {
- throw 'not implemented';
- }
-
- @override
- accept1(Visitor1 visitor, arg) {
- throw 'not implemented';
- }
-
- @override
- Token getBeginToken() {
- return null;
- }
-
- @override
- Token getEndToken() {
- throw 'not implemented';
- }
-
- @override
- visitChildren(Visitor visitor) {
- throw 'not implemented';
- }
-
- @override
- visitChildren1(Visitor1 visitor, arg) {
- throw 'not implemented';
- }
-}
-
-// Used for caching tokens on the stack
-class TokenNode extends Node {
- final Token token;
-
- TokenNode(this.token);
-
- @override
- accept(Visitor visitor) {
- throw 'not implemented';
- }
-
- @override
- accept1(Visitor1 visitor, arg) {
- throw 'not implemented';
- }
-
- @override
- Token getBeginToken() {
- throw 'not implemented';
- }
-
- @override
- Token getEndToken() {
- throw 'not implemented';
- }
-
- @override
- visitChildren(Visitor visitor) {
- throw 'not implemented';
- }
-
- @override
- visitChildren1(Visitor1 visitor, arg) {
- throw 'not implemented';
- }
-}
-
-class ClassNode extends Node {
- final Modifiers modifiers;
- final Identifier name;
- final Node superclass;
- final NodeList interfaces;
- final NodeList typeParameters;
- final NodeList body;
-
- final Token beginToken;
- final Token extendsKeyword;
- final Token endToken;
-
- ClassNode(
- this.modifiers,
- this.name,
- this.typeParameters,
- this.superclass,
- this.interfaces,
- this.beginToken,
- this.extendsKeyword,
- this.body,
- this.endToken);
-
- ClassNode asClassNode() => this;
-
- accept(Visitor visitor) => visitor.visitClassNode(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitClassNode(this, arg);
-
- visitChildren(Visitor visitor) {
- if (name != null) name.accept(visitor);
- if (typeParameters != null) typeParameters.accept(visitor);
- if (superclass != null) superclass.accept(visitor);
- if (interfaces != null) interfaces.accept(visitor);
- if (body != null) body.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (name != null) name.accept1(visitor, arg);
- if (typeParameters != null) typeParameters.accept1(visitor, arg);
- if (superclass != null) superclass.accept1(visitor, arg);
- if (interfaces != null) interfaces.accept1(visitor, arg);
- if (body != null) body.accept1(visitor, arg);
- }
-
- Token getBeginToken() => beginToken;
-
- @override
- Token getPrefixEndToken() {
- Token token;
- if (interfaces != null) {
- token = interfaces.getEndToken();
- }
- if (token == null && superclass != null) {
- token = superclass.getEndToken();
- }
- if (token == null && typeParameters != null) {
- token == typeParameters.getEndToken();
- }
- if (token == null) {
- token = name.getEndToken();
- }
- assert(token != null);
- return token;
- }
-
- Token getEndToken() => endToken;
-}
-
-class MixinApplication extends Node {
- final NominalTypeAnnotation superclass;
- final NodeList mixins;
-
- MixinApplication(this.superclass, this.mixins);
-
- MixinApplication asMixinApplication() => this;
-
- accept(Visitor visitor) => visitor.visitMixinApplication(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitMixinApplication(this, arg);
-
- visitChildren(Visitor visitor) {
- if (superclass != null) superclass.accept(visitor);
- if (mixins != null) mixins.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (superclass != null) superclass.accept1(visitor, arg);
- if (mixins != null) mixins.accept1(visitor, arg);
- }
-
- Token getBeginToken() => superclass.getBeginToken();
- Token getEndToken() => mixins.getEndToken();
-}
-
-class NamedMixinApplication extends Node implements MixinApplication {
- final Identifier name;
- final NodeList typeParameters;
-
- final Modifiers modifiers;
- final MixinApplication mixinApplication;
- final NodeList interfaces;
-
- final Token classKeyword;
- final Token endToken;
-
- NamedMixinApplication(this.name, this.typeParameters, this.modifiers,
- this.mixinApplication, this.interfaces, this.classKeyword, this.endToken);
-
- NominalTypeAnnotation get superclass => mixinApplication.superclass;
- NodeList get mixins => mixinApplication.mixins;
-
- MixinApplication asMixinApplication() => this;
- NamedMixinApplication asNamedMixinApplication() => this;
-
- accept(Visitor visitor) => visitor.visitNamedMixinApplication(this);
-
- accept1(Visitor1 visitor, arg) {
- return visitor.visitNamedMixinApplication(this, arg);
- }
-
- visitChildren(Visitor visitor) {
- name.accept(visitor);
- if (typeParameters != null) typeParameters.accept(visitor);
- if (modifiers != null) modifiers.accept(visitor);
- if (interfaces != null) interfaces.accept(visitor);
- mixinApplication.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- name.accept1(visitor, arg);
- if (typeParameters != null) typeParameters.accept1(visitor, arg);
- if (modifiers != null) modifiers.accept1(visitor, arg);
- if (interfaces != null) interfaces.accept1(visitor, arg);
- mixinApplication.accept1(visitor, arg);
- }
-
- Token getBeginToken() => classKeyword;
- Token getEndToken() => endToken;
-}
-
-abstract class Expression extends Node {
- Expression();
-
- Expression asExpression() => this;
-}
-
-abstract class Statement extends Node {
- Statement();
-
- Statement asStatement() => this;
-
- bool isValidBreakTarget() => true;
-}
-
-/// Erroneous expression that behaves as a literal null.
-class ErrorExpression extends LiteralNull {
- ErrorExpression(token) : super(token);
-
- ErrorExpression asErrorExpression() => this;
-
- bool get isErroneous => true;
-}
-
-/**
- * A message send aka method invocation. In Dart, most operations can
- * (and should) be considered as message sends. Getters and setters
- * are just methods with a special syntax. Consequently, we model
- * property access, assignment, operators, and method calls with this
- * one node.
- */
-class Send extends Expression with StoredTreeElementMixin {
- final Node receiver;
- final Node selector;
- final NodeList argumentsNode;
- final NodeList typeArgumentsNode;
-
- /// Whether this is a conditional send of the form `a?.b`.
- final bool isConditional;
-
- Link<Node> get arguments => argumentsNode.nodes;
-
- Send(
- [this.receiver,
- this.selector,
- this.argumentsNode,
- this.typeArgumentsNode,
- this.isConditional = false]);
- Send.postfix(this.receiver, this.selector,
- [Node argument = null, this.isConditional = false])
- : argumentsNode = (argument == null)
- ? new Postfix()
- : new Postfix.singleton(argument),
- typeArgumentsNode = null;
- Send.prefix(this.receiver, this.selector,
- [Node argument = null, this.isConditional = false])
- : argumentsNode =
- (argument == null) ? new Prefix() : new Prefix.singleton(argument),
- typeArgumentsNode = null;
-
- Send asSend() => this;
-
- accept(Visitor visitor) => visitor.visitSend(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitSend(this, arg);
-
- visitChildren(Visitor visitor) {
- if (receiver != null) receiver.accept(visitor);
- if (selector != null) selector.accept(visitor);
- if (argumentsNode != null) argumentsNode.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (receiver != null) receiver.accept1(visitor, arg);
- if (selector != null) selector.accept1(visitor, arg);
- if (argumentsNode != null) argumentsNode.accept1(visitor, arg);
- }
-
- int argumentCount() {
- return (argumentsNode == null) ? -1 : argumentsNode.slowLength();
- }
-
- bool get isSuperCall {
- return receiver != null && receiver.isSuper();
- }
-
- bool get isOperator => selector is Operator;
- bool get isPropertyAccess => argumentsNode == null;
- bool get isFunctionObjectInvocation => selector == null;
- bool get isPrefix => argumentsNode is Prefix;
- bool get isPostfix => argumentsNode is Postfix;
- bool get isCall => !isOperator && !isPropertyAccess;
- bool get isIndex =>
- isOperator && identical(selector.asOperator().source, '[]');
- bool get isLogicalAnd =>
- isOperator && identical(selector.asOperator().source, '&&');
- bool get isLogicalOr =>
- isOperator && identical(selector.asOperator().source, '||');
- bool get isIfNull =>
- isOperator && identical(selector.asOperator().source, '??');
-
- bool get isTypeCast {
- return isOperator && identical(selector.asOperator().source, 'as');
- }
-
- bool get isTypeTest {
- return isOperator && identical(selector.asOperator().source, 'is');
- }
-
- bool get isIsNotCheck {
- return isTypeTest && arguments.head.asSend() != null;
- }
-
- TypeAnnotation get typeAnnotationFromIsCheckOrCast {
- assert(isOperator);
- assert(identical(selector.asOperator().source, 'is') ||
- identical(selector.asOperator().source, 'as'));
- return isIsNotCheck ? arguments.head.asSend().receiver : arguments.head;
- }
-
- Token getBeginToken() {
- if (isPrefix && !isIndex) return selector.getBeginToken();
- return firstBeginToken(receiver, selector);
- }
-
- Token getEndToken() {
- if (isPrefix) {
- if (receiver != null) return receiver.getEndToken();
- if (selector != null) return selector.getEndToken();
- return null;
- }
- if (!isPostfix && argumentsNode != null) {
- Token token = argumentsNode.getEndToken();
- if (token != null) return token;
- }
- if (selector != null) return selector.getEndToken();
- return getBeginToken();
- }
-
- Send copyWithReceiver(Node newReceiver, bool isConditional) {
- assert(receiver == null);
- return new Send(
- newReceiver, selector, argumentsNode, typeArgumentsNode, isConditional);
- }
-}
-
-class Postfix extends NodeList {
- Postfix() : super(null, const Link<Node>());
- Postfix.singleton(Node argument) : super.singleton(argument);
-}
-
-class Prefix extends NodeList {
- Prefix() : super(null, const Link<Node>());
- Prefix.singleton(Node argument) : super.singleton(argument);
-}
-
-class SendSet extends Send {
- final Operator assignmentOperator;
- SendSet(receiver, selector, this.assignmentOperator, argumentsNode,
- [bool isConditional = false])
- : super(receiver, selector, argumentsNode, null, isConditional);
- SendSet.postfix(receiver, selector, this.assignmentOperator,
- [Node argument = null, bool isConditional = false])
- : super.postfix(receiver, selector, argument, isConditional);
- SendSet.prefix(receiver, selector, this.assignmentOperator,
- [Node argument = null, bool isConditional = false])
- : super.prefix(receiver, selector, argument, isConditional);
-
- SendSet asSendSet() => this;
-
- accept(Visitor visitor) => visitor.visitSendSet(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitSendSet(this, arg);
-
- visitChildren(Visitor visitor) {
- super.visitChildren(visitor);
- if (assignmentOperator != null) assignmentOperator.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- super.visitChildren1(visitor, arg);
- if (assignmentOperator != null) assignmentOperator.accept1(visitor, arg);
- }
-
- /// `true` if this send is not a simple assignment.
- bool get isComplex => !identical(assignmentOperator.source, '=');
-
- /// Whether this is an if-null assignment of the form `a ??= b`.
- bool get isIfNullAssignment => identical(assignmentOperator.source, '??=');
-
- Send copyWithReceiver(Node newReceiver, bool isConditional) {
- assert(receiver == null);
- return new SendSet(newReceiver, selector, assignmentOperator, argumentsNode,
- isConditional);
- }
-
- Token getBeginToken() {
- if (isPrefix) return assignmentOperator.getBeginToken();
- return super.getBeginToken();
- }
-
- Token getEndToken() {
- if (isPostfix) return assignmentOperator.getEndToken();
- return super.getEndToken();
- }
-}
-
-class NewExpression extends Expression {
- /** The token NEW or CONST or `null` for metadata */
- final Token newToken;
-
- // Note: we expect that send.receiver is null.
- final Send send;
-
- NewExpression([this.newToken, this.send]);
-
- NewExpression asNewExpression() => this;
-
- accept(Visitor visitor) => visitor.visitNewExpression(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitNewExpression(this, arg);
-
- visitChildren(Visitor visitor) {
- if (send != null) send.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (send != null) send.accept1(visitor, arg);
- }
-
- bool get isConst {
- return newToken == null || identical(newToken.stringValue, 'const');
- }
-
- Token getBeginToken() => newToken != null ? newToken : send.getBeginToken();
-
- Token getEndToken() => send.getEndToken();
-}
-
-class NodeList extends Node with IterableMixin<Node> {
- final Link<Node> nodes;
- final Token beginToken;
- final Token endToken;
- final String delimiter;
- bool get isEmpty => nodes.isEmpty;
-
- NodeList([this.beginToken, this.nodes, this.endToken, this.delimiter]);
-
- Iterator<Node> get iterator => nodes.iterator;
-
- NodeList.singleton(Node node) : this(null, const Link<Node>().prepend(node));
- NodeList.empty() : this(null, const Link<Node>());
-
- NodeList asNodeList() => this;
-
- // Override [IterableMixin.toString] with same code as [Node.toString].
- toString() => unparse(this);
-
- get length {
- throw new UnsupportedError('use slowLength() instead of get:length');
- }
-
- int slowLength() {
- int result = 0;
- for (Link<Node> cursor = nodes; !cursor.isEmpty; cursor = cursor.tail) {
- result++;
- }
- return result;
- }
-
- accept(Visitor visitor) => visitor.visitNodeList(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitNodeList(this, arg);
-
- visitChildren(Visitor visitor) {
- if (nodes == null) return;
- for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) {
- if (link.head != null) link.head.accept(visitor);
- }
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (nodes == null) return;
- for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) {
- if (link.head != null) link.head.accept1(visitor, arg);
- }
- }
-
- Token getBeginToken() {
- if (beginToken != null) return beginToken;
- if (nodes != null) {
- for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) {
- if (link.head.getBeginToken() != null) {
- return link.head.getBeginToken();
- }
- if (link.head.getEndToken() != null) {
- return link.head.getEndToken();
- }
- }
- }
- return endToken;
- }
-
- Token getEndToken() {
- if (endToken != null) return endToken;
- if (nodes != null) {
- Link<Node> link = nodes;
- if (link.isEmpty) return beginToken;
- while (!link.tail.isEmpty) link = link.tail;
- Node lastNode = link.head;
- if (lastNode != null) {
- if (lastNode.getEndToken() != null) return lastNode.getEndToken();
- if (lastNode.getBeginToken() != null) return lastNode.getBeginToken();
- }
- }
- return beginToken;
- }
-}
-
-class Block extends Statement {
- final NodeList statements;
-
- Block(this.statements);
-
- Block asBlock() => this;
-
- accept(Visitor visitor) => visitor.visitBlock(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitBlock(this, arg);
-
- visitChildren(Visitor visitor) {
- if (statements != null) statements.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (statements != null) statements.accept1(visitor, arg);
- }
-
- Token getBeginToken() => statements.getBeginToken();
-
- Token getEndToken() => statements.getEndToken();
-}
-
-class If extends Statement {
- final ParenthesizedExpression condition;
- final Statement thenPart;
- final Statement elsePart;
-
- final Token ifToken;
- final Token elseToken;
-
- If(this.condition, this.thenPart, this.elsePart, this.ifToken,
- this.elseToken);
-
- If asIf() => this;
-
- bool get hasElsePart => elsePart != null;
-
- accept(Visitor visitor) => visitor.visitIf(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitIf(this, arg);
-
- visitChildren(Visitor visitor) {
- if (condition != null) condition.accept(visitor);
- if (thenPart != null) thenPart.accept(visitor);
- if (elsePart != null) elsePart.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (condition != null) condition.accept1(visitor, arg);
- if (thenPart != null) thenPart.accept1(visitor, arg);
- if (elsePart != null) elsePart.accept1(visitor, arg);
- }
-
- Token getBeginToken() => ifToken;
-
- Token getEndToken() {
- if (elsePart == null) return thenPart.getEndToken();
- return elsePart.getEndToken();
- }
-}
-
-class Conditional extends Expression {
- final Expression condition;
- final Expression thenExpression;
- final Expression elseExpression;
-
- final Token questionToken;
- final Token colonToken;
-
- Conditional(this.condition, this.thenExpression, this.elseExpression,
- this.questionToken, this.colonToken);
-
- Conditional asConditional() => this;
-
- accept(Visitor visitor) => visitor.visitConditional(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitConditional(this, arg);
-
- visitChildren(Visitor visitor) {
- condition.accept(visitor);
- thenExpression.accept(visitor);
- elseExpression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- condition.accept1(visitor, arg);
- thenExpression.accept1(visitor, arg);
- elseExpression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => condition.getBeginToken();
-
- Token getEndToken() => elseExpression.getEndToken();
-}
-
-class For extends Loop {
- /** Either a variable declaration or an expression. */
- final Node initializer;
- /** Either an expression statement or an empty statement. */
- final Statement conditionStatement;
- final NodeList update;
-
- final Token forToken;
-
- For(this.initializer, this.conditionStatement, this.update, body,
- this.forToken)
- : super(body);
-
- For asFor() => this;
-
- Expression get condition {
- ExpressionStatement expressionStatement =
- conditionStatement.asExpressionStatement();
- if (expressionStatement != null) {
- return expressionStatement.expression;
- } else {
- return null;
- }
- }
-
- accept(Visitor visitor) => visitor.visitFor(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitFor(this, arg);
-
- visitChildren(Visitor visitor) {
- if (initializer != null) initializer.accept(visitor);
- if (conditionStatement != null) conditionStatement.accept(visitor);
- if (update != null) update.accept(visitor);
- if (body != null) body.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (initializer != null) initializer.accept1(visitor, arg);
- if (conditionStatement != null) conditionStatement.accept1(visitor, arg);
- if (update != null) update.accept1(visitor, arg);
- if (body != null) body.accept1(visitor, arg);
- }
-
- Token getBeginToken() => forToken;
-
- Token getEndToken() {
- return body.getEndToken();
- }
-}
-
-class FunctionDeclaration extends Statement {
- final FunctionExpression function;
-
- FunctionDeclaration(this.function);
-
- FunctionDeclaration asFunctionDeclaration() => this;
-
- accept(Visitor visitor) => visitor.visitFunctionDeclaration(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitFunctionDeclaration(this, arg);
-
- visitChildren(Visitor visitor) => function.accept(visitor);
-
- visitChildren1(Visitor1 visitor, arg) => function.accept1(visitor, arg);
-
- Token getBeginToken() => function.getBeginToken();
-
- @override
- Token getPrefixEndToken() => function.getPrefixEndToken();
-
- Token getEndToken() => function.getEndToken();
-}
-
-/// Node representing the method implementation modifiers `sync*`, `async`, and
-/// `async*` or the invalid modifier `sync`.
-class AsyncModifier extends Node {
- /// The `async` or `sync` token.
- final Token asyncToken;
-
- /// The `*` token.
- final Token starToken;
-
- AsyncModifier(this.asyncToken, this.starToken);
-
- AsyncModifier asAsyncModifier() => this;
-
- accept(Visitor visitor) => visitor.visitAsyncModifier(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitAsyncModifier(this, arg);
-
- visitChildren(Visitor visitor) {}
-
- visitChildren1(Visitor1 visitor, arg) {}
-
- Token getBeginToken() => asyncToken;
-
- Token getEndToken() => starToken != null ? starToken : asyncToken;
-
- /// Is `true` if this modifier is either `async` or `async*`.
- bool get isAsynchronous => asyncToken.lexeme == 'async';
-
- /// Is `true` if this modifier is either `sync*` or `async*`.
- bool get isYielding => starToken != null;
-}
-
-class FunctionExpression extends Expression with StoredTreeElementMixin {
- final Node name;
- final NodeList typeVariables;
-
- /**
- * List of VariableDefinitions or NodeList.
- *
- * A NodeList can only occur at the end and holds named parameters.
- */
- final NodeList parameters;
-
- final Statement body;
- final TypeAnnotation returnType;
- final Modifiers modifiers;
- final NodeList initializers;
-
- final Token getOrSet;
- final AsyncModifier asyncModifier;
-
- FunctionExpression(
- this.name,
- this.typeVariables,
- this.parameters,
- this.body,
- this.returnType,
- this.modifiers,
- this.initializers,
- this.getOrSet,
- this.asyncModifier) {
- assert(modifiers != null);
- }
-
- FunctionExpression asFunctionExpression() => this;
-
- accept(Visitor visitor) => visitor.visitFunctionExpression(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitFunctionExpression(this, arg);
-
- bool get isRedirectingFactory {
- return body != null && body.asRedirectingFactoryBody() != null;
- }
-
- visitChildren(Visitor visitor) {
- if (modifiers != null) modifiers.accept(visitor);
- if (returnType != null) returnType.accept(visitor);
- if (name != null) name.accept(visitor);
- if (typeVariables != null) typeVariables.accept(visitor);
- if (parameters != null) parameters.accept(visitor);
- if (initializers != null) initializers.accept(visitor);
- if (asyncModifier != null) asyncModifier.accept(visitor);
- if (body != null) body.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (modifiers != null) modifiers.accept1(visitor, arg);
- if (returnType != null) returnType.accept1(visitor, arg);
- if (name != null) name.accept1(visitor, arg);
- if (typeVariables != null) typeVariables.accept1(visitor, arg);
- if (parameters != null) parameters.accept1(visitor, arg);
- if (initializers != null) initializers.accept1(visitor, arg);
- if (asyncModifier != null) asyncModifier.accept1(visitor, arg);
- if (body != null) body.accept1(visitor, arg);
- }
-
- bool get hasBody => body.asEmptyStatement() == null;
-
- bool get hasEmptyBody {
- Block block = body.asBlock();
- if (block == null) return false;
- return block.statements.isEmpty;
- }
-
- Token getBeginToken() {
- Token token = firstBeginToken(modifiers, returnType);
- if (token != null) return token;
- if (getOrSet != null) return getOrSet;
- return firstBeginToken(name, parameters);
- }
-
- @override
- Token getPrefixEndToken() {
- return parameters != null ? parameters.getEndToken() : name.getEndToken();
- }
-
- Token getEndToken() {
- Token token = (body == null) ? null : body.getEndToken();
- token = (token == null) ? parameters.getEndToken() : token;
- return (token == null) ? name.getEndToken() : token;
- }
-}
-
-typedef void DecodeErrorHandler(Token token, var error);
-
-abstract class Literal<T> extends Expression {
- final Token token;
- final DecodeErrorHandler handler;
-
- Literal(Token this.token, DecodeErrorHandler this.handler);
-
- T get value;
-
- visitChildren(Visitor visitor) {}
-
- visitChildren1(Visitor1 visitor, arg) {}
-
- Token getBeginToken() => token;
-
- Token getEndToken() => token;
-}
-
-class LiteralInt extends Literal<int> {
- LiteralInt(Token token, DecodeErrorHandler handler) : super(token, handler);
-
- LiteralInt asLiteralInt() => this;
-
- int get value {
- try {
- Token valueToken = token;
- if (identical(valueToken.kind, Tokens.PLUS_TOKEN)) {
- valueToken = valueToken.next;
- }
- return int.parse(valueToken.lexeme);
- } on FormatException catch (ex) {
- handler(token, ex);
- throw new ArgumentError("handler didn't throw; aborting");
- }
- }
-
- accept(Visitor visitor) => visitor.visitLiteralInt(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralInt(this, arg);
-}
-
-class LiteralDouble extends Literal<double> {
- LiteralDouble(Token token, DecodeErrorHandler handler)
- : super(token, handler);
-
- LiteralDouble asLiteralDouble() => this;
-
- double get value {
- try {
- Token valueToken = token;
- if (identical(valueToken.kind, Tokens.PLUS_TOKEN)) {
- valueToken = valueToken.next;
- }
- return double.parse(valueToken.lexeme);
- } on FormatException catch (ex) {
- handler(token, ex);
- throw new ArgumentError("handler didn't throw; aborting");
- }
- }
-
- accept(Visitor visitor) => visitor.visitLiteralDouble(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralDouble(this, arg);
-}
-
-class LiteralBool extends Literal<bool> {
- LiteralBool(Token token, DecodeErrorHandler handler) : super(token, handler);
-
- LiteralBool asLiteralBool() => this;
-
- bool get value {
- if (identical(token.stringValue, 'true')) return true;
- if (identical(token.stringValue, 'false')) return false;
- (this.handler)(token, "not a bool ${token.lexeme}");
- throw false;
- }
-
- accept(Visitor visitor) => visitor.visitLiteralBool(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralBool(this, arg);
-}
-
-class StringQuoting {
- /// Cache of common quotings.
- static const List<StringQuoting> _mapping = const <StringQuoting>[
- const StringQuoting($SQ, raw: false, leftQuoteLength: 1),
- const StringQuoting($SQ, raw: true, leftQuoteLength: 1),
- const StringQuoting($DQ, raw: false, leftQuoteLength: 1),
- const StringQuoting($DQ, raw: true, leftQuoteLength: 1),
- // No string quotes with 2 characters.
- null,
- null,
- null,
- null,
- // Multiline quotings.
- const StringQuoting($SQ, raw: false, leftQuoteLength: 3),
- const StringQuoting($SQ, raw: true, leftQuoteLength: 3),
- const StringQuoting($DQ, raw: false, leftQuoteLength: 3),
- const StringQuoting($DQ, raw: true, leftQuoteLength: 3),
- // Leading single whitespace or escaped newline.
- const StringQuoting($SQ, raw: false, leftQuoteLength: 4),
- const StringQuoting($SQ, raw: true, leftQuoteLength: 4),
- const StringQuoting($DQ, raw: false, leftQuoteLength: 4),
- const StringQuoting($DQ, raw: true, leftQuoteLength: 4),
- // Other combinations of leading whitespace and/or escaped newline.
- const StringQuoting($SQ, raw: false, leftQuoteLength: 5),
- const StringQuoting($SQ, raw: true, leftQuoteLength: 5),
- const StringQuoting($DQ, raw: false, leftQuoteLength: 5),
- const StringQuoting($DQ, raw: true, leftQuoteLength: 5),
- const StringQuoting($SQ, raw: false, leftQuoteLength: 6),
- const StringQuoting($SQ, raw: true, leftQuoteLength: 6),
- const StringQuoting($DQ, raw: false, leftQuoteLength: 6),
- const StringQuoting($DQ, raw: true, leftQuoteLength: 6)
- ];
-
- final bool raw;
- final int leftQuoteCharCount;
- final int quote;
- const StringQuoting(this.quote, {this.raw, int leftQuoteLength})
- : this.leftQuoteCharCount = leftQuoteLength;
- String get quoteChar => identical(quote, $DQ) ? '"' : "'";
-
- int get leftQuoteLength => (raw ? 1 : 0) + leftQuoteCharCount;
- int get rightQuoteLength => (leftQuoteCharCount > 2) ? 3 : 1;
- static StringQuoting getQuoting(int quote, bool raw, int leftQuoteLength) {
- int quoteKindOffset = (quote == $DQ) ? 2 : 0;
- int rawOffset = raw ? 1 : 0;
- int index = (leftQuoteLength - 1) * 4 + rawOffset + quoteKindOffset;
- if (index < _mapping.length) return _mapping[index];
- return new StringQuoting(quote, raw: raw, leftQuoteLength: leftQuoteLength);
- }
-}
-
-/**
- * Superclass for classes representing string literals.
- */
-abstract class StringNode extends Expression {
- DartString get dartString;
- bool get isInterpolation;
-
- StringNode asStringNode() => this;
-}
-
-class LiteralString extends StringNode {
- final Token token;
- /** Non-null on validated string literals. */
- final DartString dartString;
-
- LiteralString(this.token, this.dartString);
-
- LiteralString asLiteralString() => this;
-
- bool get isInterpolation => false;
-
- Token getBeginToken() => token;
- Token getEndToken() => token;
-
- accept(Visitor visitor) => visitor.visitLiteralString(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralString(this, arg);
-
- void visitChildren(Visitor visitor) {}
-
- void visitChildren1(Visitor1 visitor, arg) {}
-}
-
-class LiteralNull extends Literal<String> {
- LiteralNull(Token token) : super(token, null);
-
- LiteralNull asLiteralNull() => this;
-
- String get value => null;
-
- accept(Visitor visitor) => visitor.visitLiteralNull(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralNull(this, arg);
-}
-
-class LiteralList extends Expression {
- final NodeList typeArguments;
- final NodeList elements;
-
- final Token constKeyword;
-
- LiteralList(this.typeArguments, this.elements, this.constKeyword);
-
- bool get isConst => constKeyword != null;
-
- LiteralList asLiteralList() => this;
- accept(Visitor visitor) => visitor.visitLiteralList(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralList(this, arg);
-
- visitChildren(Visitor visitor) {
- if (typeArguments != null) typeArguments.accept(visitor);
- elements.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (typeArguments != null) typeArguments.accept1(visitor, arg);
- elements.accept1(visitor, arg);
- }
-
- Token getBeginToken() {
- if (constKeyword != null) return constKeyword;
- return firstBeginToken(typeArguments, elements);
- }
-
- Token getEndToken() => elements.getEndToken();
-}
-
-class LiteralSymbol extends Expression {
- final Token hashToken;
- // TODO: this could be a DottedNamed.
- final NodeList identifiers;
-
- LiteralSymbol(this.hashToken, this.identifiers);
-
- LiteralSymbol asLiteralSymbol() => this;
-
- accept(Visitor visitor) => visitor.visitLiteralSymbol(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralSymbol(this, arg);
-
- void visitChildren(Visitor visitor) {
- if (identifiers != null) identifiers.accept(visitor);
- }
-
- void visitChildren1(Visitor1 visitor, arg) {
- if (identifiers != null) identifiers.accept1(visitor, arg);
- }
-
- Token getBeginToken() => hashToken;
-
- Token getEndToken() => identifiers.getEndToken();
-
- String get slowNameString {
- Unparser unparser = new Unparser();
- unparser.unparseNodeListOfIdentifiers(identifiers);
- return unparser.result;
- }
-}
-
-class Identifier extends Expression with StoredTreeElementMixin {
- final Token token;
-
- String get source => token.lexeme;
-
- Identifier(Token this.token);
-
- bool isThis() => identical(source, 'this');
-
- bool isSuper() => identical(source, 'super');
-
- Identifier asIdentifier() => this;
-
- accept(Visitor visitor) => visitor.visitIdentifier(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitIdentifier(this, arg);
-
- visitChildren(Visitor visitor) {}
-
- visitChildren1(Visitor1 visitor, arg) {}
-
- Token getBeginToken() => token;
-
- 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;
-
- accept(Visitor visitor) => visitor.visitDottedName(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitDottedName(this, arg);
-
- void visitChildren(Visitor visitor) {
- identifiers.accept(visitor);
- }
-
- void visitChildren1(Visitor1 visitor, arg) {
- identifiers.accept1(visitor, arg);
- }
-
- 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 [
- "--",
- "++",
- '+=',
- "-=",
- "*=",
- "/=",
- "%=",
- "&=",
- "|=",
- "~/=",
- "^=",
- ">>=",
- "<<=",
- "??="
- ];
-
- static const INCREMENT_OPERATORS = const <String>["++", "--"];
-
- Operator(Token token) : super(token);
-
- Operator asOperator() => this;
-
- accept(Visitor visitor) => visitor.visitOperator(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitOperator(this, arg);
-}
-
-class Return extends Statement {
- final Node expression;
- final Token beginToken;
- final Token endToken;
-
- Return(this.beginToken, this.endToken, this.expression);
-
- Return asReturn() => this;
-
- bool get hasExpression => expression != null;
-
- /// `true` if this return is of the form `=> e;`.
- bool get isArrowBody => beginToken.type == TokenType.FUNCTION;
-
- accept(Visitor visitor) => visitor.visitReturn(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitReturn(this, arg);
-
- visitChildren(Visitor visitor) {
- if (expression != null) expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (expression != null) expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => beginToken;
-
- Token getEndToken() {
- if (endToken == null) return expression.getEndToken();
- return endToken;
- }
-}
-
-class Yield extends Statement {
- final Node expression;
- final Token yieldToken;
- final Token starToken;
- final Token endToken;
-
- Yield(this.yieldToken, this.starToken, this.expression, this.endToken);
-
- Yield asYield() => this;
-
- bool get hasStar => starToken != null;
-
- accept(Visitor visitor) => visitor.visitYield(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitYield(this, arg);
-
- visitChildren(Visitor visitor) {
- expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => yieldToken;
-
- Token getEndToken() => endToken;
-}
-
-class RedirectingFactoryBody extends Statement with StoredTreeElementMixin {
- final Node constructorReference;
- final Token beginToken;
- final Token endToken;
-
- RedirectingFactoryBody(
- this.beginToken, this.endToken, this.constructorReference);
-
- RedirectingFactoryBody asRedirectingFactoryBody() => this;
-
- accept(Visitor visitor) => visitor.visitRedirectingFactoryBody(this);
-
- accept1(Visitor1 visitor, arg) {
- return visitor.visitRedirectingFactoryBody(this, arg);
- }
-
- visitChildren(Visitor visitor) {
- constructorReference.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- constructorReference.accept1(visitor, arg);
- }
-
- Token getBeginToken() => beginToken;
-
- Token getEndToken() => endToken;
-}
-
-class ExpressionStatement extends Statement {
- final Expression expression;
- final Token endToken;
-
- ExpressionStatement(this.expression, this.endToken);
-
- ExpressionStatement asExpressionStatement() => this;
-
- accept(Visitor visitor) => visitor.visitExpressionStatement(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitExpressionStatement(this, arg);
-
- visitChildren(Visitor visitor) {
- if (expression != null) expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (expression != null) expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => expression.getBeginToken();
-
- Token getEndToken() => endToken;
-}
-
-class Throw extends Expression {
- final Expression expression;
-
- final Token throwToken;
- final Token endToken;
-
- Throw(this.expression, this.throwToken, this.endToken);
-
- Throw asThrow() => this;
-
- accept(Visitor visitor) => visitor.visitThrow(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitThrow(this, arg);
-
- visitChildren(Visitor visitor) {
- expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => throwToken;
-
- Token getEndToken() => endToken;
-}
-
-class Await extends Expression {
- final Expression expression;
-
- final Token awaitToken;
-
- Await(this.awaitToken, this.expression);
-
- Await asAwait() => this;
-
- accept(Visitor visitor) => visitor.visitAwait(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitAwait(this, arg);
-
- visitChildren(Visitor visitor) {
- expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => awaitToken;
-
- Token getEndToken() => expression.getEndToken();
-}
-
-class Assert extends Statement {
- final Token assertToken;
- final Expression condition;
- /** Message may be `null`. */
- final Expression message;
- final Token semicolonToken;
-
- Assert(this.assertToken, this.condition, this.message, this.semicolonToken);
-
- Assert asAssert() => this;
-
- bool get hasMessage => message != null;
-
- accept(Visitor visitor) => visitor.visitAssert(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitAssert(this, arg);
-
- visitChildren(Visitor visitor) {
- condition.accept(visitor);
- if (message != null) message.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- condition.accept1(visitor, arg);
- if (message != null) message.accept1(visitor, arg);
- }
-
- Token getBeginToken() => assertToken;
- Token getEndToken() => semicolonToken;
-}
-
-class Rethrow extends Statement {
- final Token throwToken;
- final Token endToken;
-
- Rethrow(this.throwToken, this.endToken);
-
- Rethrow asRethrow() => this;
-
- accept(Visitor visitor) => visitor.visitRethrow(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitRethrow(this, arg);
-
- visitChildren(Visitor visitor) {}
-
- visitChildren1(Visitor1 visitor, arg) {}
-
- Token getBeginToken() => throwToken;
- Token getEndToken() => endToken;
-}
-
-abstract class TypeAnnotation extends Node {}
-
-class NominalTypeAnnotation extends TypeAnnotation {
- final Expression typeName;
- final NodeList typeArguments;
-
- NominalTypeAnnotation(this.typeName, this.typeArguments);
-
- NominalTypeAnnotation asNominalTypeAnnotation() => this;
-
- accept(Visitor visitor) => visitor.visitNominalTypeAnnotation(this);
-
- accept1(Visitor1 visitor, arg) {
- return visitor.visitNominalTypeAnnotation(this, arg);
- }
-
- visitChildren(Visitor visitor) {
- typeName.accept(visitor);
- if (typeArguments != null) typeArguments.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- typeName.accept1(visitor, arg);
- if (typeArguments != null) typeArguments.accept1(visitor, arg);
- }
-
- Token getBeginToken() => typeName.getBeginToken();
-
- Token getEndToken() {
- if (typeArguments != null) return typeArguments.getEndToken();
- return typeName.getEndToken();
- }
-}
-
-class TypeVariable extends Node {
- final Identifier name;
- final Token extendsOrSuper;
- final TypeAnnotation bound;
- TypeVariable(this.name, this.extendsOrSuper, this.bound);
-
- accept(Visitor visitor) => visitor.visitTypeVariable(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitTypeVariable(this, arg);
-
- visitChildren(Visitor visitor) {
- name.accept(visitor);
- if (bound != null) {
- bound.accept(visitor);
- }
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- name.accept1(visitor, arg);
- if (bound != null) {
- bound.accept1(visitor, arg);
- }
- }
-
- TypeVariable asTypeVariable() => this;
-
- Token getBeginToken() => name.getBeginToken();
-
- Token getEndToken() {
- return (bound != null) ? bound.getEndToken() : name.getEndToken();
- }
-}
-
-class VariableDefinitions extends Statement {
- final NodeList metadata;
- final TypeAnnotation type;
- final Modifiers modifiers;
- final NodeList definitions;
-
- VariableDefinitions(this.type, this.modifiers, this.definitions)
- : this.metadata = null {
- assert(modifiers != null);
- }
-
- // TODO(johnniwinther): Make this its own node type.
- VariableDefinitions.forParameter(
- this.metadata, this.type, this.modifiers, this.definitions) {
- assert(modifiers != null);
- }
-
- VariableDefinitions asVariableDefinitions() => this;
-
- accept(Visitor visitor) => visitor.visitVariableDefinitions(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitVariableDefinitions(this, arg);
-
- visitChildren(Visitor visitor) {
- if (metadata != null) metadata.accept(visitor);
- if (type != null) type.accept(visitor);
- if (definitions != null) definitions.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (metadata != null) metadata.accept1(visitor, arg);
- if (type != null) type.accept1(visitor, arg);
- if (definitions != null) definitions.accept1(visitor, arg);
- }
-
- Token getBeginToken() {
- var token = firstBeginToken(modifiers, type);
- if (token == null) {
- token = definitions.getBeginToken();
- }
- return token;
- }
-
- Token getEndToken() {
- var result = definitions.getEndToken();
- if (result != null) return result;
- assert(definitions.nodes.length == 1);
- assert(definitions.nodes.last == null);
- return type.getEndToken();
- }
-}
-
-abstract class Loop extends Statement {
- Expression get condition;
- final Statement body;
-
- Loop(this.body);
-
- bool isValidContinueTarget() => true;
-}
-
-class DoWhile extends Loop {
- final Token doKeyword;
- final Token whileKeyword;
- final Token endToken;
-
- final Expression condition;
-
- DoWhile(Statement body, Expression this.condition, Token this.doKeyword,
- Token this.whileKeyword, Token this.endToken)
- : super(body);
-
- DoWhile asDoWhile() => this;
-
- accept(Visitor visitor) => visitor.visitDoWhile(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitDoWhile(this, arg);
-
- visitChildren(Visitor visitor) {
- if (condition != null) condition.accept(visitor);
- if (body != null) body.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (condition != null) condition.accept1(visitor, arg);
- if (body != null) body.accept1(visitor, arg);
- }
-
- Token getBeginToken() => doKeyword;
-
- Token getEndToken() => endToken;
-}
-
-class While extends Loop {
- final Token whileKeyword;
- final Expression condition;
-
- While(Expression this.condition, Statement body, Token this.whileKeyword)
- : super(body);
-
- While asWhile() => this;
-
- accept(Visitor visitor) => visitor.visitWhile(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitWhile(this, arg);
-
- visitChildren(Visitor visitor) {
- if (condition != null) condition.accept(visitor);
- if (body != null) body.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (condition != null) condition.accept1(visitor, arg);
- if (body != null) body.accept1(visitor, arg);
- }
-
- Token getBeginToken() => whileKeyword;
-
- Token getEndToken() => body.getEndToken();
-}
-
-class ParenthesizedExpression extends Expression {
- final Expression expression;
- final BeginToken beginToken;
-
- ParenthesizedExpression(
- Expression this.expression, BeginToken this.beginToken);
-
- ParenthesizedExpression asParenthesizedExpression() => this;
-
- accept(Visitor visitor) => visitor.visitParenthesizedExpression(this);
-
- accept1(Visitor1 visitor, arg) {
- return visitor.visitParenthesizedExpression(this, arg);
- }
-
- visitChildren(Visitor visitor) {
- if (expression != null) expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (expression != null) expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => beginToken;
-
- Token getEndToken() => beginToken.endGroup;
-}
-
-/** Representation of modifiers such as static, abstract, final, etc. */
-class Modifiers extends Node {
- /**
- * Pseudo-constant for empty modifiers.
- */
- static final Modifiers EMPTY = new Modifiers(new NodeList.empty());
-
- /* TODO(ahe): The following should be validated relating to modifiers:
- * 1. The nodes must come in a certain order.
- * 2. The keywords "var" and "final" may not be used at the same time.
- * 3. The keywords "abstract" and "external" may not be used at the same time.
- * 4. The type of an element must be null if isVar() is true.
- */
-
- final NodeList nodes;
- /** Bit pattern to easy check what modifiers are present. */
- final int flags;
-
- static const int FLAG_STATIC = 1;
- static const int FLAG_ABSTRACT = FLAG_STATIC << 1;
- static const int FLAG_FINAL = FLAG_ABSTRACT << 1;
- static const int FLAG_VAR = FLAG_FINAL << 1;
- static const int FLAG_CONST = FLAG_VAR << 1;
- static const int FLAG_FACTORY = FLAG_CONST << 1;
- static const int FLAG_EXTERNAL = FLAG_FACTORY << 1;
- static const int FLAG_COVARIANT = FLAG_EXTERNAL << 1;
-
- Modifiers(NodeList nodes) : this.withFlags(nodes, computeFlags(nodes.nodes));
-
- Modifiers.withFlags(this.nodes, this.flags);
-
- static int computeFlags(Link<Node> nodes) {
- int flags = 0;
- for (; !nodes.isEmpty; nodes = nodes.tail) {
- String value = nodes.head.asIdentifier().source;
- if (identical(value, 'static'))
- flags |= FLAG_STATIC;
- else if (identical(value, 'abstract'))
- flags |= FLAG_ABSTRACT;
- else if (identical(value, 'final'))
- flags |= FLAG_FINAL;
- else if (identical(value, 'var'))
- flags |= FLAG_VAR;
- else if (identical(value, 'const'))
- flags |= FLAG_CONST;
- else if (identical(value, 'factory'))
- flags |= FLAG_FACTORY;
- else if (identical(value, 'external'))
- flags |= FLAG_EXTERNAL;
- else if (identical(value, 'covariant'))
- flags |= FLAG_COVARIANT;
- else
- throw 'internal error: ${nodes.head}';
- }
- return flags;
- }
-
- Node findModifier(String modifier) {
- Link<Node> nodeList = nodes.nodes;
- for (; !nodeList.isEmpty; nodeList = nodeList.tail) {
- String value = nodeList.head.asIdentifier().source;
- if (identical(value, modifier)) {
- return nodeList.head;
- }
- }
- return null;
- }
-
- Modifiers asModifiers() => this;
- Token getBeginToken() => nodes.getBeginToken();
- Token getEndToken() => nodes.getEndToken();
-
- accept(Visitor visitor) => visitor.visitModifiers(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitModifiers(this, arg);
-
- visitChildren(Visitor visitor) => nodes.accept(visitor);
-
- visitChildren1(Visitor1 visitor, arg) => nodes.accept1(visitor, arg);
-
- bool get isStatic => (flags & FLAG_STATIC) != 0;
- bool get isAbstract => (flags & FLAG_ABSTRACT) != 0;
- bool get isFinal => (flags & FLAG_FINAL) != 0;
- bool get isVar => (flags & FLAG_VAR) != 0;
- bool get isConst => (flags & FLAG_CONST) != 0;
- bool get isFactory => (flags & FLAG_FACTORY) != 0;
- bool get isExternal => (flags & FLAG_EXTERNAL) != 0;
- bool get isCovariant => (flags & FLAG_COVARIANT) != 0;
-
- Node getStatic() => findModifier('static');
-
- /**
- * Use this to check if the declaration is either explicitly or implicitly
- * final.
- */
- bool get isFinalOrConst => isFinal || isConst;
-
- String toString() {
- return modifiersToString(
- isStatic: isStatic,
- isAbstract: isAbstract,
- isFinal: isFinal,
- isVar: isVar,
- isConst: isConst,
- isFactory: isFactory,
- isExternal: isExternal,
- isCovariant: isCovariant);
- }
-}
-
-class StringInterpolation extends StringNode {
- final LiteralString string;
- final NodeList parts;
-
- StringInterpolation(this.string, this.parts);
-
- StringInterpolation asStringInterpolation() => this;
-
- DartString get dartString => null;
- bool get isInterpolation => true;
-
- accept(Visitor visitor) => visitor.visitStringInterpolation(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitStringInterpolation(this, arg);
-
- visitChildren(Visitor visitor) {
- string.accept(visitor);
- parts.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- string.accept1(visitor, arg);
- parts.accept1(visitor, arg);
- }
-
- Token getBeginToken() => string.getBeginToken();
- Token getEndToken() => parts.getEndToken();
-}
-
-class StringInterpolationPart extends Node {
- final Expression expression;
- final LiteralString string;
-
- StringInterpolationPart(this.expression, this.string);
-
- StringInterpolationPart asStringInterpolationPart() => this;
-
- accept(Visitor visitor) => visitor.visitStringInterpolationPart(this);
-
- accept1(Visitor1 visitor, arg) {
- return visitor.visitStringInterpolationPart(this, arg);
- }
-
- visitChildren(Visitor visitor) {
- expression.accept(visitor);
- string.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- expression.accept1(visitor, arg);
- string.accept1(visitor, arg);
- }
-
- Token getBeginToken() => expression.getBeginToken();
-
- Token getEndToken() => string.getEndToken();
-}
-
-/**
- * A class representing juxtaposed string literals.
- * The string literals can be both plain literals and string interpolations.
- */
-class StringJuxtaposition extends StringNode {
- final Expression first;
- final Expression second;
-
- /**
- * Caches the check for whether this juxtaposition contains a string
- * interpolation
- */
- bool isInterpolationCache = null;
-
- /**
- * Caches a Dart string representation of the entire juxtaposition's
- * content. Only juxtapositions that don't (transitively) contains
- * interpolations have a static representation.
- */
- DartString dartStringCache = null;
-
- StringJuxtaposition(this.first, this.second);
-
- StringJuxtaposition asStringJuxtaposition() => this;
-
- bool get isInterpolation {
- if (isInterpolationCache == null) {
- isInterpolationCache = (first.accept(const IsInterpolationVisitor()) ||
- second.accept(const IsInterpolationVisitor()));
- }
- return isInterpolationCache;
- }
-
- /**
- * Retrieve a single DartString that represents this entire juxtaposition
- * of string literals.
- * Should only be called if [isInterpolation] returns false.
- */
- DartString get dartString {
- if (isInterpolation) {
- failedAt(this, "Getting dartString on interpolation;");
- }
- if (dartStringCache == null) {
- DartString firstString = first.accept(const GetDartStringVisitor());
- DartString secondString = second.accept(const GetDartStringVisitor());
- if (firstString == null || secondString == null) {
- return null;
- }
- dartStringCache = new DartString.concat(firstString, secondString);
- }
- return dartStringCache;
- }
-
- accept(Visitor visitor) => visitor.visitStringJuxtaposition(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitStringJuxtaposition(this, arg);
-
- void visitChildren(Visitor visitor) {
- first.accept(visitor);
- second.accept(visitor);
- }
-
- void visitChildren1(Visitor1 visitor, arg) {
- first.accept1(visitor, arg);
- second.accept1(visitor, arg);
- }
-
- Token getBeginToken() => first.getBeginToken();
-
- Token getEndToken() => second.getEndToken();
-}
-
-class EmptyStatement extends Statement {
- final Token semicolonToken;
-
- EmptyStatement(this.semicolonToken);
-
- EmptyStatement asEmptyStatement() => this;
-
- accept(Visitor visitor) => visitor.visitEmptyStatement(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitEmptyStatement(this, arg);
-
- visitChildren(Visitor visitor) {}
-
- visitChildren1(Visitor1 visitor, arg) {}
-
- Token getBeginToken() => semicolonToken;
-
- Token getEndToken() => semicolonToken;
-}
-
-class LiteralMap extends Expression {
- final NodeList typeArguments;
- final NodeList entries;
-
- final Token constKeyword;
-
- LiteralMap(this.typeArguments, this.entries, this.constKeyword);
-
- bool get isConst => constKeyword != null;
-
- LiteralMap asLiteralMap() => this;
-
- accept(Visitor visitor) => visitor.visitLiteralMap(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralMap(this, arg);
-
- visitChildren(Visitor visitor) {
- if (typeArguments != null) typeArguments.accept(visitor);
- entries.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (typeArguments != null) typeArguments.accept1(visitor, arg);
- entries.accept1(visitor, arg);
- }
-
- Token getBeginToken() {
- if (constKeyword != null) return constKeyword;
- return firstBeginToken(typeArguments, entries);
- }
-
- Token getEndToken() => entries.getEndToken();
-}
-
-class LiteralMapEntry extends Node {
- final Expression key;
- final Expression value;
-
- final Token colonToken;
-
- LiteralMapEntry(this.key, this.colonToken, this.value);
-
- LiteralMapEntry asLiteralMapEntry() => this;
-
- accept(Visitor visitor) => visitor.visitLiteralMapEntry(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLiteralMapEntry(this, arg);
-
- visitChildren(Visitor visitor) {
- key.accept(visitor);
- value.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- key.accept1(visitor, arg);
- value.accept1(visitor, arg);
- }
-
- Token getBeginToken() => key.getBeginToken();
-
- Token getEndToken() => value.getEndToken();
-}
-
-class NamedArgument extends Expression {
- final Identifier name;
- final Expression expression;
-
- final Token colonToken;
-
- NamedArgument(this.name, this.colonToken, this.expression);
-
- NamedArgument asNamedArgument() => this;
-
- accept(Visitor visitor) => visitor.visitNamedArgument(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitNamedArgument(this, arg);
-
- visitChildren(Visitor visitor) {
- name.accept(visitor);
- expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- name.accept1(visitor, arg);
- expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => name.getBeginToken();
-
- Token getEndToken() => expression.getEndToken();
-}
-
-class SwitchStatement extends Statement {
- final ParenthesizedExpression parenthesizedExpression;
- final NodeList cases;
-
- final Token switchKeyword;
-
- SwitchStatement(this.parenthesizedExpression, this.cases, this.switchKeyword);
-
- SwitchStatement asSwitchStatement() => this;
-
- Expression get expression => parenthesizedExpression.expression;
-
- accept(Visitor visitor) => visitor.visitSwitchStatement(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitSwitchStatement(this, arg);
-
- visitChildren(Visitor visitor) {
- parenthesizedExpression.accept(visitor);
- cases.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- parenthesizedExpression.accept1(visitor, arg);
- cases.accept1(visitor, arg);
- }
-
- Token getBeginToken() => switchKeyword;
-
- Token getEndToken() => cases.getEndToken();
-}
-
-class CaseMatch extends Node {
- final Token caseKeyword;
- final Expression expression;
- final Token colonToken;
- CaseMatch(this.caseKeyword, this.expression, this.colonToken);
-
- CaseMatch asCaseMatch() => this;
- Token getBeginToken() => caseKeyword;
- Token getEndToken() => colonToken;
-
- accept(Visitor visitor) => visitor.visitCaseMatch(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitCaseMatch(this, arg);
-
- visitChildren(Visitor visitor) => expression.accept(visitor);
-
- visitChildren1(Visitor1 visitor, arg) => expression.accept1(visitor, arg);
-}
-
-class SwitchCase extends Node {
- // The labels and case patterns are collected in [labelsAndCases].
- // The default keyword, if present, is collected in [defaultKeyword].
- // Any actual switch case must have at least one 'case' or 'default'
- // clause.
- // Notice: The labels and cases can occur interleaved in the source.
- // They are separated here, since the order is irrelevant to the meaning
- // of the switch.
-
- /** List of [Label] and [CaseMatch] nodes. */
- final NodeList labelsAndCases;
- /** A "default" keyword token, if applicable. */
- final Token defaultKeyword;
- /** List of statements, the body of the case. */
- final NodeList statements;
-
- final Token startToken;
-
- SwitchCase(this.labelsAndCases, this.defaultKeyword, this.statements,
- this.startToken);
-
- SwitchCase asSwitchCase() => this;
-
- bool get isDefaultCase => defaultKeyword != null;
-
- bool isValidContinueTarget() => true;
-
- accept(Visitor visitor) => visitor.visitSwitchCase(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitSwitchCase(this, arg);
-
- visitChildren(Visitor visitor) {
- labelsAndCases.accept(visitor);
- statements.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- labelsAndCases.accept1(visitor, arg);
- statements.accept1(visitor, arg);
- }
-
- Token getBeginToken() {
- return startToken;
- }
-
- Token getEndToken() {
- if (statements.nodes.isEmpty) {
- // All cases must have at least one expression or be the default.
- if (defaultKeyword != null) {
- // The colon after 'default'.
- return defaultKeyword.next;
- }
- // The colon after the last expression.
- return labelsAndCases.getEndToken();
- } else {
- return statements.getEndToken();
- }
- }
-}
-
-abstract class GotoStatement extends Statement {
- final Identifier target;
- final Token keywordToken;
- final Token semicolonToken;
-
- GotoStatement(this.target, this.keywordToken, this.semicolonToken);
-
- visitChildren(Visitor visitor) {
- if (target != null) target.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (target != null) target.accept1(visitor, arg);
- }
-
- Token getBeginToken() => keywordToken;
-
- Token getEndToken() => semicolonToken;
-
- // TODO(ahe): make class abstract instead of adding an abstract method.
- accept(Visitor visitor);
-}
-
-class BreakStatement extends GotoStatement {
- BreakStatement(Identifier target, Token keywordToken, Token semicolonToken)
- : super(target, keywordToken, semicolonToken);
-
- BreakStatement asBreakStatement() => this;
-
- accept(Visitor visitor) => visitor.visitBreakStatement(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitBreakStatement(this, arg);
-}
-
-class ContinueStatement extends GotoStatement {
- ContinueStatement(Identifier target, Token keywordToken, Token semicolonToken)
- : super(target, keywordToken, semicolonToken);
-
- ContinueStatement asContinueStatement() => this;
-
- accept(Visitor visitor) => visitor.visitContinueStatement(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitContinueStatement(this, arg);
-}
-
-abstract class ForIn extends Loop {
- final Node declaredIdentifier;
- final Expression expression;
-
- final Token forToken;
- final Token inToken;
-
- ForIn(this.declaredIdentifier, this.expression, Statement body, this.forToken,
- this.inToken)
- : super(body);
-
- Expression get condition => null;
-
- ForIn asForIn() => this;
-
- Token getEndToken() => body.getEndToken();
-}
-
-class SyncForIn extends ForIn with StoredTreeElementMixin {
- SyncForIn(declaredIdentifier, expression, Statement body, forToken, inToken)
- : super(declaredIdentifier, expression, body, forToken, inToken);
-
- SyncForIn asSyncForIn() => this;
-
- accept(Visitor visitor) => visitor.visitSyncForIn(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitSyncForIn(this, arg);
-
- visitChildren(Visitor visitor) {
- declaredIdentifier.accept(visitor);
- expression.accept(visitor);
- body.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- declaredIdentifier.accept1(visitor, arg);
- expression.accept1(visitor, arg);
- body.accept1(visitor, arg);
- }
-
- Token getBeginToken() => forToken;
-}
-
-class AsyncForIn extends ForIn with StoredTreeElementMixin {
- final Token awaitToken;
-
- AsyncForIn(declaredIdentifier, expression, Statement body, this.awaitToken,
- forToken, inToken)
- : super(declaredIdentifier, expression, body, forToken, inToken);
-
- AsyncForIn asAsyncForIn() => this;
-
- accept(Visitor visitor) => visitor.visitAsyncForIn(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitAsyncForIn(this, arg);
-
- visitChildren(Visitor visitor) {
- declaredIdentifier.accept(visitor);
- expression.accept(visitor);
- body.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- declaredIdentifier.accept1(visitor, arg);
- expression.accept1(visitor, arg);
- body.accept1(visitor, arg);
- }
-
- Token getBeginToken() => awaitToken;
-}
-
-class Label extends Node {
- final Identifier identifier;
- final Token colonToken;
-
- Label(this.identifier, this.colonToken);
-
- String get labelName => identifier.source;
-
- Label asLabel() => this;
-
- accept(Visitor visitor) => visitor.visitLabel(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLabel(this, arg);
-
- void visitChildren(Visitor visitor) {
- identifier.accept(visitor);
- }
-
- void visitChildren1(Visitor1 visitor, arg) {
- identifier.accept1(visitor, arg);
- }
-
- Token getBeginToken() => identifier.token;
- Token getEndToken() => colonToken;
-}
-
-class LabeledStatement extends Statement {
- final NodeList labels;
- final Statement statement;
-
- LabeledStatement(this.labels, this.statement);
-
- LabeledStatement asLabeledStatement() => this;
-
- accept(Visitor visitor) => visitor.visitLabeledStatement(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLabeledStatement(this, arg);
-
- visitChildren(Visitor visitor) {
- labels.accept(visitor);
- statement.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- labels.accept1(visitor, arg);
- statement.accept1(visitor, arg);
- }
-
- Token getBeginToken() => labels.getBeginToken();
-
- Token getEndToken() => statement.getEndToken();
-
- bool isValidContinueTarget() => statement.isValidContinueTarget();
-}
-
-abstract class LibraryTag extends Node {
- final List<MetadataAnnotation> metadata;
-
- LibraryTag(this.metadata);
-
- bool get isLibraryName => false;
- bool get isImport => false;
- bool get isExport => false;
- bool get isPart => false;
- bool get isPartOf => false;
-}
-
-class LibraryName extends LibraryTag {
- final Expression name;
-
- final Token libraryKeyword;
-
- LibraryName(this.libraryKeyword, this.name, List<MetadataAnnotation> metadata)
- : super(metadata);
-
- bool get isLibraryName => true;
-
- LibraryName asLibraryName() => this;
-
- accept(Visitor visitor) => visitor.visitLibraryName(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitLibraryName(this, arg);
-
- visitChildren(Visitor visitor) => name.accept(visitor);
-
- visitChildren1(Visitor1 visitor, arg) => name.accept1(visitor, arg);
-
- Token getBeginToken() => libraryKeyword;
-
- Token getEndToken() => name.getEndToken().next;
-}
-
-/**
- * This tag describes a dependency between one library and the exported
- * identifiers of another library. The other library is specified by the [uri].
- * Combinators filter away some identifiers from the other library.
- */
-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;
-}
-
-/**
- * An [:import:] library tag.
- *
- * An import tag is dependency on another library where the exported identifiers
- * are put into the import scope of the importing library. The import scope is
- * only visible inside the library.
- */
-class Import extends LibraryDependency {
- final Identifier prefix;
- final Token importKeyword;
- final bool isDeferred;
-
- Import(this.importKeyword, StringNode uri, NodeList conditionalUris,
- this.prefix, NodeList combinators, List<MetadataAnnotation> metadata,
- {this.isDeferred})
- : super(uri, conditionalUris, combinators, metadata);
-
- bool get isImport => true;
-
- Import asImport() => this;
-
- accept(Visitor visitor) => visitor.visitImport(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitImport(this, arg);
-
- visitChildren(Visitor visitor) {
- uri.accept(visitor);
- if (prefix != null) prefix.accept(visitor);
- if (combinators != null) combinators.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- uri.accept1(visitor, arg);
- if (prefix != null) prefix.accept1(visitor, arg);
- if (combinators != null) combinators.accept1(visitor, arg);
- }
-
- Token getBeginToken() => importKeyword;
-
- 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);
-
- accept1(Visitor1 visitor, arg) => visitor.visitConditionalUri(this, arg);
-
- visitChildren(Visitor visitor) {
- key.accept(visitor);
- if (value != null) value.accept(visitor);
- uri.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- key.accept1(visitor, arg);
- if (value != null) value.accept1(visitor, arg);
- uri.accept1(visitor, arg);
- }
-
- Token getBeginToken() => ifToken;
-
- Token getEndToken() => uri.getEndToken();
-}
-
-/**
- * An `enum` declaration.
- *
- * An `enum` defines a number of named constants inside a non-extensible class
- */
-class Enum extends Node {
- /** The name of the enum class. */
- final Identifier name;
- /** The names of the enum constants. */
- final NodeList names;
- final Token enumToken;
-
- Enum(this.enumToken, this.name, this.names);
-
- Enum asEnum() => this;
-
- accept(Visitor visitor) => visitor.visitEnum(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitEnum(this, arg);
-
- visitChildren(Visitor visitor) {
- name.accept(visitor);
- if (names != null) names.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- name.accept1(visitor, arg);
- if (names != null) names.accept1(visitor, arg);
- }
-
- Token getBeginToken() => enumToken;
- Token getEndToken() => names.getEndToken();
-}
-
-/**
- * An [:export:] library tag.
- *
- * An export tag is dependency on another library where the exported identifiers
- * are put into the export scope of the exporting library. The export scope is
- * not visible inside the library.
- */
-class Export extends LibraryDependency {
- final Token exportKeyword;
-
- Export(this.exportKeyword, StringNode uri, NodeList conditionalUris,
- NodeList combinators, List<MetadataAnnotation> metadata)
- : super(uri, conditionalUris, combinators, metadata);
-
- bool get isExport => true;
-
- Export asExport() => this;
-
- accept(Visitor visitor) => visitor.visitExport(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitExport(this, arg);
-
- visitChildren(Visitor visitor) {
- uri.accept(visitor);
- if (combinators != null) combinators.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- uri.accept1(visitor, arg);
- if (combinators != null) combinators.accept1(visitor, arg);
- }
-
- Token getBeginToken() => exportKeyword;
-
- Token getEndToken() {
- if (combinators != null) return combinators.getEndToken().next;
- if (conditionalUris != null) return conditionalUris.getEndToken().next;
- return uri.getEndToken().next;
- }
-}
-
-class Part extends LibraryTag {
- final StringNode uri;
-
- final Token partKeyword;
-
- Part(this.partKeyword, this.uri, List<MetadataAnnotation> metadata)
- : super(metadata);
-
- bool get isPart => true;
-
- Part asPart() => this;
-
- accept(Visitor visitor) => visitor.visitPart(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitPart(this, arg);
-
- visitChildren(Visitor visitor) => uri.accept(visitor);
-
- visitChildren1(Visitor1 visitor, arg) => uri.accept1(visitor, arg);
-
- Token getBeginToken() => partKeyword;
-
- Token getEndToken() => uri.getEndToken().next;
-}
-
-class PartOf extends Node {
- final Expression name;
-
- final Token partKeyword;
-
- final List<MetadataAnnotation> metadata;
-
- PartOf(this.partKeyword, this.name, this.metadata);
-
- Token get ofKeyword => partKeyword.next;
-
- bool get isPartOf => true;
-
- PartOf asPartOf() => this;
-
- accept(Visitor visitor) => visitor.visitPartOf(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitPartOf(this, arg);
-
- visitChildren(Visitor visitor) => name.accept(visitor);
-
- visitChildren1(Visitor1 visitor, arg) => name.accept1(visitor, arg);
-
- Token getBeginToken() => partKeyword;
-
- Token getEndToken() => name.getEndToken().next;
-}
-
-class Combinator extends Node {
- final NodeList identifiers;
-
- final Token keywordToken;
-
- Combinator(this.identifiers, this.keywordToken);
-
- bool get isShow => identical(keywordToken.stringValue, 'show');
-
- bool get isHide => identical(keywordToken.stringValue, 'hide');
-
- Combinator asCombinator() => this;
-
- accept(Visitor visitor) => visitor.visitCombinator(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitCombinator(this, arg);
-
- visitChildren(Visitor visitor) => identifiers.accept(visitor);
-
- visitChildren1(Visitor1 visitor, arg) => identifiers.accept1(visitor, arg);
-
- Token getBeginToken() => keywordToken;
-
- Token getEndToken() => identifiers.getEndToken();
-}
-
-class Typedef extends Node {
- final bool isGeneralizedTypeAlias;
-
- /// Parameters to the template.
- ///
- /// For example, `T` and `S` are template parameters in the following
- /// typedef: `typedef F<S, T> = Function(S, T)`, or, in the inlined syntax,
- /// `typedef F<S, T>(S x, T y)`.
- final NodeList templateParameters;
-
- final TypeAnnotation returnType;
- final Identifier name;
-
- /// The generic type parameters to the function type.
- ///
- /// For example `A` and `B` (but not `T`) are type parameters in
- /// `typedef F<T> = Function<A, B>(A, B, T)`;
- final NodeList typeParameters;
- final NodeList formals;
-
- final Token typedefKeyword;
- final Token endToken;
-
- Typedef(
- this.isGeneralizedTypeAlias,
- this.templateParameters,
- this.returnType,
- this.name,
- this.typeParameters,
- this.formals,
- this.typedefKeyword,
- this.endToken);
-
- Typedef asTypedef() => this;
-
- accept(Visitor visitor) => visitor.visitTypedef(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitTypedef(this, arg);
-
- visitChildren(Visitor visitor) {
- if (templateParameters != null) templateParameters.accept(visitor);
- if (returnType != null) returnType.accept(visitor);
- name.accept(visitor);
- if (typeParameters != null) typeParameters.accept(visitor);
- formals.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (templateParameters != null) templateParameters.accept1(visitor, arg);
- if (returnType != null) returnType.accept1(visitor, arg);
- name.accept1(visitor, arg);
- if (typeParameters != null) typeParameters.accept1(visitor, arg);
- formals.accept1(visitor, arg);
- }
-
- Token getBeginToken() => typedefKeyword;
-
- Token getEndToken() => endToken;
-}
-
-class FunctionTypeAnnotation extends TypeAnnotation {
- final TypeAnnotation returnType;
- final Token functionToken;
- final NodeList typeParameters;
- final NodeList formals;
-
- FunctionTypeAnnotation(
- this.returnType, this.functionToken, this.typeParameters, this.formals);
-
- FunctionTypeAnnotation asFunctionTypeAnnotation() => this;
-
- accept(Visitor visitor) => visitor.visitFunctionTypeAnnotation(this);
-
- accept1(Visitor1 visitor, arg) {
- return visitor.visitFunctionTypeAnnotation(this, arg);
- }
-
- visitChildren(Visitor visitor) {
- if (returnType != null) returnType.accept(visitor);
- if (typeParameters != null) typeParameters.accept(visitor);
- formals.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (returnType != null) returnType.accept1(visitor, arg);
- if (typeParameters != null) typeParameters.accept1(visitor, arg);
- formals.accept1(visitor, arg);
- }
-
- Token getBeginToken() {
- if (returnType != null) return returnType.getBeginToken();
- return functionToken;
- }
-
- Token getEndToken() => formals.getEndToken();
-}
-
-class TryStatement extends Statement {
- final Block tryBlock;
- final NodeList catchBlocks;
- final Block finallyBlock;
-
- final Token tryKeyword;
- final Token finallyKeyword;
-
- TryStatement(this.tryBlock, this.catchBlocks, this.finallyBlock,
- this.tryKeyword, this.finallyKeyword);
-
- TryStatement asTryStatement() => this;
-
- accept(Visitor visitor) => visitor.visitTryStatement(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitTryStatement(this, arg);
-
- visitChildren(Visitor visitor) {
- tryBlock.accept(visitor);
- catchBlocks.accept(visitor);
- if (finallyBlock != null) finallyBlock.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- tryBlock.accept1(visitor, arg);
- catchBlocks.accept1(visitor, arg);
- if (finallyBlock != null) finallyBlock.accept1(visitor, arg);
- }
-
- Token getBeginToken() => tryKeyword;
-
- Token getEndToken() {
- if (finallyBlock != null) return finallyBlock.getEndToken();
- if (!catchBlocks.isEmpty) return catchBlocks.getEndToken();
- return tryBlock.getEndToken();
- }
-}
-
-class Cascade extends Expression {
- final Expression expression;
- Cascade(this.expression);
-
- Cascade asCascade() => this;
- accept(Visitor visitor) => visitor.visitCascade(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitCascade(this, arg);
-
- void visitChildren(Visitor visitor) {
- expression.accept(visitor);
- }
-
- void visitChildren1(Visitor1 visitor, arg) {
- expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => expression.getBeginToken();
-
- Token getEndToken() => expression.getEndToken();
-}
-
-class CascadeReceiver extends Expression {
- final Expression expression;
- final Token cascadeOperator;
- CascadeReceiver(this.expression, this.cascadeOperator);
-
- CascadeReceiver asCascadeReceiver() => this;
- accept(Visitor visitor) => visitor.visitCascadeReceiver(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitCascadeReceiver(this, arg);
-
- void visitChildren(Visitor visitor) {
- expression.accept(visitor);
- }
-
- void visitChildren1(Visitor1 visitor, arg) {
- expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => expression.getBeginToken();
-
- Token getEndToken() => expression.getEndToken();
-}
-
-class CatchBlock extends Node {
- final TypeAnnotation type;
- final NodeList formals;
- final Block block;
-
- final Token onKeyword;
- final Token catchKeyword;
-
- CatchBlock(
- this.type, this.formals, this.block, this.onKeyword, this.catchKeyword);
-
- CatchBlock asCatchBlock() => this;
-
- accept(Visitor visitor) => visitor.visitCatchBlock(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitCatchBlock(this, arg);
-
- Node get exception {
- if (formals == null || formals.nodes.isEmpty) return null;
- VariableDefinitions declarations = formals.nodes.head;
- return declarations.definitions.nodes.head;
- }
-
- Node get trace {
- if (formals == null || formals.nodes.isEmpty) return null;
- Link<Node> declarations = formals.nodes.tail;
- if (declarations.isEmpty) return null;
- VariableDefinitions head = declarations.head;
- return head.definitions.nodes.head;
- }
-
- visitChildren(Visitor visitor) {
- if (type != null) type.accept(visitor);
- if (formals != null) formals.accept(visitor);
- block.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- if (type != null) type.accept1(visitor, arg);
- if (formals != null) formals.accept1(visitor, arg);
- block.accept1(visitor, arg);
- }
-
- Token getBeginToken() => onKeyword != null ? onKeyword : catchKeyword;
-
- Token getEndToken() => block.getEndToken();
-}
-
-class Metadata extends Node {
- final Token token;
- final Expression expression;
-
- Metadata(this.token, this.expression);
-
- Metadata asMetadata() => this;
-
- accept(Visitor visitor) => visitor.visitMetadata(this);
-
- accept1(Visitor1 visitor, arg) => visitor.visitMetadata(this, arg);
-
- visitChildren(Visitor visitor) {
- expression.accept(visitor);
- }
-
- visitChildren1(Visitor1 visitor, arg) {
- expression.accept1(visitor, arg);
- }
-
- Token getBeginToken() => token;
-
- Token getEndToken() => expression.getEndToken();
-}
-
-class Initializers {
- static bool isSuperConstructorCall(Send node) {
- return (node.receiver == null && node.selector.isSuper()) ||
- (node.receiver != null &&
- node.receiver.isSuper() &&
- !node.isConditional &&
- node.selector.asIdentifier() != null);
- }
-
- static bool isConstructorRedirect(Send node) {
- return (node.receiver == null && node.selector.isThis()) ||
- (node.receiver != null &&
- node.receiver.isThis() &&
- !node.isConditional &&
- node.selector.asIdentifier() != null);
- }
-}
-
-class GetDartStringVisitor extends Visitor<DartString> {
- const GetDartStringVisitor();
- DartString visitNode(Node node) => null;
- DartString visitStringJuxtaposition(StringJuxtaposition node) =>
- node.dartString;
- DartString visitLiteralString(LiteralString node) => node.dartString;
-}
-
-class IsInterpolationVisitor extends Visitor<bool> {
- const IsInterpolationVisitor();
- bool visitNode(Node node) => false;
- bool visitStringInterpolation(StringInterpolation node) => true;
- bool visitStringJuxtaposition(StringJuxtaposition node) =>
- node.isInterpolation;
-}
-
-/// Erroneous node used to recover from parser errors. Implements various
-/// interfaces and provides bare minimum of implementation to avoid unnecessary
-/// messages.
-class ErrorNode extends Node
- implements FunctionExpression, VariableDefinitions, Typedef {
- final Token token;
- final Message message;
- final Identifier name;
- final NodeList definitions;
-
- ErrorNode.internal(this.token, this.message, this.name, this.definitions);
-
- factory ErrorNode(Token token, Message message) {
- Identifier name = new Identifier(token);
- NodeList definitions =
- new NodeList(null, const Link<Node>().prepend(name), null, null);
- return new ErrorNode.internal(token, message, name, definitions);
- }
-
- Token get beginToken => token;
- Token get endToken => token;
-
- Token getBeginToken() => token;
-
- Token getEndToken() => token;
-
- accept(Visitor visitor) {}
-
- accept1(Visitor1 visitor, arg) {}
-
- visitChildren(Visitor visitor) {}
-
- visitChildren1(Visitor1 visitor, arg) {}
-
- bool get isErroneous => true;
-
- // FunctionExpression.
- get asyncModifier => null;
- get typeVariables => null;
- get parameters => null;
- get body => null;
- get returnType => null;
- get modifiers => Modifiers.EMPTY;
- get initializers => null;
- get getOrSet => null;
- get isRedirectingFactory => false;
- bool get hasBody => false;
- bool get hasEmptyBody => false;
-
- // VariableDefinitions.
- get metadata => null;
- get type => null;
-
- // Typedef.
- get isGeneralizedTypeAlias => null;
- get templateParameters => null;
- get typeParameters => null;
- get formals => null;
- get typedefKeyword => null;
-}
-
-/**
- * Encapsulates the field [TreeElementMixin._element].
- *
- * This library is an implementation detail of dart2js, and should not
- * be imported except by resolution and tree node libraries, or for
- * testing.
- *
- * We have taken great care to ensure AST nodes can be cached between
- * compiler instances. Part of this requires that we always access
- * resolution results through TreeElements.
- *
- * So please, do not add additional elements to this library, and do
- * not import it.
- */
-/// Interface for associating
-abstract class TreeElementMixin {
- Object get _element;
- void set _element(Object value);
-}
-
-/// Null implementation of [TreeElementMixin] which does not allow association
-/// of elements.
-///
-/// This class is the superclass of all AST nodes.
-abstract class NullTreeElementMixin implements TreeElementMixin, Spannable {
- // Deliberately using [Object] here to thwart code completion.
- // You're not really supposed to access this field anyways.
- Object get _element => null;
- set _element(_) {
- assert(false,
- failedAt(this, "Elements cannot be associated with ${runtimeType}."));
- }
-}
-
-/// Actual implementation of [TreeElementMixin] which stores the associated
-/// element in the private field [_element].
-///
-/// This class is mixed into the node classes that are actually associated with
-/// elements.
-abstract class StoredTreeElementMixin implements TreeElementMixin {
- Object _element;
-}
-
-/**
- * Do not call this method directly. Instead, use an instance of
- * TreeElements.
- *
- * Using [Object] as return type to thwart code completion.
- */
-Object getTreeElement(TreeElementMixin node) => node._element;
-
-/**
- * Do not call this method directly. Instead, use an instance of
- * TreeElements.
- */
-void setTreeElement(TreeElementMixin node, Object value) {
- node._element = value;
-}
diff --git a/pkg/compiler/lib/src/tree/prettyprint.dart b/pkg/compiler/lib/src/tree/prettyprint.dart
deleted file mode 100644
index a6bdb4c..0000000
--- a/pkg/compiler/lib/src/tree/prettyprint.dart
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../util/util.dart';
-import 'nodes.dart';
-
-/**
- * Pretty-prints Node tree in XML-like format.
- *
- * TODO(smok): Add main() to run from command-line to print out tree for given
- * .dart file.
- */
-class PrettyPrinter extends Indentation with Tagging<Node> implements Visitor {
- @override
- void addDefaultParameters(Node node, Map params) {
- params['getBeginToken'] = tokenToStringOrNull(node.getBeginToken());
- params['getEndToken'] = tokenToStringOrNull(node.getEndToken());
- }
-
- String valueToString(var value) {
- if (value is Token) {
- return value.lexeme;
- }
- return value;
- }
-
- /**
- * Pretty-prints given node tree into string.
- */
- static String prettyPrint(Node node) {
- var p = new PrettyPrinter();
- node.accept(p);
- return p.sb.toString();
- }
-
- visitNodeWithChildren(Node node, String type) {
- openNode(node, type);
- node.visitChildren(this);
- closeNode();
- }
-
- visitAssert(Assert node) {
- visitNodeWithChildren(node, "Assert");
- }
-
- visitAsyncModifier(AsyncModifier node) {
- openAndCloseNode(node, "AsyncModifier",
- {'asyncToken': node.asyncToken, 'starToken': node.starToken});
- }
-
- visitBlock(Block node) {
- visitNodeWithChildren(node, "Block");
- }
-
- visitBreakStatement(BreakStatement node) {
- visitNodeWithChildren(node, "BreakStatement");
- }
-
- visitCascade(Cascade node) {
- visitNodeWithChildren(node, "Cascade");
- }
-
- visitCascadeReceiver(CascadeReceiver node) {
- visitNodeWithChildren(node, "CascadeReceiver");
- }
-
- visitCaseMatch(CaseMatch node) {
- visitNodeWithChildren(node, "CaseMatch");
- }
-
- visitCatchBlock(CatchBlock node) {
- visitNodeWithChildren(node, "CatchBlock");
- }
-
- visitClassNode(ClassNode node) {
- openNode(node, "ClassNode",
- {"extendsKeyword": tokenToStringOrNull(node.extendsKeyword)});
- visitChildNode(node.name, "name");
- visitChildNode(node.superclass, "superclass");
- visitChildNode(node.interfaces, "interfaces");
- visitChildNode(node.typeParameters, "typeParameters");
- closeNode();
- }
-
- visitConditional(Conditional node) {
- 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");
- }
-
- visitEmptyStatement(EmptyStatement node) {
- visitNodeWithChildren(node, "EmptyStatement");
- }
-
- visitEnum(Enum node) {
- visitNodeWithChildren(node, "Enum");
- }
-
- visitExpressionStatement(ExpressionStatement node) {
- visitNodeWithChildren(node, "ExpressionStatement");
- }
-
- visitFor(For node) {
- visitNodeWithChildren(node, "For");
- }
-
- visitForIn(ForIn node) {
- node.visitChildren(this);
- closeNode();
- }
-
- visitAsyncForIn(AsyncForIn node) {
- openNode(node, "AsyncForIn");
- visitForIn(node);
- }
-
- visitSyncForIn(SyncForIn node) {
- openNode(node, "SyncForIn");
- visitForIn(node);
- }
-
- visitFunctionDeclaration(FunctionDeclaration node) {
- visitNodeWithChildren(node, "FunctionDeclaration");
- }
-
- visitFunctionExpression(FunctionExpression node) {
- openNode(node, "FunctionExpression",
- {"getOrSet": tokenToStringOrNull(node.getOrSet)});
- visitChildNode(node.modifiers, "modifiers");
- visitChildNode(node.returnType, "returnType");
- visitChildNode(node.name, "name");
- visitChildNode(node.parameters, "parameters");
- visitChildNode(node.initializers, "initializers");
- visitChildNode(node.body, "body");
- closeNode();
- }
-
- visitFunctionTypeAnnotation(FunctionTypeAnnotation node) {
- openNode(node, "FunctionTypeAnnotation");
- visitChildNode(node.returnType, "returnType");
- visitChildNode(node.typeParameters, "typeParameters");
- visitChildNode(node.formals, "formals");
- closeNode();
- }
-
- visitIdentifier(Identifier node) {
- openAndCloseNode(node, "Identifier", {"token": node.token});
- }
-
- visitIf(If node) {
- visitNodeWithChildren(node, "If");
- }
-
- visitLabel(Label node) {
- visitNodeWithChildren(node, "Label");
- }
-
- visitLabeledStatement(LabeledStatement node) {
- visitNodeWithChildren(node, "LabeledStatement");
- }
-
- // Custom.
- printLiteral(Literal node, String type) {
- openAndCloseNode(node, type, {"value": node.value.toString()});
- }
-
- visitLiteralBool(LiteralBool node) {
- printLiteral(node, "LiteralBool");
- }
-
- visitLiteralDouble(LiteralDouble node) {
- printLiteral(node, "LiteralDouble");
- }
-
- visitLiteralInt(LiteralInt node) {
- printLiteral(node, "LiteralInt");
- }
-
- /** Returns token string value or [:null:] if token is [:null:]. */
- tokenToStringOrNull(Token token) => token == null ? null : token.stringValue;
-
- visitLiteralList(LiteralList node) {
- openNode(node, "LiteralList",
- {"constKeyword": tokenToStringOrNull(node.constKeyword)});
- visitChildNode(node.typeArguments, "typeArguments");
- visitChildNode(node.elements, "elements");
- closeNode();
- }
-
- visitLiteralMap(LiteralMap node) {
- visitNodeWithChildren(node, "LiteralMap");
- }
-
- visitLiteralMapEntry(LiteralMapEntry node) {
- visitNodeWithChildren(node, "LiteralMapEntry");
- }
-
- visitLiteralNull(LiteralNull node) {
- printLiteral(node, "LiteralNull");
- }
-
- visitLiteralString(LiteralString node) {
- openAndCloseNode(node, "LiteralString", {"value": node.token});
- }
-
- visitMixinApplication(MixinApplication node) {
- visitNodeWithChildren(node, "MixinApplication");
- }
-
- visitModifiers(Modifiers node) {
- visitNodeWithChildren(node, "Modifiers");
- }
-
- visitNamedArgument(NamedArgument node) {
- visitNodeWithChildren(node, "NamedArgument");
- }
-
- visitNamedMixinApplication(NamedMixinApplication node) {
- visitNodeWithChildren(node, "NamedMixinApplication");
- }
-
- visitNewExpression(NewExpression node) {
- visitNodeWithChildren(node, "NewExpression");
- }
-
- visitNodeList(NodeList node) {
- var params = {"delimiter": node.delimiter};
- if (node.isEmpty) {
- openAndCloseNode(node, "NodeList", params);
- } else {
- openNode(node, "NodeList", params);
- node.visitChildren(this);
- closeNode();
- }
- }
-
- visitNominalTypeAnnotation(NominalTypeAnnotation node) {
- openNode(node, "NominalTypeAnnotation");
- visitChildNode(node.typeName, "typeName");
- visitChildNode(node.typeArguments, "typeArguments");
- closeNode();
- }
-
- visitOperator(Operator node) {
- openAndCloseNode(node, "Operator", {"value": node.token});
- }
-
- visitParenthesizedExpression(ParenthesizedExpression node) {
- visitNodeWithChildren(node, "ParenthesizedExpression");
- }
-
- visitRedirectingFactoryBody(RedirectingFactoryBody node) {
- openNode(node, "RedirectingFactoryBody");
- visitChildNode(node.constructorReference, "constructorReference");
- closeNode();
- }
-
- visitRethrow(Rethrow node) {
- visitNodeWithChildren(node, "Rethrow");
- }
-
- visitReturn(Return node) {
- openNode(node, "Return");
- visitChildNode(node.expression, "expression");
- closeNode();
- }
-
- visitYield(Yield node) {
- openNode(node, "Yield", {'star': node.starToken});
- visitChildNode(node.expression, "expression");
- closeNode();
- }
-
- visitChildNode(Node node, String fieldName) {
- if (node == null) return;
- addCurrentIndent();
- sb.write("<$fieldName>\n");
- pushTag(fieldName);
- node.accept(this);
- popTag();
- addCurrentIndent();
- sb.write("</$fieldName>\n");
- }
-
- openSendNodeWithFields(Send node, String type) {
- openNode(node, type, {
- "isPrefix": "${node.isPrefix}",
- "isPostfix": "${node.isPostfix}",
- "isIndex": "${node.isIndex}"
- });
- visitChildNode(node.receiver, "receiver");
- visitChildNode(node.selector, "selector");
- visitChildNode(node.argumentsNode, "argumentsNode");
- }
-
- visitSend(Send node) {
- openSendNodeWithFields(node, "Send");
- closeNode();
- }
-
- visitSendSet(SendSet node) {
- openSendNodeWithFields(node, "SendSet");
- visitChildNode(node.assignmentOperator, "assignmentOperator");
- closeNode();
- }
-
- visitStringInterpolation(StringInterpolation node) {
- visitNodeWithChildren(node, "StringInterpolation");
- }
-
- visitStringInterpolationPart(StringInterpolationPart node) {
- visitNodeWithChildren(node, "StringInterpolationPart");
- }
-
- visitStringJuxtaposition(StringJuxtaposition node) {
- visitNodeWithChildren(node, "StringJuxtaposition");
- }
-
- visitSwitchCase(SwitchCase node) {
- visitNodeWithChildren(node, "SwitchCase");
- }
-
- visitSwitchStatement(SwitchStatement node) {
- visitNodeWithChildren(node, "SwitchStatement");
- }
-
- visitLiteralSymbol(LiteralSymbol node) {
- openNode(node, "LiteralSymbol");
- visitChildNode(node.identifiers, "identifiers");
- closeNode();
- }
-
- visitThrow(Throw node) {
- visitNodeWithChildren(node, "Throw");
- }
-
- visitAwait(Await node) {
- visitNodeWithChildren(node, "Await");
- }
-
- visitTryStatement(TryStatement node) {
- visitNodeWithChildren(node, "TryStatement");
- }
-
- visitTypedef(Typedef node) {
- visitNodeWithChildren(node, "Typedef");
- }
-
- visitTypeVariable(TypeVariable node) {
- openNode(node, "TypeVariable");
- visitChildNode(node.name, "name");
- visitChildNode(node.bound, "bound");
- closeNode();
- }
-
- visitVariableDefinitions(VariableDefinitions node) {
- openNode(node, "VariableDefinitions");
- visitChildNode(node.type, "type");
- visitChildNode(node.modifiers, "modifiers");
- visitChildNode(node.definitions, "definitions");
- closeNode();
- }
-
- visitWhile(While node) {
- visitNodeWithChildren(node, "While");
- }
-
- visitMetadata(Metadata node) {
- openNode(node, "Metadata", {"token": node.token});
- visitChildNode(node.expression, "expression");
- closeNode();
- }
-
- visitCombinator(Combinator node) {
- openNode(node, "Combinator",
- {"isShow": "${node.isShow}", "isHide": "${node.isHide}"});
- closeNode();
- }
-
- visitExport(Export node) {
- openNode(node, "Export");
- visitChildNode(node.uri, "uri");
- if (node.conditionalUris != null) {
- visitChildNode(node.conditionalUris, "conditionalUris");
- }
- visitChildNode(node.combinators, "combinators");
- closeNode();
- }
-
- visitImport(Import node) {
- 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");
- }
- closeNode();
- }
-
- visitPart(Part node) {
- openNode(node, "Part");
- visitChildNode(node.uri, "uri");
- closeNode();
- }
-
- visitPartOf(PartOf node) {
- openNode(node, "PartOf");
- visitChildNode(node.name, "name");
- closeNode();
- }
-
- visitLibraryName(LibraryName node) {
- openNode(node, "LibraryName");
- visitChildNode(node.name, "name");
- closeNode();
- }
-
- visitNode(Node node) {
- unimplemented('visitNode', node: node);
- }
-
- visitLibraryDependency(Node node) {
- unimplemented('visitNode', node: node);
- }
-
- visitLibraryTag(LibraryTag node) {
- unimplemented('visitNode', node: node);
- }
-
- visitLiteral(Literal node) {
- unimplemented('visitNode', node: node);
- }
-
- visitLoop(Loop node) {
- unimplemented('visitNode', node: node);
- }
-
- visitPostfix(Postfix node) {
- unimplemented('visitNode', node: node);
- }
-
- visitPrefix(Prefix node) {
- unimplemented('visitNode', node: node);
- }
-
- visitStringNode(StringNode node) {
- unimplemented('visitNode', node: node);
- }
-
- visitStatement(Statement node) {
- unimplemented('visitNode', node: node);
- }
-
- visitExpression(Expression node) {
- unimplemented('visitNode', node: node);
- }
-
- visitGotoStatement(GotoStatement node) {
- unimplemented('visitNode', node: node);
- }
-
- visitTypeAnnotation(TypeAnnotation node) {
- unimplemented('visitNode', node: node);
- }
-
- unimplemented(String message, {Node node}) {
- throw message;
- }
-}
diff --git a/pkg/compiler/lib/src/tree/tree.dart b/pkg/compiler/lib/src/tree/tree.dart
deleted file mode 100644
index 71e9b6d..0000000
--- a/pkg/compiler/lib/src/tree/tree.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library tree;
-
-export 'dartstring.dart';
-export 'nodes.dart';
-export 'prettyprint.dart';
-export 'unparser.dart';
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
deleted file mode 100644
index f6901e9..0000000
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ /dev/null
@@ -1,922 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
- show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN;
-import '../util/util.dart';
-import 'nodes.dart';
-
-String unparse(Node node, {minify: true}) {
- Unparser unparser = new Unparser(minify: minify);
- unparser.unparse(node);
- return unparser.result;
-}
-
-class Unparser extends Indentation implements Visitor {
- final StringBuffer sb = new StringBuffer();
-
- String get result => sb.toString();
-
- Unparser({this.minify: true, this.stripTypes: false});
-
- bool minify;
- bool stripTypes;
-
- void newline() {
- if (!minify) {
- sb.write("\n");
- onEmptyLine = true;
- }
- }
-
- void space([String token = " "]) {
- write(minify ? "" : token);
- }
-
- void addToken(Token token) {
- if (token == null) return;
- write(token.lexeme);
- if (identical(token.kind, Tokens.KEYWORD_TOKEN) ||
- identical(token.kind, Tokens.IDENTIFIER_TOKEN)) {
- write(' ');
- }
- }
-
- bool onEmptyLine = true;
-
- write(object) {
- String s = object.toString();
- if (s == '') return;
- if (onEmptyLine) {
- sb.write(indentation);
- }
- sb.write(s);
- onEmptyLine = false;
- }
-
- unparse(Node node) {
- visit(node);
- }
-
- visit(Node node) {
- if (node != null) node.accept(this);
- }
-
- visitAssert(Assert node) {
- write(node.assertToken.lexeme);
- write('(');
- visit(node.condition);
- if (node.hasMessage) {
- write(',');
- space();
- visit(node.message);
- }
- write(');');
- }
-
- visitBlock(Block node) => unparseBlockStatements(node.statements);
-
- unparseBlockStatements(NodeList statements) {
- addToken(statements.beginToken);
-
- Link<Node> nodes = statements.nodes;
- if (nodes != null && !nodes.isEmpty) {
- indentMore();
- newline();
- visit(nodes.head);
- for (Link link = nodes.tail; !link.isEmpty; link = link.tail) {
- newline();
- visit(link.head);
- }
- indentLess();
- newline();
- }
- if (statements.endToken != null) {
- write(statements.endToken.lexeme);
- }
- }
-
- visitCascade(Cascade node) {
- visit(node.expression);
- }
-
- visitCascadeReceiver(CascadeReceiver node) {
- visit(node.expression);
- }
-
- unparseClassWithBody(ClassNode node, members) {
- if (!node.modifiers.nodes.isEmpty) {
- visit(node.modifiers);
- write(' ');
- }
- write('class ');
- visit(node.name);
- if (node.typeParameters != null) {
- visit(node.typeParameters);
- }
- if (node.extendsKeyword != null) {
- write(' ');
- addToken(node.extendsKeyword);
- visit(node.superclass);
- }
- if (!node.interfaces.isEmpty) {
- write(' ');
- visit(node.interfaces);
- }
- space();
- write('{');
- if (!members.isEmpty) {
- newline();
- indentMore();
- for (Node member in members) {
- visit(member);
- newline();
- }
- indentLess();
- }
- write('}');
- }
-
- visitEnum(Enum node) {
- sb.write('enum ');
- visit(node.name);
- sb.write(' ');
- visit(node.names);
- }
-
- visitClassNode(ClassNode node) {
- unparseClassWithBody(node, node.body.nodes);
- }
-
- visitMixinApplication(MixinApplication node) {
- visit(node.superclass);
- write(' with ');
- visit(node.mixins);
- }
-
- visitNamedMixinApplication(NamedMixinApplication node) {
- if (!node.modifiers.nodes.isEmpty) {
- visit(node.modifiers);
- write(' ');
- }
- write('class ');
- visit(node.name);
- if (node.typeParameters != null) {
- visit(node.typeParameters);
- }
- write(' = ');
- visit(node.mixinApplication);
- if (node.interfaces != null) {
- write(' implements ');
- visit(node.interfaces);
- }
- write(';');
- }
-
- visitConditional(Conditional node) {
- visit(node.condition);
- space();
- write(node.questionToken.lexeme);
- space();
- visit(node.thenExpression);
- space();
- write(node.colonToken.lexeme);
- space();
- visit(node.elseExpression);
- }
-
- visitExpressionStatement(ExpressionStatement node) {
- visit(node.expression);
- write(node.endToken.lexeme);
- }
-
- visitFor(For node) {
- write(node.forToken.lexeme);
- space();
- write('(');
- visit(node.initializer);
- write(';');
- if (node.conditionStatement is! EmptyStatement) space();
- visit(node.conditionStatement);
- if (!node.update.nodes.isEmpty) space();
- visit(node.update);
- write(')');
- space();
- visit(node.body);
- }
-
- visitFunctionDeclaration(FunctionDeclaration node) {
- visit(node.function);
- }
-
- void unparseFunctionName(Node name) {
- // TODO(antonm): that's a workaround as currently FunctionExpression
- // names are modelled with Send and it emits operator[] as only
- // operator, without [] which are expected to be emitted with
- // arguments.
- if (name is Send) {
- Send send = name;
- assert(send is! SendSet);
- if (!send.isOperator) {
- // Looks like a factory method.
- visit(send.receiver);
- write('.');
- } else {
- visit(send.receiver);
- Identifier identifier = send.selector.asIdentifier();
- if (identical(identifier.token.kind, Tokens.KEYWORD_TOKEN)) {
- write(' ');
- } else if (identifier.source == 'negate') {
- // TODO(ahe): Remove special case for negate.
- write(' ');
- }
- }
- visit(send.selector);
- } else {
- visit(name);
- }
- }
-
- visitAsyncModifier(AsyncModifier node) {
- write(node.asyncToken.lexeme);
- if (node.starToken != null) {
- write(node.starToken.lexeme);
- }
- }
-
- visitFunctionExpression(FunctionExpression node) {
- if (!node.modifiers.nodes.isEmpty) {
- visit(node.modifiers);
- write(' ');
- }
- if (node.returnType != null && !stripTypes) {
- visit(node.returnType);
- write(' ');
- }
- if (node.getOrSet != null) {
- write(node.getOrSet.lexeme);
- write(' ');
- }
- unparseFunctionName(node.name);
- visit(node.typeVariables);
- visit(node.parameters);
- if (node.initializers != null) {
- space();
- write(':');
- space();
- unparseNodeListFrom(node.initializers, node.initializers.nodes,
- spaces: true);
- }
- if (node.asyncModifier != null) {
- if (node.getOrSet != null) {
- write(' ');
- } else {
- // Space is optional if this is not a getter.
- space();
- }
- visit(node.asyncModifier);
- }
- if (node.body != null && node.body is! EmptyStatement) {
- space();
- }
- visit(node.body);
- }
-
- visitIdentifier(Identifier node) {
- write(node.token.lexeme);
- }
-
- visitIf(If node) {
- write(node.ifToken.lexeme);
- space();
- visit(node.condition);
- space();
- visit(node.thenPart);
- if (node.hasElsePart) {
- space();
- write(node.elseToken.lexeme);
- space();
- if (node.elsePart is! Block && minify) write(' ');
- visit(node.elsePart);
- }
- }
-
- visitLiteralBool(LiteralBool node) {
- write(node.token.lexeme);
- }
-
- visitLiteralDouble(LiteralDouble node) {
- write(node.token.lexeme);
- // -Lit is represented as a send.
- if (node.token.kind == Tokens.PLUS_TOKEN) write(node.token.next.lexeme);
- }
-
- visitLiteralInt(LiteralInt node) {
- write(node.token.lexeme);
- // -Lit is represented as a send.
- if (node.token.kind == Tokens.PLUS_TOKEN) write(node.token.next.lexeme);
- }
-
- visitLiteralString(LiteralString node) {
- write(node.token.lexeme);
- }
-
- visitStringJuxtaposition(StringJuxtaposition node) {
- visit(node.first);
- write(" ");
- visit(node.second);
- }
-
- visitLiteralNull(LiteralNull node) {
- write(node.token.lexeme);
- }
-
- visitLiteralSymbol(LiteralSymbol node) {
- write(node.hashToken.lexeme);
- unparseNodeListOfIdentifiers(node.identifiers);
- }
-
- unparseNodeListOfIdentifiers(NodeList node) {
- // Manually print the list to avoid spaces around operators in unminified
- // code.
- Link<Node> l = node.nodes;
- write(l.head.asIdentifier().token.lexeme);
- for (l = l.tail; !l.isEmpty; l = l.tail) {
- write(".");
- write(l.head.asIdentifier().token.lexeme);
- }
- }
-
- visitNewExpression(NewExpression node) {
- addToken(node.newToken);
- visit(node.send);
- }
-
- visitLiteralList(LiteralList node) {
- if (node.constKeyword != null) write(node.constKeyword.lexeme);
- visit(node.typeArguments);
- visit(node.elements);
- // If list is empty, emit space after [] to disambiguate cases like []==[].
- if (minify && node.elements.isEmpty) write(' ');
- }
-
- visitModifiers(Modifiers node) {
- // Spaces are already included as delimiter.
- unparseNodeList(node.nodes, spaces: false);
- }
-
- /**
- * Unparses given NodeList starting from specific node.
- */
- unparseNodeListFrom(NodeList node, Link<Node> from, {bool spaces: true}) {
- if (from.isEmpty) return;
- String delimiter = (node.delimiter == null) ? "" : "${node.delimiter}";
- visit(from.head);
- for (Link link = from.tail; !link.isEmpty; link = link.tail) {
- write(delimiter);
- if (spaces) space();
- visit(link.head);
- }
- }
-
- unparseNodeList(NodeList node, {bool spaces: true}) {
- addToken(node.beginToken);
- if (node.nodes != null) {
- unparseNodeListFrom(node, node.nodes, spaces: spaces);
- }
- // If the NodeList is a single "[]" token
- // then beginToken == endToken and only write beginToken.
- if (node.endToken != null && node.endToken != node.beginToken) {
- write(node.endToken.lexeme);
- }
- }
-
- visitNodeList(NodeList node) {
- unparseNodeList(node);
- }
-
- visitOperator(Operator node) {
- visitIdentifier(node);
- }
-
- visitRedirectingFactoryBody(RedirectingFactoryBody node) {
- space();
- write(node.beginToken.lexeme);
- space();
- visit(node.constructorReference);
- write(node.endToken.lexeme);
- }
-
- visitRethrow(Rethrow node) {
- write('rethrow;');
- }
-
- visitReturn(Return node) {
- write(node.beginToken.lexeme);
- if (node.hasExpression && node.beginToken.stringValue != '=>') {
- write(' ');
- }
- if (node.beginToken.stringValue == '=>') space();
- visit(node.expression);
- if (node.endToken != null) write(node.endToken.lexeme);
- }
-
- visitYield(Yield node) {
- write(node.yieldToken.lexeme);
- if (node.starToken != null) {
- write(node.starToken.lexeme);
- }
- write(' ');
- visit(node.expression);
- write(node.endToken.lexeme);
- }
-
- unparseSendReceiver(Send node, {bool spacesNeeded: false}) {
- if (node.receiver == null) return;
- visit(node.receiver);
- CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver();
- if (asCascadeReceiver != null) {
- newline();
- indentMore();
- indentMore();
- write(asCascadeReceiver.cascadeOperator.lexeme);
- indentLess();
- indentLess();
- } else if (node.selector.asOperator() == null) {
- write(node.isConditional ? '?.' : '.');
- } else if (spacesNeeded) {
- write(' ');
- }
- }
-
- unparseSendArgument(Send node, {bool spacesNeeded: false}) {
- if (node.argumentsNode == null) return;
-
- if (node.isIsNotCheck) {
- Send argNode = node.arguments.head;
- visit(argNode.selector);
- space();
- visit(argNode.receiver);
- } else {
- if (spacesNeeded) write(' ');
- visit(node.typeArgumentsNode);
- visit(node.argumentsNode);
- }
- }
-
- visitSend(Send node) {
- Operator op = node.selector.asOperator();
- String opString = op != null ? op.source : null;
- bool spacesNeeded = minify
- ? identical(opString, 'is') || identical(opString, 'as')
- : (opString != null && !node.isPrefix && !node.isIndex);
-
- void minusMinusSpace(Node other) {
- if (other != null && opString == '-') {
- Token beginToken = other.getBeginToken();
- if (beginToken != null &&
- beginToken.stringValue != null &&
- beginToken.stringValue.startsWith('-')) {
- sb.write(' ');
- spacesNeeded = false;
- }
- }
- }
-
- if (node.isPrefix) {
- visit(node.selector);
- // Add a space for sequences like - -x (double unary minus).
- minusMinusSpace(node.receiver);
- }
-
- unparseSendReceiver(node, spacesNeeded: spacesNeeded);
- if (!node.isPrefix && !node.isIndex) {
- visit(node.selector);
- }
- minusMinusSpace(node.argumentsNode);
-
- unparseSendArgument(node, spacesNeeded: spacesNeeded);
- }
-
- visitSendSet(SendSet node) {
- if (node.isPrefix) {
- if (minify) {
- write(' ');
- }
- visit(node.assignmentOperator);
- }
- unparseSendReceiver(node);
- if (node.isIndex) {
- write('[');
- visit(node.arguments.head);
- write(']');
- if (!node.isPrefix) {
- if (!node.isPostfix) {
- space();
- }
- visit(node.assignmentOperator);
- if (!node.isPostfix) {
- space();
- }
- }
- unparseNodeListFrom(node.argumentsNode, node.argumentsNode.nodes.tail);
- } else {
- visit(node.selector);
- if (!node.isPrefix) {
- if (!node.isPostfix && node.assignmentOperator.source != ':') {
- space();
- }
- visit(node.assignmentOperator);
- if (!node.isPostfix) {
- space();
- }
- if (minify && node.assignmentOperator.source != '=') {
- write(' ');
- }
- }
- visit(node.argumentsNode);
- }
- }
-
- visitThrow(Throw node) {
- write(node.throwToken.lexeme);
- write(' ');
- visit(node.expression);
- }
-
- visitAwait(Await node) {
- write(node.awaitToken.lexeme);
- write(' ');
- visit(node.expression);
- }
-
- visitNominalTypeAnnotation(NominalTypeAnnotation node) {
- visit(node.typeName);
- visit(node.typeArguments);
- }
-
- visitFunctionTypeAnnotation(FunctionTypeAnnotation node) {
- visit(node.returnType);
- write(' Function');
- visit(node.typeParameters);
- visit(node.formals);
- }
-
- visitTypeVariable(TypeVariable node) {
- visit(node.name);
- if (node.bound != null) {
- write(' extends ');
- visit(node.bound);
- }
- }
-
- visitVariableDefinitions(VariableDefinitions node) {
- if (node.metadata != null) {
- visit(node.metadata);
- write(' ');
- }
- visit(node.modifiers);
- if (!node.modifiers.nodes.isEmpty) {
- write(' ');
- }
- // TODO(sigurdm): Avoid writing the space when [stripTypes], but still write
- // it if the 'type; is var.
- if (node.type != null) {
- visit(node.type);
- write(' ');
- }
- visit(node.definitions);
- }
-
- visitDoWhile(DoWhile node) {
- write(node.doKeyword.lexeme);
- if (node.body is! Block) {
- write(' ');
- } else {
- space();
- }
- visit(node.body);
- space();
- write(node.whileKeyword.lexeme);
- space();
- visit(node.condition);
- write(node.endToken.lexeme);
- }
-
- visitWhile(While node) {
- write(node.whileKeyword.lexeme);
- space();
- visit(node.condition);
- space();
- visit(node.body);
- }
-
- visitParenthesizedExpression(ParenthesizedExpression node) {
- write(node.getBeginToken().lexeme);
- visit(node.expression);
- write(node.getEndToken().lexeme);
- }
-
- visitStringInterpolation(StringInterpolation node) {
- visit(node.string);
- unparseNodeList(node.parts, spaces: false);
- }
-
- visitStringInterpolationPart(StringInterpolationPart node) {
- write('\${'); // TODO(ahe): Preserve the real tokens.
- visit(node.expression);
- write('}');
- visit(node.string);
- }
-
- visitEmptyStatement(EmptyStatement node) {
- write(node.semicolonToken.lexeme);
- }
-
- visitGotoStatement(GotoStatement node) {
- write(node.keywordToken.lexeme);
- if (node.target != null) {
- write(' ');
- visit(node.target);
- }
- write(node.semicolonToken.lexeme);
- }
-
- visitBreakStatement(BreakStatement node) {
- visitGotoStatement(node);
- }
-
- visitContinueStatement(ContinueStatement node) {
- visitGotoStatement(node);
- }
-
- visitForIn(ForIn node) {
- write(node.forToken.lexeme);
- space();
- write('(');
- visit(node.declaredIdentifier);
- write(' ');
- addToken(node.inToken);
- visit(node.expression);
- write(')');
- space();
- visit(node.body);
- }
-
- visitAsyncForIn(AsyncForIn node) {
- write(node.awaitToken.lexeme);
- write(' ');
- visitForIn(node);
- }
-
- visitSyncForIn(SyncForIn node) {
- visitForIn(node);
- }
-
- visitLabel(Label node) {
- visit(node.identifier);
- write(node.colonToken.lexeme);
- }
-
- visitLabeledStatement(LabeledStatement node) {
- visit(node.labels);
- visit(node.statement);
- }
-
- visitLiteralMap(LiteralMap node) {
- if (node.constKeyword != null) write(node.constKeyword.lexeme);
- if (node.typeArguments != null) visit(node.typeArguments);
- visit(node.entries);
- }
-
- visitLiteralMapEntry(LiteralMapEntry node) {
- visit(node.key);
- write(node.colonToken.lexeme);
- space();
- visit(node.value);
- }
-
- visitNamedArgument(NamedArgument node) {
- visit(node.name);
- write(node.colonToken.lexeme);
- space();
- visit(node.expression);
- }
-
- visitSwitchStatement(SwitchStatement node) {
- addToken(node.switchKeyword);
- visit(node.parenthesizedExpression);
- space();
- unparseNodeList(node.cases, spaces: false);
- }
-
- visitSwitchCase(SwitchCase node) {
- newline();
- indentMore();
- visit(node.labelsAndCases);
- if (node.isDefaultCase) {
- write('default:');
- }
- unparseBlockStatements(node.statements);
- indentLess();
- }
-
- unparseLibraryName(String libraryName) {
- write('library $libraryName;');
- newline();
- }
-
- unparseImportTag(String uri,
- {String prefix,
- List<String> shows: const <String>[],
- bool isDeferred: false}) {
- String deferredString = isDeferred ? ' deferred' : '';
- String prefixString = prefix == null ? '' : ' as $prefix';
- String showString = shows.isEmpty ? '' : ' show ${shows.join(", ")}';
- write('import "$uri"$deferredString$prefixString$showString;');
- newline();
- }
-
- unparseExportTag(String uri, {List<String> shows: const []}) {
- String suffix = shows.isEmpty ? '' : ' show ${shows.join(", ")}';
- write('export "$uri"$suffix;');
- newline();
- }
-
- visitTryStatement(TryStatement node) {
- addToken(node.tryKeyword);
- visit(node.tryBlock);
- visit(node.catchBlocks);
- if (node.finallyKeyword != null) {
- space();
- addToken(node.finallyKeyword);
- visit(node.finallyBlock);
- }
- }
-
- visitCaseMatch(CaseMatch node) {
- addToken(node.caseKeyword);
- visit(node.expression);
- write(node.colonToken.lexeme);
- }
-
- visitCatchBlock(CatchBlock node) {
- addToken(node.onKeyword);
- if (node.type != null) {
- visit(node.type);
- write(' ');
- }
- space();
- addToken(node.catchKeyword);
- visit(node.formals);
- space();
- visit(node.block);
- }
-
- visitTypedef(Typedef node) {
- addToken(node.typedefKeyword);
- if (node.returnType != null) {
- visit(node.returnType);
- write(' ');
- }
- visit(node.name);
- if (node.templateParameters != null) {
- visit(node.templateParameters);
- }
- visit(node.formals);
- write(node.endToken.lexeme);
- }
-
- visitLibraryName(LibraryName node) {
- addToken(node.libraryKeyword);
- node.visitChildren(this);
- write(node.getEndToken().lexeme);
- newline();
- }
-
- visitConditionalUri(ConditionalUri node) {
- write(node.ifToken.lexeme);
- 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');
- }
- if (node.prefix != null) {
- write(' as ');
- visit(node.prefix);
- }
- if (node.combinators != null) {
- write(' ');
- visit(node.combinators);
- }
- write(node.getEndToken().lexeme);
- newline();
- }
-
- visitExport(Export node) {
- addToken(node.exportKeyword);
- visit(node.uri);
- if (node.hasConditionalUris) {
- write(' ');
- visitNodeList(node.conditionalUris);
- }
- if (node.combinators != null) {
- write(' ');
- visit(node.combinators);
- }
- write(node.getEndToken().lexeme);
- newline();
- }
-
- visitPart(Part node) {
- addToken(node.partKeyword);
- visit(node.uri);
- write(node.getEndToken().lexeme);
- }
-
- visitPartOf(PartOf node) {
- addToken(node.partKeyword);
- addToken(node.ofKeyword);
- visit(node.name);
- write(node.getEndToken().lexeme);
- }
-
- visitCombinator(Combinator node) {
- addToken(node.keywordToken);
- visit(node.identifiers);
- }
-
- visitMetadata(Metadata node) {
- addToken(node.token);
- visit(node.expression);
- }
-
- visitNode(Node node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitExpression(Expression node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitLibraryTag(LibraryTag node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitLibraryDependency(Node node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitLiteral(Literal node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitLoop(Loop node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitPostfix(Postfix node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitPrefix(Prefix node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitStatement(Statement node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitStringNode(StringNode node) {
- throw 'internal error'; // Should not be called.
- }
-
- visitTypeAnnotation(TypeAnnotation node) {
- throw 'internal error'; // Should not be called.
- }
-}
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
deleted file mode 100644
index 5709a40..0000000
--- a/pkg/compiler/lib/src/typechecker.dart
+++ /dev/null
@@ -1,2064 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.typechecker;
-
-import 'common/names.dart' show Identifiers;
-import 'common/resolution.dart' show Resolution;
-import 'common/tasks.dart' show CompilerTask;
-import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constants/expressions.dart';
-import 'constants/values.dart';
-import 'common_elements.dart';
-import 'elements/resolution_types.dart';
-import 'elements/elements.dart'
- show
- AbstractFieldElement,
- AstElement,
- ClassElement,
- ConstructorElement,
- Element,
- Elements,
- EnumClassElement,
- EnumConstantElement,
- ExecutableElement,
- FieldElement,
- FormalElement,
- FunctionElement,
- GetterElement,
- InitializingFormalElement,
- LibraryElement,
- MemberSignature,
- ResolvedAst,
- SetterElement,
- TypeDeclarationElement,
- TypedElement,
- VariableElement;
-import 'elements/entities.dart' show AsyncMarker;
-import 'elements/names.dart';
-import 'enqueue.dart' show DeferredAction;
-import 'resolution/class_members.dart' show MembersCreator, ErroneousMember;
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'tree/tree.dart';
-import 'util/util.dart' show Link, LinkBuilder;
-
-class TypeCheckerTask extends CompilerTask {
- final Compiler compiler;
- TypeCheckerTask(Compiler compiler)
- : compiler = compiler,
- super(compiler.measurer);
-
- String get name => "Type checker";
- DiagnosticReporter get reporter => compiler.reporter;
-
- void check(AstElement element) {
- if (element.isClass) return;
- if (element.isTypedef) return;
- ResolvedAst resolvedAst = element.resolvedAst;
- reporter.withCurrentElement(element.implementation, () {
- measure(() {
- TypeCheckerVisitor visitor = new TypeCheckerVisitor(
- compiler, resolvedAst.elements, compiler.resolution.types);
- if (element.isField) {
- visitor.analyzingInitializer = true;
- ResolutionDartType type =
- visitor.analyzeVariableTypeAnnotation(resolvedAst.node);
- visitor.analyzeVariableInitializer(element, type, resolvedAst.body);
- } else {
- resolvedAst.node.accept(visitor);
- }
- });
- });
- }
-}
-
-/**
- * Class used to report different warnings for different kinds of members.
- */
-class MemberKind {
- static const MemberKind METHOD = const MemberKind("method");
- static const MemberKind OPERATOR = const MemberKind("operator");
- static const MemberKind GETTER = const MemberKind("getter");
- static const MemberKind SETTER = const MemberKind("setter");
-
- final String name;
-
- const MemberKind(this.name);
-
- String toString() => name;
-}
-
-/**
- * [ElementAccess] represents the access of [element], either as a property
- * access or invocation.
- */
-abstract class ElementAccess {
- Element get element;
-
- String get name => element.name;
-
- ResolutionDartType computeType(Resolution resolution);
-
- /// Returns [: true :] if the element can be access as an invocation.
- bool isCallable(Compiler compiler) {
- if (element != null && element.isAbstractField) {
- AbstractFieldElement abstractFieldElement = element;
- if (abstractFieldElement.getter == null) {
- // Setters cannot be invoked as function invocations.
- return false;
- }
- }
- ResolutionInterfaceType functionType =
- compiler.resolution.commonElements.functionType;
- return compiler.resolution.types
- .isAssignable(computeType(compiler.resolution), functionType);
- }
-}
-
-/// An access of a instance member.
-class MemberAccess extends ElementAccess {
- final MemberSignature member;
-
- MemberAccess(MemberSignature this.member);
-
- Element get element => member.declarations.first.element;
-
- ResolutionDartType computeType(Resolution resolution) => member.type;
-
- String toString() => 'MemberAccess($member)';
-}
-
-/// An access of an unresolved element.
-class DynamicAccess implements ElementAccess {
- const DynamicAccess();
-
- Element get element => null;
-
- String get name => 'dynamic';
-
- ResolutionDartType computeType(Resolution resolution) =>
- const ResolutionDynamicType();
-
- bool isCallable(Compiler compiler) => true;
-
- String toString() => 'DynamicAccess';
-}
-
-/**
- * An access of a resolved top-level or static property or function, or an
- * access of a resolved element through [:this:].
- */
-class ResolvedAccess extends ElementAccess {
- final Element element;
-
- ResolvedAccess(Element this.element) {
- assert(element != null);
- }
-
- ResolutionDartType computeType(Resolution resolution) {
- if (element.isGetter) {
- GetterElement getter = element;
- ResolutionFunctionType functionType = getter.computeType(resolution);
- return functionType.returnType;
- } else if (element.isSetter) {
- SetterElement setter = element;
- ResolutionFunctionType functionType = setter.computeType(resolution);
- if (functionType.parameterTypes.length != 1) {
- // TODO(johnniwinther,karlklose): this happens for malformed static
- // setters. Treat them the same as instance members.
- return const ResolutionDynamicType();
- }
- return functionType.parameterTypes.first;
- } else if (element.isTypedef || element.isClass) {
- TypeDeclarationElement typeDeclaration = element;
- typeDeclaration.computeType(resolution);
- return typeDeclaration.thisType;
- } else {
- TypedElement typedElement = element;
- typedElement.computeType(resolution);
- return typedElement.type;
- }
- }
-
- String toString() => 'ResolvedAccess($element)';
-}
-
-/// An access to a promoted variable.
-class PromotedAccess extends ElementAccess {
- final VariableElement element;
- final ResolutionDartType type;
-
- PromotedAccess(VariableElement this.element, ResolutionDartType this.type) {
- assert(element != null);
- assert(type != null);
- }
-
- ResolutionDartType computeType(Resolution resolution) => type;
-
- String toString() => 'PromotedAccess($element,$type)';
-}
-
-/**
- * An access of a resolved top-level or static property or function, or an
- * access of a resolved element through [:this:].
- */
-class TypeAccess extends ElementAccess {
- final ResolutionDartType type;
- TypeAccess(ResolutionDartType this.type) {
- assert(type != null);
- }
-
- Element get element => type.element;
-
- ResolutionDartType computeType(Resolution resolution) => type;
-
- String toString() => 'TypeAccess($type)';
-}
-
-/**
- * An access of a type literal.
- */
-class TypeLiteralAccess extends ElementAccess {
- final ResolutionDartType type;
-
- TypeLiteralAccess(this.type) {
- assert(type != null);
- }
-
- Element get element => type.element;
-
- String get name => type.name;
-
- ResolutionInterfaceType computeType(Resolution resolution) =>
- resolution.commonElements.typeType;
-
- String toString() => 'TypeLiteralAccess($type)';
-}
-
-/// An access to the 'call' method of a function type.
-class FunctionCallAccess implements ElementAccess {
- final Element element;
- final ResolutionDartType type;
-
- const FunctionCallAccess(this.element, this.type);
-
- String get name => 'call';
-
- ResolutionDartType computeType(Resolution resolution) => type;
-
- bool isCallable(Compiler compiler) => true;
-
- String toString() => 'FunctionAccess($element, $type)';
-}
-
-/// An is-expression that potentially promotes a variable.
-class TypePromotion {
- final Send node;
- final VariableElement variable;
- final ResolutionDartType type;
- final List<TypePromotionMessage> messages = <TypePromotionMessage>[];
-
- TypePromotion(this.node, this.variable, this.type);
-
- bool get isValid => messages.isEmpty;
-
- TypePromotion copy() {
- return new TypePromotion(node, variable, type)..messages.addAll(messages);
- }
-
- void addHint(DiagnosticMessage hint,
- [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
- messages.add(new TypePromotionMessage(hint, infos));
- }
-
- String toString() {
- return 'Promote ${variable} to ${type}${isValid ? '' : ' (invalid)'}';
- }
-}
-
-/// A hint or info message attached to a type promotion.
-class TypePromotionMessage {
- DiagnosticMessage hint;
- List<DiagnosticMessage> infos;
-
- TypePromotionMessage(this.hint, this.infos);
-}
-
-class TypeCheckerVisitor extends Visitor<ResolutionDartType> {
- final Compiler compiler;
- final TreeElements elements;
- final Types types;
-
- Node lastSeenNode;
- ResolutionDartType expectedReturnType;
- AsyncMarker currentAsyncMarker = AsyncMarker.SYNC;
-
- final ClassElement currentClass;
-
- /// The immediately enclosing field, method or constructor being analyzed.
- ExecutableElement executableContext;
-
- CommonElements get commonElements => resolution.commonElements;
-
- DiagnosticReporter get reporter => compiler.reporter;
-
- Resolution get resolution => compiler.resolution;
-
- ResolutionInterfaceType get intType => commonElements.intType;
- ResolutionInterfaceType get doubleType => commonElements.doubleType;
- ResolutionInterfaceType get boolType => commonElements.boolType;
- ResolutionInterfaceType get stringType => commonElements.stringType;
-
- ResolutionDartType thisType;
- ResolutionDartType superType;
-
- Link<ResolutionDartType> cascadeTypes = const Link<ResolutionDartType>();
-
- bool analyzingInitializer = false;
-
- Map<Node, List<TypePromotion>> shownTypePromotionsMap =
- new Map<Node, List<TypePromotion>>();
-
- Map<VariableElement, Link<TypePromotion>> typePromotionsMap =
- new Map<VariableElement, Link<TypePromotion>>();
-
- Set<TypePromotion> reportedTypePromotions = new Set<TypePromotion>();
-
- void showTypePromotion(Node node, TypePromotion typePromotion) {
- List<TypePromotion> shownTypePromotions =
- shownTypePromotionsMap.putIfAbsent(node, () => <TypePromotion>[]);
- shownTypePromotions.add(typePromotion);
- }
-
- void registerKnownTypePromotion(TypePromotion typePromotion) {
- VariableElement variable = typePromotion.variable;
- Link<TypePromotion> knownTypes = typePromotionsMap.putIfAbsent(
- variable, () => const Link<TypePromotion>());
- typePromotionsMap[variable] = knownTypes.prepend(typePromotion);
- }
-
- void unregisterKnownTypePromotion(TypePromotion typePromotion) {
- VariableElement variable = typePromotion.variable;
- Link<TypePromotion> knownTypes = typePromotionsMap[variable].tail;
- if (knownTypes.isEmpty) {
- typePromotionsMap.remove(variable);
- } else {
- typePromotionsMap[variable] = knownTypes;
- }
- }
-
- List<TypePromotion> getShownTypePromotionsFor(Node node) {
- List<TypePromotion> shownTypePromotions = shownTypePromotionsMap[node];
- return shownTypePromotions != null ? shownTypePromotions : const [];
- }
-
- TypePromotion getKnownTypePromotion(VariableElement element) {
- Link<TypePromotion> promotions = typePromotionsMap[element];
- if (promotions != null) {
- while (!promotions.isEmpty) {
- TypePromotion typePromotion = promotions.head;
- if (typePromotion.isValid) {
- return typePromotion;
- }
- promotions = promotions.tail;
- }
- }
- return null;
- }
-
- ResolutionDartType getKnownType(VariableElement element) {
- TypePromotion typePromotion = getKnownTypePromotion(element);
- if (typePromotion != null) return typePromotion.type;
- return element.type;
- }
-
- TypeCheckerVisitor(this.compiler, TreeElements elements, this.types)
- : this.elements = elements,
- this.executableContext = elements.analyzedElement,
- this.currentClass = elements.analyzedElement != null
- ? elements.analyzedElement.enclosingClass
- : null {
- if (currentClass != null) {
- thisType = currentClass.thisType;
- superType = currentClass.supertype;
- } else {
- // If these are used, an error should have been reported by the resolver.
- thisType = const ResolutionDynamicType();
- superType = const ResolutionDynamicType();
- }
- }
-
- LibraryElement get currentLibrary => elements.analyzedElement.library;
-
- reportTypeWarning(Spannable spannable, MessageKind kind,
- [Map arguments = const {}]) {
- reporter.reportWarningMessage(spannable, kind, arguments);
- }
-
- reportMessage(Spannable spannable, MessageKind kind, Map arguments,
- {bool isHint: false}) {
- if (isHint) {
- reporter.reportHintMessage(spannable, kind, arguments);
- } else {
- reporter.reportWarningMessage(spannable, kind, arguments);
- }
- }
-
- reportTypePromotionHint(TypePromotion typePromotion) {
- if (!reportedTypePromotions.contains(typePromotion)) {
- reportedTypePromotions.add(typePromotion);
- for (TypePromotionMessage message in typePromotion.messages) {
- reporter.reportHint(message.hint, message.infos);
- }
- }
- }
-
- // TODO(karlklose): remove these functions.
- ResolutionDartType unhandledExpression() => const ResolutionDynamicType();
-
- ResolutionDartType analyzeNonVoid(Node node) {
- ResolutionDartType type = analyze(node);
- if (type.isVoid) {
- reportTypeWarning(node, MessageKind.VOID_EXPRESSION);
- }
- return type;
- }
-
- ResolutionDartType analyzeWithDefault(
- Node node, ResolutionDartType defaultValue) {
- return node != null ? analyze(node) : defaultValue;
- }
-
- /// If [inInitializer] is true, assignment should be interpreted as write to
- /// a field and not to a setter.
- ResolutionDartType analyze(Node node,
- {bool inInitializer: false, bool mustHaveType: true}) {
- if (node == null) {
- final String error = 'Unexpected node: null';
- if (lastSeenNode != null) {
- reporter.internalError(lastSeenNode, error);
- } else {
- reporter.internalError(executableContext, error);
- }
- } else {
- lastSeenNode = node;
- }
- bool previouslyInitializer = analyzingInitializer;
- analyzingInitializer = inInitializer;
- ResolutionDartType result = node.accept(this);
- analyzingInitializer = previouslyInitializer;
- if (result == null && mustHaveType) {
- reporter.internalError(node, 'Type is null.');
- }
- return result;
- }
-
- void analyzeUntyped(Node node, {bool inInitializer: false}) {
- if (node != null) {
- analyze(node, inInitializer: inInitializer, mustHaveType: false);
- }
- }
-
- void checkTypePromotion(Node node, TypePromotion typePromotion,
- {bool checkAccesses: false}) {
- VariableElement variable = typePromotion.variable;
- String variableName = variable.name;
- List<Node> potentialMutationsIn =
- elements.getPotentialMutationsIn(node, variable);
- if (!potentialMutationsIn.isEmpty) {
- DiagnosticMessage hint = reporter.createMessage(
- typePromotion.node,
- MessageKind.POTENTIAL_MUTATION,
- {'variableName': variableName, 'shownType': typePromotion.type});
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- for (Node mutation in potentialMutationsIn) {
- infos.add(reporter.createMessage(
- mutation,
- MessageKind.POTENTIAL_MUTATION_HERE,
- {'variableName': variableName}));
- }
- typePromotion.addHint(hint, infos);
- }
- List<Node> potentialMutationsInClosures =
- elements.getPotentialMutationsInClosure(variable);
- if (!potentialMutationsInClosures.isEmpty) {
- DiagnosticMessage hint = reporter.createMessage(
- typePromotion.node,
- MessageKind.POTENTIAL_MUTATION_IN_CLOSURE,
- {'variableName': variableName, 'shownType': typePromotion.type});
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- for (Node mutation in potentialMutationsInClosures) {
- infos.add(reporter.createMessage(
- mutation,
- MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE,
- {'variableName': variableName}));
- }
- typePromotion.addHint(hint, infos);
- }
- if (checkAccesses) {
- List<Node> accesses = elements.getAccessesByClosureIn(node, variable);
- List<Node> mutations = elements.getPotentialMutations(variable);
- if (!accesses.isEmpty && !mutations.isEmpty) {
- DiagnosticMessage hint = reporter.createMessage(
- typePromotion.node,
- MessageKind.ACCESSED_IN_CLOSURE,
- {'variableName': variableName, 'shownType': typePromotion.type});
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- for (Node access in accesses) {
- infos.add(reporter.createMessage(
- access,
- MessageKind.ACCESSED_IN_CLOSURE_HERE,
- {'variableName': variableName}));
- }
- for (Node mutation in mutations) {
- infos.add(reporter.createMessage(
- mutation,
- MessageKind.POTENTIAL_MUTATION_HERE,
- {'variableName': variableName}));
- }
- typePromotion.addHint(hint, infos);
- }
- }
- }
-
- /// Show type promotions from [left] and [right] in [node] given that the
- /// promoted variables are not potentially mutated in [right].
- void reshowTypePromotions(Node node, Node left, Node right) {
- for (TypePromotion typePromotion in getShownTypePromotionsFor(left)) {
- typePromotion = typePromotion.copy();
- checkTypePromotion(right, typePromotion);
- showTypePromotion(node, typePromotion);
- }
-
- for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) {
- typePromotion = typePromotion.copy();
- checkTypePromotion(right, typePromotion);
- showTypePromotion(node, typePromotion);
- }
- }
-
- /// Analyze [node] in the context of the known types shown in [context].
- ResolutionDartType analyzeInPromotedContext(Node context, Node node,
- {bool mustHaveType: true}) {
- Link<TypePromotion> knownForNode = const Link<TypePromotion>();
- for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) {
- typePromotion = typePromotion.copy();
- checkTypePromotion(node, typePromotion, checkAccesses: true);
- knownForNode = knownForNode.prepend(typePromotion);
- registerKnownTypePromotion(typePromotion);
- }
-
- final ResolutionDartType type = analyze(node, mustHaveType: mustHaveType);
-
- while (!knownForNode.isEmpty) {
- unregisterKnownTypePromotion(knownForNode.head);
- knownForNode = knownForNode.tail;
- }
-
- return type;
- }
-
- /**
- * Check if a value of type [from] can be assigned to a variable, parameter or
- * return value of type [to]. If `isConst == true`, an error is emitted in
- * checked mode, otherwise a warning is issued.
- */
- bool checkAssignable(
- Spannable spannable, ResolutionDartType from, ResolutionDartType to,
- {bool isConst: false}) {
- if (!types.isAssignable(from, to)) {
- if (compiler.options.enableTypeAssertions && isConst) {
- reporter.reportErrorMessage(spannable, MessageKind.NOT_ASSIGNABLE,
- {'fromType': from, 'toType': to});
- } else {
- reporter.reportWarningMessage(spannable, MessageKind.NOT_ASSIGNABLE,
- {'fromType': from, 'toType': to});
- }
- return false;
- }
- return true;
- }
-
- checkCondition(Expression condition) {
- checkAssignable(condition, analyze(condition), boolType);
- }
-
- void pushCascadeType(ResolutionDartType type) {
- cascadeTypes = cascadeTypes.prepend(type);
- }
-
- ResolutionDartType popCascadeType() {
- ResolutionDartType type = cascadeTypes.head;
- cascadeTypes = cascadeTypes.tail;
- return type;
- }
-
- visitAssert(Assert node) {
- analyze(node.condition);
- if (node.hasMessage) analyze(node.message);
- }
-
- visitBlock(Block node) {
- analyzeUntyped(node.statements);
- }
-
- ResolutionDartType visitCascade(Cascade node) {
- analyze(node.expression);
- return popCascadeType();
- }
-
- ResolutionDartType visitCascadeReceiver(CascadeReceiver node) {
- ResolutionDartType type = analyze(node.expression);
- pushCascadeType(type);
- return type;
- }
-
- visitDoWhile(DoWhile node) {
- analyzeUntyped(node.body);
- checkCondition(node.condition);
- }
-
- visitExpressionStatement(ExpressionStatement node) {
- Expression expression = node.expression;
- analyze(expression);
- }
-
- /** Dart Programming Language Specification: 11.5.1 For Loop */
- visitFor(For node) {
- if (node.initializer != null) {
- analyzeUntyped(node.initializer);
- }
- if (node.condition != null) {
- checkCondition(node.condition);
- }
- if (node.update != null) {
- analyzeUntyped(node.update);
- }
- analyzeUntyped(node.body);
- }
-
- visitFunctionDeclaration(FunctionDeclaration node) {
- analyze(node.function);
- }
-
- ResolutionDartType visitFunctionExpression(FunctionExpression node) {
- ResolutionDartType type;
- ResolutionDartType returnType;
- final FunctionElement element = elements.getFunctionDefinition(node);
- assert(
- element != null, failedAt(node, 'FunctionExpression with no element'));
- if (Elements.isUnresolved(element)) return const ResolutionDynamicType();
- if (element.isGenerativeConstructor) {
- type = const ResolutionDynamicType();
- returnType = const ResolutionVoidType();
-
- element.functionSignature.forEachParameter((FormalElement parameter) {
- if (parameter.isInitializingFormal) {
- InitializingFormalElement fieldParameter = parameter;
- checkAssignable(parameter, parameter.type,
- fieldParameter.fieldElement.computeType(resolution));
- }
- });
- if (node.initializers != null) {
- analyzeUntyped(node.initializers, inInitializer: true);
- }
- } else {
- ResolutionFunctionType functionType = element.computeType(resolution);
- returnType = functionType.returnType;
- type = functionType;
- }
- ExecutableElement previousExecutableContext = executableContext;
- ResolutionDartType previousReturnType = expectedReturnType;
- expectedReturnType = returnType;
- AsyncMarker previousAsyncMarker = currentAsyncMarker;
-
- executableContext = element;
- currentAsyncMarker = element.asyncMarker;
- analyzeUntyped(node.body);
-
- executableContext = previousExecutableContext;
- expectedReturnType = previousReturnType;
- currentAsyncMarker = previousAsyncMarker;
- return type;
- }
-
- ResolutionDartType visitIdentifier(Identifier node) {
- if (node.isThis()) {
- return thisType;
- } else if (node.isSuper()) {
- return superType;
- } else {
- TypedElement element = elements[node];
- assert(element != null, failedAt(node, 'Missing element for identifier'));
- assert(element.isVariable || element.isParameter || element.isField,
- failedAt(node, 'Unexpected context element ${element}'));
- return element.computeType(resolution);
- }
- }
-
- visitIf(If node) {
- Expression condition = node.condition.expression;
- Statement thenPart = node.thenPart;
-
- checkCondition(node.condition);
- analyzeInPromotedContext(condition, thenPart, mustHaveType: false);
- if (node.elsePart != null) {
- analyzeUntyped(node.elsePart);
- }
- }
-
- void checkPrivateAccess(Node node, Element element, String name) {
- if (name != null &&
- Name.isPrivateName(name) &&
- element.library != currentLibrary) {
- reportTypeWarning(node, MessageKind.PRIVATE_ACCESS,
- {'name': name, 'libraryName': element.library.name});
- }
- }
-
- ElementAccess lookupMember(Node node, ResolutionDartType receiverType,
- String name, MemberKind memberKind, Element receiverElement,
- {bool lookupClassMember: false, bool isHint: false}) {
- if (receiverType.treatAsDynamic) {
- return const DynamicAccess();
- }
-
- Name memberName = new Name(name, currentLibrary,
- isSetter: memberKind == MemberKind.SETTER);
-
- // Lookup the class or interface member [name] in [interface].
- MemberSignature lookupMemberSignature(
- Name name, ResolutionInterfaceType interface) {
- MembersCreator.computeClassMembersByName(
- resolution, interface.element, name.text);
- return lookupClassMember || analyzingInitializer
- ? interface.lookupClassMember(name)
- : interface.lookupInterfaceMember(name);
- }
-
- // Compute the access of [name] on [type]. This function takes the special
- // 'call' method into account.
- ElementAccess getAccess(Name name, ResolutionDartType unaliasedBound,
- ResolutionInterfaceType interface) {
- MemberSignature member = lookupMemberSignature(memberName, interface);
- if (member != null) {
- if (member is ErroneousMember) {
- return const DynamicAccess();
- } else {
- return new MemberAccess(member);
- }
- }
- if (name == const PublicName('call')) {
- if (unaliasedBound.isFunctionType) {
- // This is an access the implicit 'call' method of a function type.
- return new FunctionCallAccess(receiverElement, unaliasedBound);
- }
- ResolutionInterfaceType functionType = commonElements.functionType;
- if (types.isSubtype(interface, functionType)) {
- // This is an access of the special 'call' method implicitly defined
- // on 'Function'. This method can be called with any arguments, which
- // we ensure by giving it the type 'dynamic'.
- return new FunctionCallAccess(null, const ResolutionDynamicType());
- }
- }
- return null;
- }
-
- ResolutionDartType unaliasedBound =
- Types.computeUnaliasedBound(resolution, receiverType);
- if (unaliasedBound.treatAsDynamic) {
- return new DynamicAccess();
- }
- ResolutionInterfaceType interface =
- Types.computeInterfaceType(resolution, unaliasedBound);
- ElementAccess access = getAccess(memberName, unaliasedBound, interface);
- if (access != null) {
- return access;
- }
- if (receiverElement != null &&
- (receiverElement.isVariable || receiverElement.isParameter)) {
- Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement];
- if (typePromotions != null) {
- while (!typePromotions.isEmpty) {
- TypePromotion typePromotion = typePromotions.head;
- if (!typePromotion.isValid) {
- ResolutionDartType unaliasedBound =
- Types.computeUnaliasedBound(resolution, typePromotion.type);
- if (!unaliasedBound.treatAsDynamic) {
- ResolutionInterfaceType interface =
- Types.computeInterfaceType(resolution, unaliasedBound);
- if (getAccess(memberName, unaliasedBound, interface) != null) {
- reportTypePromotionHint(typePromotion);
- }
- }
- }
- typePromotions = typePromotions.tail;
- }
- }
- }
- // We didn't find a member with the correct name. If this lookup is for a
- // super or redirecting initializer, the resolver has already emitted an
- // error message. If the target is a proxy, no warning needs to be emitted.
- // Otherwise, try to emit the most precise warning.
- if (!interface.element.isProxy && !analyzingInitializer) {
- bool foundPrivateMember = false;
- if (memberName.isPrivate) {
- void findPrivateMember(MemberSignature member) {
- if (memberName.isSimilarTo(member.name)) {
- PrivateName privateName = member.name;
- LibraryElement library = privateName.library;
- reportMessage(node, MessageKind.PRIVATE_ACCESS,
- {'name': name, 'libraryName': library.name},
- isHint: isHint);
- foundPrivateMember = true;
- }
- }
-
- // TODO(johnniwinther): Avoid computation of all class members.
- MembersCreator.computeAllClassMembers(resolution, interface.element);
- if (lookupClassMember) {
- interface.element.forEachClassMember(findPrivateMember);
- } else {
- interface.element.forEachInterfaceMember(findPrivateMember);
- }
- }
- if (!foundPrivateMember) {
- switch (memberKind) {
- case MemberKind.METHOD:
- reportMessage(node, MessageKind.UNDEFINED_METHOD,
- {'className': receiverType.name, 'memberName': name},
- isHint: isHint);
- break;
- case MemberKind.OPERATOR:
- reportMessage(node, MessageKind.UNDEFINED_OPERATOR,
- {'className': receiverType.name, 'memberName': name},
- isHint: isHint);
- break;
- case MemberKind.GETTER:
- if (lookupMemberSignature(memberName.setter, interface) != null) {
- // A setter is present so warn explicitly about the missing
- // getter.
- reportMessage(
- node,
- MessageKind.UNDEFINED_INSTANCE_GETTER_BUT_SETTER,
- {'className': receiverType.name, 'memberName': name},
- isHint: isHint);
- } else if (name == 'await') {
- Map arguments = {'className': receiverType.name};
- String functionName = executableContext.name;
- MessageKind kind;
- if (functionName == '') {
- kind = MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE;
- } else {
- kind = MessageKind.AWAIT_MEMBER_NOT_FOUND;
- arguments['functionName'] = functionName;
- }
- reportMessage(node, kind, arguments, isHint: isHint);
- } else {
- reportMessage(node, MessageKind.UNDEFINED_GETTER,
- {'className': receiverType.name, 'memberName': name},
- isHint: isHint);
- }
- break;
- case MemberKind.SETTER:
- reportMessage(node, MessageKind.UNDEFINED_SETTER,
- {'className': receiverType.name, 'memberName': name},
- isHint: isHint);
- break;
- }
- }
- }
- return const DynamicAccess();
- }
-
- ResolutionDartType lookupMemberType(
- Node node, ResolutionDartType type, String name, MemberKind memberKind,
- {bool isHint: false}) {
- return lookupMember(node, type, name, memberKind, null, isHint: isHint)
- .computeType(resolution);
- }
-
- void analyzeArguments(Send send, Element element, ResolutionDartType type,
- [LinkBuilder<ResolutionDartType> argumentTypes]) {
- Link<Node> arguments = send.arguments;
- type.computeUnaliased(resolution);
- ResolutionDartType unaliasedType = type.unaliased;
- if (identical(unaliasedType.kind, ResolutionTypeKind.FUNCTION)) {
- /// Report [warning] including info(s) about the declaration of [element]
- /// or [type].
- void reportWarning(DiagnosticMessage warning) {
- // TODO(johnniwinther): Support pointing to individual parameters on
- // assignability warnings.
- List<DiagnosticMessage> infos = <DiagnosticMessage>[];
- Element declaration = element;
- if (declaration == null) {
- declaration = type.element;
- } else if (type.isTypedef) {
- infos.add(reporter.createMessage(declaration,
- MessageKind.THIS_IS_THE_DECLARATION, {'name': element.name}));
- declaration = type.element;
- }
- if (declaration != null) {
- infos.add(reporter.createMessage(
- declaration, MessageKind.THIS_IS_THE_METHOD));
- }
- reporter.reportWarning(warning, infos);
- }
-
- /// Report a warning on [node] if [argumentType] is not assignable to
- /// [parameterType].
- void checkAssignable(Spannable node, ResolutionDartType argumentType,
- ResolutionDartType parameterType) {
- if (!types.isAssignable(argumentType, parameterType)) {
- reportWarning(reporter.createMessage(node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': argumentType, 'toType': parameterType}));
- }
- }
-
- ResolutionFunctionType funType = unaliasedType;
- Iterator<ResolutionDartType> parameterTypes =
- funType.parameterTypes.iterator;
- Iterator<ResolutionDartType> optionalParameterTypes =
- funType.optionalParameterTypes.iterator;
- while (!arguments.isEmpty) {
- Node argument = arguments.head;
- NamedArgument namedArgument = argument.asNamedArgument();
- if (namedArgument != null) {
- argument = namedArgument.expression;
- String argumentName = namedArgument.name.source;
- ResolutionDartType namedParameterType =
- funType.getNamedParameterType(argumentName);
- if (namedParameterType == null) {
- // TODO(johnniwinther): Provide better information on the called
- // function.
- reportWarning(reporter.createMessage(
- argument,
- MessageKind.NAMED_ARGUMENT_NOT_FOUND,
- {'argumentName': argumentName}));
-
- ResolutionDartType argumentType = analyze(argument);
- if (argumentTypes != null) argumentTypes.addLast(argumentType);
- } else {
- ResolutionDartType argumentType = analyze(argument);
- if (argumentTypes != null) argumentTypes.addLast(argumentType);
- checkAssignable(argument, argumentType, namedParameterType);
- }
- } else {
- if (!parameterTypes.moveNext()) {
- if (!optionalParameterTypes.moveNext()) {
- // TODO(johnniwinther): Provide better information on the
- // called function.
- reportWarning(reporter.createMessage(
- argument, MessageKind.ADDITIONAL_ARGUMENT));
-
- ResolutionDartType argumentType = analyze(argument);
- if (argumentTypes != null) argumentTypes.addLast(argumentType);
- } else {
- ResolutionDartType argumentType = analyze(argument);
- if (argumentTypes != null) argumentTypes.addLast(argumentType);
- checkAssignable(
- argument, argumentType, optionalParameterTypes.current);
- }
- } else {
- ResolutionDartType argumentType = analyze(argument);
- if (argumentTypes != null) argumentTypes.addLast(argumentType);
- checkAssignable(argument, argumentType, parameterTypes.current);
- }
- }
- arguments = arguments.tail;
- }
- if (parameterTypes.moveNext()) {
- // TODO(johnniwinther): Provide better information on the called
- // function.
- reportWarning(reporter.createMessage(send, MessageKind.MISSING_ARGUMENT,
- {'argumentType': parameterTypes.current}));
- }
- } else {
- while (!arguments.isEmpty) {
- ResolutionDartType argumentType = analyze(arguments.head);
- if (argumentTypes != null) argumentTypes.addLast(argumentType);
- arguments = arguments.tail;
- }
- }
- }
-
- // Analyze the invocation [node] of [elementAccess].
- //
- // If provided [argumentTypes] is filled with the argument types during
- // analysis.
- ResolutionDartType analyzeInvocation(Send node, ElementAccess elementAccess,
- [LinkBuilder<ResolutionDartType> argumentTypes]) {
- ResolutionDartType type = elementAccess.computeType(resolution);
- if (elementAccess.isCallable(compiler)) {
- analyzeArguments(node, elementAccess.element, type, argumentTypes);
- } else {
- reportTypeWarning(
- node, MessageKind.NOT_CALLABLE, {'elementName': elementAccess.name});
- analyzeArguments(node, elementAccess.element,
- const ResolutionDynamicType(), argumentTypes);
- }
- type.computeUnaliased(resolution);
- type = type.unaliased;
- if (type.isFunctionType) {
- ResolutionFunctionType funType = type;
- return funType.returnType;
- } else {
- return const ResolutionDynamicType();
- }
- }
-
- /**
- * Computes the [ElementAccess] for [name] on the [node] possibly using the
- * [element] provided for [node] by the resolver.
- */
- ElementAccess computeAccess(
- Send node, String name, Element element, MemberKind memberKind,
- {bool lookupClassMember: false}) {
- if (Elements.isMalformed(element)) {
- return const DynamicAccess();
- }
- if (node.receiver != null) {
- Element receiverElement = elements[node.receiver];
- if (receiverElement != null) {
- if (receiverElement.isPrefix) {
- if (node.isConditional) {
- // Skip cases like `prefix?.topLevel`.
- return const DynamicAccess();
- }
- assert(
- element != null, failedAt(node, 'Prefixed node has no element.'));
- return computeResolvedAccess(node, name, element, memberKind);
- }
- }
- // e.foo() for some expression e.
- ResolutionDartType receiverType = analyze(node.receiver);
- if (receiverType.treatAsDynamic || receiverType.isVoid) {
- return const DynamicAccess();
- }
- return lookupMember(
- node, receiverType, name, memberKind, elements[node.receiver],
- lookupClassMember:
- lookupClassMember || element != null && element.isStatic);
- } else {
- return computeResolvedAccess(node, name, element, memberKind);
- }
- }
-
- /**
- * Computes the [ElementAccess] for [name] on the [node] using the [element]
- * provided for [node] by the resolver.
- */
- ElementAccess computeResolvedAccess(
- Send node, String name, Element element, MemberKind memberKind) {
- if (element == null) {
- // foo() where foo is unresolved.
- return lookupMember(node, thisType, name, memberKind, null);
- } else if (element.isMalformed) {
- // foo() where foo is erroneous.
- return const DynamicAccess();
- } else if (element.impliesType) {
- // The literal `Foo` where Foo is a class, a typedef, or a type variable.
- if (elements.isTypeLiteral(node)) {
- return new TypeLiteralAccess(elements.getTypeLiteralType(node));
- }
- return createResolvedAccess(node, name, element);
- } else if (element.isClassMember) {
- // foo() where foo is a member.
- return lookupMember(node, thisType, name, memberKind, null,
- lookupClassMember: element.isStatic);
- } else if (element.isFunction) {
- // foo() where foo is a method in the same class.
- return createResolvedAccess(node, name, element);
- } else if (element.isVariable ||
- element.isRegularParameter ||
- element.isField ||
- element.isInitializingFormal) {
- // foo() where foo is a field in the same class.
- return createResolvedAccess(node, name, element);
- } else if (element.isGetter || element.isSetter) {
- return createResolvedAccess(node, name, element);
- } else {
- reporter.internalError(
- element, 'Unexpected element kind ${element.kind}.');
- return null;
- }
- }
-
- ElementAccess createResolvedAccess(Send node, String name, Element element) {
- checkPrivateAccess(node, element, name);
- return createPromotedAccess(element);
- }
-
- ElementAccess createPromotedAccess(Element element) {
- if (element.isVariable || element.isParameter) {
- TypePromotion typePromotion = getKnownTypePromotion(element);
- if (typePromotion != null) {
- return new PromotedAccess(element, typePromotion.type);
- }
- }
- return new ResolvedAccess(element);
- }
-
- /**
- * Computes the type of the access of [name] on the [node] possibly using the
- * [element] provided for [node] by the resolver.
- */
- ResolutionDartType computeAccessType(
- Send node, String name, Element element, MemberKind memberKind,
- {bool lookupClassMember: false}) {
- ResolutionDartType type = computeAccess(node, name, element, memberKind,
- lookupClassMember: lookupClassMember)
- .computeType(resolution);
- if (type == null) {
- reporter.internalError(node, 'Type is null on access of $name on $node.');
- }
- return type;
- }
-
- /// Compute a version of [shownType] that is more specific that [knownType].
- /// This is used to provided better hints when trying to promote a supertype
- /// to a raw subtype. For instance trying to promote `Iterable<int>` to `List`
- /// we suggest the use of `List<int>`, which would make promotion valid.
- ResolutionDartType computeMoreSpecificType(
- ResolutionDartType shownType, ResolutionDartType knownType) {
- if (knownType.isInterfaceType &&
- shownType.isInterfaceType &&
- types.isSubtype(shownType.asRaw(), knownType)) {
- // For the comments in the block, assume the hierarchy:
- // class A<T, V> {}
- // class B<S, U> extends A<S, int> {}
- // and a promotion from a [knownType] of `A<double, int>` to a
- // [shownType] of `B`.
- ResolutionInterfaceType knownInterfaceType = knownType;
- ClassElement shownClass = shownType.element;
-
- // Compute `B<double, dynamic>` as the subtype of `A<double, int>` using
- // the relation between `A<S, int>` and `A<double, int>`.
- MoreSpecificSubtypeVisitor visitor =
- new MoreSpecificSubtypeVisitor(types);
- ResolutionInterfaceType shownTypeGeneric =
- visitor.computeMoreSpecific(shownClass, knownInterfaceType);
-
- if (shownTypeGeneric != null &&
- types.isMoreSpecific(shownTypeGeneric, knownType)) {
- // This should be the case but we double-check.
- // TODO(johnniwinther): Ensure that we don't suggest malbounded types.
- return shownTypeGeneric;
- }
- }
- return null;
- }
-
- ResolutionDartType visitSend(Send node) {
- Element element = elements[node];
-
- if (element != null && element.isConstructor) {
- ResolutionDartType receiverType;
- if (node.receiver != null) {
- receiverType = analyze(node.receiver);
- } else if (node.selector.isSuper()) {
- // TODO(johnniwinther): Lookup super-member in class members.
- receiverType = superType;
- } else {
- assert(node.selector.isThis());
- receiverType = thisType;
- }
- ResolutionDartType constructorType =
- computeConstructorType(element, receiverType);
- analyzeArguments(node, element, constructorType);
- return const ResolutionDynamicType();
- }
-
- Identifier selector = node.selector.asIdentifier();
- if (Elements.isClosureSend(node, element)) {
- if (element != null) {
- if (element.isError) {
- // foo() where foo is erroneous
- return analyzeInvocation(node, const DynamicAccess());
- } else {
- assert(element.isLocal,
- failedAt(node, "Unexpected element $element in closure send."));
- // foo() where foo is a local or a parameter.
- return analyzeInvocation(node, createPromotedAccess(element));
- }
- } else {
- // exp() where exp is some complex expression like (o) or foo().
- ResolutionDartType type = analyze(node.selector);
- return analyzeInvocation(node, new TypeAccess(type));
- }
- } else if (Elements.isMalformed(element) && selector == null) {
- // exp() where exp is an erroneous construct like `new Unresolved()`.
- ResolutionDartType type = analyze(node.selector);
- return analyzeInvocation(node, new TypeAccess(type));
- }
-
- String name = selector.source;
-
- if (node.isOperator && identical(name, 'is')) {
- analyze(node.receiver);
- if (!node.isIsNotCheck) {
- Element variable = elements[node.receiver];
- if (variable == null) {
- // Look for the variable element within parenthesized expressions.
- ParenthesizedExpression parentheses =
- node.receiver.asParenthesizedExpression();
- while (parentheses != null) {
- variable = elements[parentheses.expression];
- if (variable != null) break;
- parentheses = parentheses.expression.asParenthesizedExpression();
- }
- }
-
- if (variable != null && (variable.isVariable || variable.isParameter)) {
- ResolutionDartType knownType = getKnownType(variable);
- if (!knownType.isDynamic) {
- ResolutionDartType shownType =
- elements.getType(node.arguments.head);
- TypePromotion typePromotion =
- new TypePromotion(node, variable, shownType);
- if (!types.isMoreSpecific(shownType, knownType)) {
- String variableName = variable.name;
- if (!types.isSubtype(shownType, knownType)) {
- typePromotion.addHint(reporter.createMessage(
- node, MessageKind.NOT_MORE_SPECIFIC_SUBTYPE, {
- 'variableName': variableName,
- 'shownType': shownType,
- 'knownType': knownType
- }));
- } else {
- ResolutionDartType shownTypeSuggestion =
- computeMoreSpecificType(shownType, knownType);
- if (shownTypeSuggestion != null) {
- typePromotion.addHint(reporter.createMessage(
- node, MessageKind.NOT_MORE_SPECIFIC_SUGGESTION, {
- 'variableName': variableName,
- 'shownType': shownType,
- 'shownTypeSuggestion': shownTypeSuggestion,
- 'knownType': knownType
- }));
- } else {
- typePromotion.addHint(reporter.createMessage(
- node, MessageKind.NOT_MORE_SPECIFIC, {
- 'variableName': variableName,
- 'shownType': shownType,
- 'knownType': knownType
- }));
- }
- }
- }
- showTypePromotion(node, typePromotion);
- }
- }
- }
- return boolType;
- }
- if (node.isOperator && identical(name, 'as')) {
- analyze(node.receiver);
- return elements.getType(node.arguments.head);
- } else if (node.isOperator) {
- final Node receiver = node.receiver;
- final ResolutionDartType receiverType = analyze(receiver);
- if (identical(name, '==') ||
- identical(name, '!=')
- // TODO(johnniwinther): Remove these.
- ||
- identical(name, '===') ||
- identical(name, '!==')) {
- // Analyze argument.
- analyze(node.arguments.head);
- return boolType;
- } else if (identical(name, '||')) {
- checkAssignable(receiver, receiverType, boolType);
- final Node argument = node.arguments.head;
- final ResolutionDartType argumentType = analyze(argument);
- checkAssignable(argument, argumentType, boolType);
- return boolType;
- } else if (identical(name, '&&')) {
- checkAssignable(receiver, receiverType, boolType);
- final Node argument = node.arguments.head;
-
- final ResolutionDartType argumentType =
- analyzeInPromotedContext(receiver, argument);
-
- reshowTypePromotions(node, receiver, argument);
-
- checkAssignable(argument, argumentType, boolType);
- return boolType;
- } else if (identical(name, '!')) {
- checkAssignable(receiver, receiverType, boolType);
- return boolType;
- } else if (identical(name, '?')) {
- return boolType;
- } else if (identical(name, '??')) {
- final Node argument = node.arguments.head;
- final ResolutionDartType argumentType = analyze(argument);
- return types.computeLeastUpperBound(receiverType, argumentType);
- }
- String operatorName = selector.source;
- if (identical(name, '-') && node.arguments.isEmpty) {
- operatorName = 'unary-';
- }
- assert(
- identical(name, '+') ||
- identical(name, '=') ||
- identical(name, '-') ||
- identical(name, '*') ||
- identical(name, '/') ||
- identical(name, '%') ||
- identical(name, '~/') ||
- identical(name, '|') ||
- identical(name, '&') ||
- identical(name, '^') ||
- identical(name, '~') ||
- identical(name, '<<') ||
- identical(name, '>>') ||
- identical(name, '<') ||
- identical(name, '>') ||
- identical(name, '<=') ||
- identical(name, '>=') ||
- identical(name, '[]'),
- failedAt(node, 'Unexpected operator $name'));
-
- // TODO(karlklose): handle `void` in expression context by calling
- // [analyzeNonVoid] instead of [analyze].
- ElementAccess access = receiverType.isVoid
- ? const DynamicAccess()
- : lookupMember(
- node, receiverType, operatorName, MemberKind.OPERATOR, null);
- LinkBuilder<ResolutionDartType> argumentTypesBuilder =
- new LinkBuilder<ResolutionDartType>();
- ResolutionDartType resultType =
- analyzeInvocation(node, access, argumentTypesBuilder);
- if (receiverType == intType) {
- if (identical(name, '+') ||
- identical(operatorName, '-') ||
- identical(name, '*') ||
- identical(name, '%')) {
- ResolutionDartType argumentType = argumentTypesBuilder.toLink().head;
- if (argumentType == intType) {
- return intType;
- } else if (argumentType == doubleType) {
- return doubleType;
- }
- }
- }
- return resultType;
- } else if (node.isPropertyAccess) {
- ElementAccess access =
- computeAccess(node, selector.source, element, MemberKind.GETTER);
- return access.computeType(resolution);
- } else if (node.isFunctionObjectInvocation) {
- return unhandledExpression();
- } else {
- ElementAccess access =
- computeAccess(node, selector.source, element, MemberKind.METHOD);
- return analyzeInvocation(node, access);
- }
- }
-
- /// Returns the first type in the list or [:dynamic:] if the list is empty.
- ResolutionDartType firstType(List<ResolutionDartType> list) {
- return list.isEmpty ? const ResolutionDynamicType() : list.first;
- }
-
- /**
- * Returns the second type in the list or [:dynamic:] if the list is too
- * short.
- */
- ResolutionDartType secondType(List<ResolutionDartType> list) {
- return list.length < 2 ? const ResolutionDynamicType() : list[1];
- }
-
- /**
- * Checks [: target o= value :] for some operator o, and returns the type
- * of the result. This method also handles increment/decrement expressions
- * like [: target++ :].
- */
- ResolutionDartType checkAssignmentOperator(SendSet node, String operatorName,
- Node valueNode, ResolutionDartType value) {
- assert(!node.isIndex, failedAt(node));
- Element setterElement = elements[node];
- Element getterElement = elements[node.selector];
- Identifier selector = node.selector;
- ResolutionDartType getter = computeAccessType(
- node, selector.source, getterElement, MemberKind.GETTER);
- ResolutionDartType setter = computeAccessType(
- node, selector.source, setterElement, MemberKind.SETTER);
- // [operator] is the type of operator+ or operator- on [target].
- ResolutionDartType operator =
- lookupMemberType(node, getter, operatorName, MemberKind.OPERATOR);
- if (operator is ResolutionFunctionType) {
- ResolutionFunctionType operatorType = operator;
- // [result] is the type of target o value.
- ResolutionDartType result = operatorType.returnType;
- ResolutionDartType operatorArgument =
- firstType(operatorType.parameterTypes);
- // Check target o value.
- bool validValue = checkAssignable(valueNode, value, operatorArgument);
- if (validValue || !(node.isPrefix || node.isPostfix)) {
- // Check target = result.
- checkAssignable(node.assignmentOperator, result, setter);
- }
- return node.isPostfix ? getter : result;
- }
- return const ResolutionDynamicType();
- }
-
- /**
- * Checks [: base[key] o= value :] for some operator o, and returns the type
- * of the result. This method also handles increment/decrement expressions
- * like [: base[key]++ :].
- */
- ResolutionDartType checkIndexAssignmentOperator(SendSet node,
- String operatorName, Node valueNode, ResolutionDartType value) {
- assert(node.isIndex, failedAt(node));
- final ResolutionDartType base = analyze(node.receiver);
- final Node keyNode = node.arguments.head;
- final ResolutionDartType key = analyze(keyNode);
-
- // [indexGet] is the type of operator[] on [base].
- ResolutionDartType indexGet =
- lookupMemberType(node, base, '[]', MemberKind.OPERATOR);
- if (indexGet is ResolutionFunctionType) {
- ResolutionFunctionType indexGetType = indexGet;
- ResolutionDartType indexGetKey = firstType(indexGetType.parameterTypes);
- // Check base[key].
- bool validKey = checkAssignable(keyNode, key, indexGetKey);
-
- // [element] is the type of base[key].
- ResolutionDartType element = indexGetType.returnType;
- // [operator] is the type of operator o on [element].
- ResolutionDartType operator =
- lookupMemberType(node, element, operatorName, MemberKind.OPERATOR);
- if (operator is ResolutionFunctionType) {
- ResolutionFunctionType operatorType = operator;
-
- // Check base[key] o value.
- ResolutionDartType operatorArgument =
- firstType(operatorType.parameterTypes);
- bool validValue = checkAssignable(valueNode, value, operatorArgument);
-
- // [result] is the type of base[key] o value.
- ResolutionDartType result = operatorType.returnType;
-
- // [indexSet] is the type of operator[]= on [base].
- ResolutionDartType indexSet =
- lookupMemberType(node, base, '[]=', MemberKind.OPERATOR);
- if (indexSet is ResolutionFunctionType) {
- ResolutionFunctionType indexSetType = indexSet;
- ResolutionDartType indexSetKey =
- firstType(indexSetType.parameterTypes);
- ResolutionDartType indexSetValue =
- secondType(indexSetType.parameterTypes);
-
- if (validKey || indexGetKey != indexSetKey) {
- // Only check base[key] on []= if base[key] was valid for [] or
- // if the key types differ.
- checkAssignable(keyNode, key, indexSetKey);
- }
- // Check base[key] = result
- if (validValue || !(node.isPrefix || node.isPostfix)) {
- checkAssignable(node.assignmentOperator, result, indexSetValue);
- }
- }
- return node.isPostfix ? element : result;
- }
- }
- return const ResolutionDynamicType();
- }
-
- visitSendSet(SendSet node) {
- Element element = elements[node];
- Identifier selector = node.selector;
- final name = node.assignmentOperator.source;
- if (identical(name, '=') || identical(name, '??=')) {
- // e1 = value
- if (node.isIndex) {
- // base[key] = value
- final ResolutionDartType base = analyze(node.receiver);
- final Node keyNode = node.arguments.head;
- final ResolutionDartType key = analyze(keyNode);
- final Node valueNode = node.arguments.tail.head;
- final ResolutionDartType value = analyze(valueNode);
- ResolutionDartType indexSet =
- lookupMemberType(node, base, '[]=', MemberKind.OPERATOR);
- ResolutionDartType indexSetValue = const ResolutionDynamicType();
- if (indexSet is ResolutionFunctionType) {
- ResolutionFunctionType indexSetType = indexSet;
- ResolutionDartType indexSetKey =
- firstType(indexSetType.parameterTypes);
- checkAssignable(keyNode, key, indexSetKey);
- indexSetValue = secondType(indexSetType.parameterTypes);
- checkAssignable(node.assignmentOperator, value, indexSetValue);
- }
- return identical(name, '=')
- ? value
- : types.computeLeastUpperBound(value, indexSetValue);
- } else {
- // target = value
- ResolutionDartType target;
- if (analyzingInitializer) {
- // Field declaration `Foo target = value;` or initializer
- // `this.target = value`. Lookup the getter `target` in the class
- // members.
- target = computeAccessType(
- node, selector.source, element, MemberKind.GETTER,
- lookupClassMember: true);
- } else {
- // Normal assignment `target = value`.
- target = computeAccessType(
- node, selector.source, element, MemberKind.SETTER);
- }
- final Node valueNode = node.arguments.head;
- final ResolutionDartType value = analyze(valueNode);
- checkAssignable(node.assignmentOperator, value, target);
- return identical(name, '=')
- ? value
- : types.computeLeastUpperBound(value, target);
- }
- } else if (identical(name, '++') || identical(name, '--')) {
- // e++ or e--
- String operatorName = identical(name, '++') ? '+' : '-';
- if (node.isIndex) {
- // base[key]++, base[key]--, ++base[key], or --base[key]
- return checkIndexAssignmentOperator(
- node, operatorName, node.assignmentOperator, intType);
- } else {
- // target++, target--, ++target, or --target
- return checkAssignmentOperator(
- node, operatorName, node.assignmentOperator, intType);
- }
- } else {
- // e1 o= e2 for some operator o.
- String operatorName;
- switch (name) {
- case '+=':
- operatorName = '+';
- break;
- case '-=':
- operatorName = '-';
- break;
- case '*=':
- operatorName = '*';
- break;
- case '/=':
- operatorName = '/';
- break;
- case '%=':
- operatorName = '%';
- break;
- case '~/=':
- operatorName = '~/';
- break;
- case '&=':
- operatorName = '&';
- break;
- case '|=':
- operatorName = '|';
- break;
- case '^=':
- operatorName = '^';
- break;
- case '<<=':
- operatorName = '<<';
- break;
- case '>>=':
- operatorName = '>>';
- break;
- default:
- reporter.internalError(node, 'Unexpected assignment operator $name.');
- }
- if (node.isIndex) {
- // base[key] o= value for some operator o.
- final Node valueNode = node.arguments.tail.head;
- final ResolutionDartType value = analyze(valueNode);
- return checkIndexAssignmentOperator(
- node, operatorName, valueNode, value);
- } else {
- // target o= value for some operator o.
- final Node valueNode = node.arguments.head;
- final ResolutionDartType value = analyze(valueNode);
- return checkAssignmentOperator(node, operatorName, valueNode, value);
- }
- }
- }
-
- ResolutionDartType visitLiteralInt(LiteralInt node) {
- return intType;
- }
-
- ResolutionDartType visitLiteralDouble(LiteralDouble node) {
- return doubleType;
- }
-
- ResolutionDartType visitLiteralBool(LiteralBool node) {
- return boolType;
- }
-
- ResolutionDartType visitLiteralString(LiteralString node) {
- return stringType;
- }
-
- ResolutionDartType visitStringJuxtaposition(StringJuxtaposition node) {
- analyze(node.first);
- analyze(node.second);
- return stringType;
- }
-
- ResolutionDartType visitLiteralNull(LiteralNull node) {
- return const ResolutionDynamicType();
- }
-
- ResolutionInterfaceType visitLiteralSymbol(LiteralSymbol node) {
- return commonElements.symbolType;
- }
-
- ResolutionDartType computeConstructorType(
- ConstructorElement constructor, ResolutionDartType type) {
- if (Elements.isUnresolved(constructor))
- return const ResolutionDynamicType();
- ResolutionDartType constructorType = constructor.computeType(resolution);
- if (identical(type.kind, ResolutionTypeKind.INTERFACE)) {
- if (constructor.isSynthesized) {
- // TODO(johnniwinther): Remove this when synthesized constructors handle
- // type variables correctly.
- ResolutionInterfaceType interfaceType = type;
- ClassElement receiverElement = interfaceType.element;
- while (receiverElement.isMixinApplication) {
- receiverElement = receiverElement.supertype.element;
- }
- constructorType = constructorType
- .substByContext(interfaceType.asInstanceOf(receiverElement));
- } else {
- constructorType = constructorType.substByContext(type);
- }
- }
- return constructorType;
- }
-
- ResolutionDartType visitNewExpression(NewExpression node) {
- Element element = elements[node.send];
- if (Elements.isUnresolved(element)) return const ResolutionDynamicType();
-
- checkPrivateAccess(node, element, element.name);
-
- ResolutionDartType newType = elements.getType(node);
- assert(newType != null,
- failedAt(node, "No new type registered in $elements."));
- ResolutionDartType constructorType =
- computeConstructorType(element, newType);
- analyzeArguments(node.send, element, constructorType);
- return newType;
- }
-
- ResolutionDartType visitLiteralList(LiteralList node) {
- ResolutionInterfaceType listType = elements.getType(node);
- ResolutionDartType listElementType = firstType(listType.typeArguments);
- for (Link<Node> link = node.elements.nodes;
- !link.isEmpty;
- link = link.tail) {
- Node element = link.head;
- ResolutionDartType elementType = analyze(element);
- checkAssignable(element, elementType, listElementType,
- isConst: node.isConst);
- }
- return listType;
- }
-
- visitNodeList(NodeList node) {
- for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
- analyzeUntyped(link.head, inInitializer: analyzingInitializer);
- }
- }
-
- visitRedirectingFactoryBody(RedirectingFactoryBody node) {
- // TODO(lrn): Typecheck the body. It must refer to the constructor
- // of a subtype.
- }
-
- visitRethrow(Rethrow node) {
- // Nothing to do here.
- }
-
- /** Dart Programming Language Specification: 11.10 Return */
- visitReturn(Return node) {
- if (identical(node.beginToken.stringValue, 'native')) {
- return null;
- }
-
- final Node expression = node.expression;
-
- // Executing a return statement return e; [...] It is a static type warning
- // if the type of e may not be assigned to the declared return type of the
- // immediately enclosing function.
- if (expression != null) {
- ResolutionDartType expressionType = analyze(expression);
- if (executableContext.isGenerativeConstructor) {
- // The resolver already emitted an error for this expression.
- } else {
- if (currentAsyncMarker == AsyncMarker.ASYNC) {
- ResolutionInterfaceType futureOfFlattenedType =
- commonElements.futureType(types.flatten(expressionType));
- expressionType = futureOfFlattenedType;
- }
- if (expectedReturnType.isVoid &&
- !types.isAssignable(expressionType, const ResolutionVoidType())) {
- // In `void f(...) => e`, `e` can have any type.
- if (!node.isArrowBody) {
- reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
- }
- } else {
- checkAssignable(expression, expressionType, expectedReturnType);
- }
- }
- } else if (currentAsyncMarker != AsyncMarker.SYNC) {
- // `return;` is allowed.
- } else if (!types.isAssignable(
- expectedReturnType, const ResolutionVoidType())) {
- // Let f be the function immediately enclosing a return statement of the
- // form 'return;' It is a static warning if both of the following
- // conditions hold:
- // - f is not a generative constructor.
- // - The return type of f may not be assigned to void.
- reportTypeWarning(
- node, MessageKind.RETURN_NOTHING, {'returnType': expectedReturnType});
- }
- }
-
- ResolutionDartType visitThrow(Throw node) {
- // TODO(johnniwinther): Handle reachability.
- analyze(node.expression);
- return const ResolutionDynamicType();
- }
-
- ResolutionDartType visitAwait(Await node) {
- ResolutionDartType expressionType = analyze(node.expression);
- if (resolution.target.supportsAsyncAwait) {
- return types.flatten(expressionType);
- } else {
- return const ResolutionDynamicType();
- }
- }
-
- visitYield(Yield node) {
- ResolutionDartType resultType = analyze(node.expression);
- if (!node.hasStar) {
- if (currentAsyncMarker.isAsync) {
- ResolutionInterfaceType streamOfResultType =
- commonElements.streamType(resultType);
- resultType = streamOfResultType;
- } else {
- ResolutionInterfaceType iterableOfResultType =
- commonElements.iterableType(resultType);
- resultType = iterableOfResultType;
- }
- } else {
- if (currentAsyncMarker.isAsync) {
- // The static type of expression must be assignable to Stream.
- ResolutionInterfaceType streamType = commonElements.streamType();
- checkAssignable(node, resultType, streamType);
- } else {
- // The static type of expression must be assignable to Iterable.
- ResolutionInterfaceType iterableType = commonElements.iterableType();
- checkAssignable(node, resultType, iterableType);
- }
- }
- // The static type of the result must be assignable to the declared type.
- checkAssignable(node, resultType, expectedReturnType);
- }
-
- ResolutionDartType visitTypeAnnotation(TypeAnnotation node) {
- return elements.getType(node);
- }
-
- ResolutionDartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
- ResolutionDartType type =
- analyzeWithDefault(node.type, const ResolutionDynamicType());
- if (type.isVoid) {
- reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
- type = const ResolutionDynamicType();
- }
- return type;
- }
-
- void analyzeVariableInitializer(
- Spannable spannable, ResolutionDartType declaredType, Node initializer) {
- if (initializer == null) return;
-
- ResolutionDartType expressionType = analyzeNonVoid(initializer);
- checkAssignable(spannable, expressionType, declaredType);
- }
-
- visitVariableDefinitions(VariableDefinitions node) {
- ResolutionDartType type = analyzeVariableTypeAnnotation(node);
- for (Link<Node> link = node.definitions.nodes;
- !link.isEmpty;
- link = link.tail) {
- Node definition = link.head;
- assert(definition is Identifier || definition is SendSet,
- failedAt(definition, 'expected identifier or initialization'));
- if (definition is SendSet) {
- SendSet initialization = definition;
- analyzeVariableInitializer(initialization.assignmentOperator, type,
- initialization.arguments.head);
- // TODO(sigmund): explore inferring a type for `var` using the RHS (like
- // DDC does), for example:
- // if (node.type == null && node.modifiers.isVar &&
- // !initializer.isDynamic) {
- // var variable = elements[definition];
- // if (variable != null) {
- // var typePromotion = new TypePromotion(
- // node, variable, initializer);
- // registerKnownTypePromotion(typePromotion);
- // }
- // }
- }
- }
- }
-
- visitWhile(While node) {
- checkCondition(node.condition);
- analyzeUntyped(node.body);
- }
-
- ResolutionDartType visitParenthesizedExpression(
- ParenthesizedExpression node) {
- Expression expression = node.expression;
- ResolutionDartType type = analyze(expression);
- for (TypePromotion typePromotion in getShownTypePromotionsFor(expression)) {
- showTypePromotion(node, typePromotion);
- }
- return type;
- }
-
- ResolutionDartType visitConditional(Conditional node) {
- Expression condition = node.condition;
- Expression thenExpression = node.thenExpression;
-
- checkCondition(condition);
-
- ResolutionDartType thenType =
- analyzeInPromotedContext(condition, thenExpression);
-
- ResolutionDartType elseType = analyze(node.elseExpression);
- return types.computeLeastUpperBound(thenType, elseType);
- }
-
- visitStringInterpolation(StringInterpolation node) {
- node.visitChildren(this);
- return stringType;
- }
-
- visitStringInterpolationPart(StringInterpolationPart node) {
- node.visitChildren(this);
- return stringType;
- }
-
- visitEmptyStatement(EmptyStatement node) {
- // Nothing to do here.
- }
-
- visitBreakStatement(BreakStatement node) {
- // Nothing to do here.
- }
-
- visitContinueStatement(ContinueStatement node) {
- // Nothing to do here.
- }
-
- ResolutionDartType computeForInElementType(ForIn node) {
- VariableDefinitions declaredIdentifier =
- node.declaredIdentifier.asVariableDefinitions();
- if (declaredIdentifier != null) {
- return analyzeWithDefault(
- declaredIdentifier.type, const ResolutionDynamicType());
- } else {
- return analyze(node.declaredIdentifier);
- }
- }
-
- visitAsyncForIn(AsyncForIn node) {
- ResolutionDartType elementType = computeForInElementType(node);
- ResolutionDartType expressionType = analyze(node.expression);
- if (resolution.target.supportsAsyncAwait) {
- ResolutionInterfaceType streamOfDynamic = commonElements.streamType();
- if (!types.isAssignable(expressionType, streamOfDynamic)) {
- reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE,
- {'fromType': expressionType, 'toType': streamOfDynamic},
- isHint: true);
- } else {
- ResolutionInterfaceType interfaceType =
- Types.computeInterfaceType(resolution, expressionType);
- if (interfaceType != null) {
- ResolutionInterfaceType streamType =
- interfaceType.asInstanceOf(streamOfDynamic.element);
- if (streamType != null) {
- ResolutionDartType streamElementType =
- streamType.typeArguments.first;
- if (!types.isAssignable(streamElementType, elementType)) {
- reportMessage(
- node.expression,
- MessageKind.FORIN_NOT_ASSIGNABLE,
- {
- 'currentType': streamElementType,
- 'expressionType': expressionType,
- 'elementType': elementType
- },
- isHint: true);
- }
- }
- }
- }
- }
- analyzeUntyped(node.body);
- }
-
- visitSyncForIn(SyncForIn node) {
- ResolutionDartType elementType = computeForInElementType(node);
- ResolutionDartType expressionType = analyze(node.expression);
- ResolutionDartType iteratorType = lookupMemberType(node.expression,
- expressionType, Identifiers.iterator, MemberKind.GETTER);
- ResolutionDartType currentType = lookupMemberType(
- node.expression, iteratorType, Identifiers.current, MemberKind.GETTER,
- isHint: true);
- if (!types.isAssignable(currentType, elementType)) {
- reportMessage(
- node.expression,
- MessageKind.FORIN_NOT_ASSIGNABLE,
- {
- 'currentType': currentType,
- 'expressionType': expressionType,
- 'elementType': elementType
- },
- isHint: true);
- }
- analyzeUntyped(node.body);
- }
-
- visitLabeledStatement(LabeledStatement node) {
- analyzeUntyped(node.statement);
- }
-
- visitLiteralMap(LiteralMap node) {
- ResolutionInterfaceType mapType = elements.getType(node);
- ResolutionDartType mapKeyType = firstType(mapType.typeArguments);
- ResolutionDartType mapValueType = secondType(mapType.typeArguments);
- bool isConst = node.isConst;
- for (Link<Node> link = node.entries.nodes;
- !link.isEmpty;
- link = link.tail) {
- LiteralMapEntry entry = link.head;
- ResolutionDartType keyType = analyze(entry.key);
- checkAssignable(entry.key, keyType, mapKeyType, isConst: isConst);
- ResolutionDartType valueType = analyze(entry.value);
- checkAssignable(entry.value, valueType, mapValueType, isConst: isConst);
- }
- return mapType;
- }
-
- visitNamedArgument(NamedArgument node) {
- // Named arguments are visited as part of analyzing invocations of
- // unresolved methods. For instance [: foo(a: 42); :] where 'foo' is neither
- // found in the enclosing scope nor through lookup on 'this' or
- // [: x.foo(b: 42); :] where 'foo' cannot be not found through lookup on
- // the static type of 'x'.
- return analyze(node.expression);
- }
-
- visitSwitchStatement(SwitchStatement node) {
- // TODO(johnniwinther): Handle reachability based on reachability of
- // switch cases.
- // TODO(johnniwinther): Provide hint of duplicate case constants.
-
- ResolutionDartType expressionType = analyze(node.expression);
-
- // Check that all the case expressions are assignable to the expression.
- bool hasDefaultCase = false;
- for (SwitchCase switchCase in node.cases) {
- if (switchCase.isDefaultCase) {
- hasDefaultCase = true;
- }
- for (Node labelOrCase in switchCase.labelsAndCases) {
- CaseMatch caseMatch = labelOrCase.asCaseMatch();
- if (caseMatch == null) continue;
-
- ResolutionDartType caseType = analyze(caseMatch.expression);
- checkAssignable(caseMatch, expressionType, caseType);
- }
-
- analyzeUntyped(switchCase);
- }
-
- if (!hasDefaultCase && expressionType.isEnumType) {
- compiler.enqueuer.resolution
- .addDeferredAction(new DeferredAction(executableContext, () {
- Map<ConstantValue, FieldElement> enumValues =
- <ConstantValue, FieldElement>{};
- List<FieldElement> unreferencedFields = <FieldElement>[];
- EnumClassElement enumClass = expressionType.element;
- enumClass.enumValues.forEach((EnumConstantElement field) {
- // TODO(johnniwinther): Ensure that the enum constant is computed at
- // this point.
- ConstantValue constantValue = compiler.resolver.constantCompiler
- .getConstantValueForVariable(field);
- if (constantValue == null) {
- // The field might not have been resolved.
- unreferencedFields.add(field);
- } else {
- enumValues[constantValue] = field;
- }
- });
-
- for (SwitchCase switchCase in node.cases) {
- for (Node labelOrCase in switchCase.labelsAndCases) {
- CaseMatch caseMatch = labelOrCase.asCaseMatch();
- if (caseMatch != null) {
- ConstantExpression caseConstant = compiler
- .resolver.constantCompiler
- .compileNode(caseMatch.expression, elements);
- enumValues
- .remove(compiler.constants.getConstantValue(caseConstant));
- }
- }
- }
- unreferencedFields.addAll(enumValues.values);
- if (!unreferencedFields.isEmpty) {
- reporter.reportWarningMessage(node, MessageKind.MISSING_ENUM_CASES, {
- 'enumType': expressionType,
- 'enumValues': unreferencedFields.map((e) => e.name).join(', ')
- });
- }
- }));
- }
- }
-
- visitSwitchCase(SwitchCase node) {
- analyzeUntyped(node.statements);
- }
-
- visitTryStatement(TryStatement node) {
- // TODO(johnniwinther): Use reachability information of try-block,
- // catch-blocks and finally-block to compute the whether the try statement
- // is returning.
- analyzeUntyped(node.tryBlock);
- for (CatchBlock catchBlock in node.catchBlocks) {
- analyzeUntyped(catchBlock);
- }
- analyzeUntyped(node.finallyBlock);
- }
-
- visitCatchBlock(CatchBlock node) {
- analyzeUntyped(node.block);
- }
-
- visitTypedef(Typedef node) {
- // Do not typecheck [Typedef] nodes.
- }
-
- visitNode(Node node) {
- reporter.internalError(node,
- 'Unexpected node ${node.getObjectDescription()} in the type checker.');
- }
-}
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
index 3ce4ce1..6b35ca4 100644
--- a/pkg/compiler/lib/src/types/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -6,6 +6,7 @@
import '../constants/values.dart' show ConstantValue;
import '../elements/entities.dart';
+import '../universe/selector.dart';
/// A value in an abstraction of runtime values.
abstract class AbstractValue {}
@@ -63,7 +64,7 @@
/// The [AbstractValue] that represents a non-null fixed size JavaScript array
/// at runtime.
- AbstractValue get fixedArrayType;
+ AbstractValue get fixedListType;
/// The [AbstractValue] that represents a non-null 31-bit unsigned integer at
/// runtime.
@@ -230,6 +231,10 @@
/// [b].
AbstractValue union(covariant AbstractValue a, covariant AbstractValue b);
+ /// Returns [AbstractValue] for the runtime values contained in at least one
+ /// of [values].
+ AbstractValue unionOfMany(List<AbstractValue> values);
+
/// Returns [AbstractValue] for the runtime values that [a] and [b] have in
/// common.
AbstractValue intersection(
@@ -243,4 +248,24 @@
/// Computes the [AbstractValue] corresponding to the constant [value].
AbstractValue computeAbstractValueForConstant(ConstantValue value);
+
+ /// Returns the element type of [value] if it represents a container value
+ /// at runtime. Returns [dynamicType] otherwise.
+ AbstractValue getContainerElementType(AbstractValue value);
+
+ /// Returns the value type of [value] if it represents a map value at runtime.
+ /// Returns [dynamicType] otherwise.
+ AbstractValue getMapValueType(AbstractValue value);
+
+ /// Compute the type of all potential receivers of the set of live [members].
+ AbstractValue computeReceiver(Iterable<MemberEntity> members);
+
+ /// Returns whether [member] is a potential target when being
+ /// invoked on a [receiver]. [selector] is used to ensure library privacy is
+ /// taken into account.
+ bool canHit(AbstractValue receiver, MemberEntity member, Selector selector);
+
+ /// Returns whether [selector] invoked on a [receiver] can hit a
+ /// [noSuchMethod].
+ bool needsNoSuchMethodHandling(AbstractValue receiver, Selector selector);
}
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 932a128..f83240a 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -62,7 +62,8 @@
if (((flags >> 1) == SUBCLASS) && !world.hasAnyStrictSubclass(base)) {
flags = (flags & 0x1) | (EXACT << 1);
}
- return world.getCachedMask(
+ CommonMasks commonMasks = world.abstractValueDomain;
+ return commonMasks.getCachedMask(
base, flags, () => new FlatTypeMask.internal(base, flags));
}
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index 24203e1..8e4916c 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -63,10 +63,22 @@
TypeMask _indexablePrimitiveType;
TypeMask _readableArrayType;
TypeMask _mutableArrayType;
- TypeMask _fixedArrayType;
TypeMask _unmodifiableArrayType;
TypeMask _interceptorType;
+ /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
+ /// `FlatTypeMask.flags` property.
+ final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks =
+ new List<Map<ClassEntity, TypeMask>>.filled(8, null);
+
+ /// Return the cached mask for [base] with the given flags, or
+ /// calls [createMask] to create the mask and cache it.
+ TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
+ Map<ClassEntity, TypeMask> cachedMasks =
+ _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
+ return cachedMasks.putIfAbsent(base, createMask);
+ }
+
TypeMask get dynamicType => _dynamicType ??= new TypeMask.subclass(
_closedWorld.commonElements.objectClass, _closedWorld);
@@ -149,9 +161,6 @@
_mutableArrayType ??= new TypeMask.nonNullSubclass(
commonElements.jsMutableArrayClass, _closedWorld);
- TypeMask get fixedArrayType => _fixedArrayType ??=
- new TypeMask.nonNullExact(commonElements.jsFixedArrayClass, _closedWorld);
-
TypeMask get unmodifiableArrayType =>
_unmodifiableArrayType ??= new TypeMask.nonNullExact(
commonElements.jsUnmodifiableArrayClass, _closedWorld);
@@ -375,4 +384,62 @@
AbstractValue computeAbstractValueForConstant(ConstantValue value) {
return computeTypeMask(_closedWorld, value);
}
+
+ @override
+ AbstractValue getMapValueType(AbstractValue value) {
+ if (value is MapTypeMask) {
+ return value.valueType ?? dynamicType;
+ }
+ return dynamicType;
+ }
+
+ @override
+ AbstractValue getContainerElementType(AbstractValue value) {
+ if (value is ContainerTypeMask) {
+ return value.elementType ?? dynamicType;
+ }
+ return dynamicType;
+ }
+
+ @override
+ AbstractValue unionOfMany(List<AbstractValue> values) {
+ TypeMask result = const TypeMask.nonNullEmpty();
+ for (TypeMask value in values) {
+ result = result.union(value, _closedWorld);
+ }
+ return result;
+ }
+
+ @override
+ AbstractValue computeReceiver(Iterable<MemberEntity> members) {
+ assert(_closedWorld
+ .hasAnyStrictSubclass(_closedWorld.commonElements.objectClass));
+ return new TypeMask.unionOf(
+ members.expand((MemberEntity element) {
+ ClassEntity cls = element.enclosingClass;
+ return [cls]..addAll(_closedWorld.mixinUsesOf(cls));
+ }).map((cls) {
+ if (_closedWorld.commonElements.jsNullClass == cls) {
+ return const TypeMask.empty();
+ } else if (_closedWorld.isInstantiated(cls)) {
+ return new TypeMask.nonNullSubclass(cls, _closedWorld);
+ } else {
+ // TODO(johnniwinther): Avoid the need for this case.
+ return const TypeMask.empty();
+ }
+ }),
+ _closedWorld);
+ }
+
+ @override
+ bool canHit(
+ covariant TypeMask receiver, MemberEntity member, Selector selector) {
+ return receiver.canHit(member, selector, _closedWorld);
+ }
+
+ @override
+ bool needsNoSuchMethodHandling(
+ covariant TypeMask receiver, Selector selector) {
+ return receiver.needsNoSuchMethodHandling(selector, _closedWorld);
+ }
}
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 963a622..704157c 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -7,16 +7,11 @@
import '../common.dart' show failedAt;
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart' show Compiler;
-import '../elements/elements.dart';
import '../elements/entities.dart';
import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
-import '../tree/tree.dart';
import '../universe/selector.dart' show Selector;
-import '../util/util.dart' show Maplet;
import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
-
-import 'masks.dart';
-export 'masks.dart';
+import 'abstract_value_domain.dart';
/// Results about a single element (e.g. a method, parameter, or field)
/// produced by the global type-inference algorithm.
@@ -34,37 +29,33 @@
/// The inferred type when this result belongs to a parameter or field
/// element, null otherwise.
- TypeMask get type;
+ AbstractValue get type;
/// The inferred return type when this result belongs to a function element.
- TypeMask get returnType;
+ AbstractValue get returnType;
/// Returns the type of a list new expression [node].
- TypeMask typeOfNewList(T node);
+ AbstractValue typeOfNewList(T node);
/// Returns the type of a list literal [node].
- TypeMask typeOfListLiteral(T node);
+ AbstractValue typeOfListLiteral(T node);
/// Returns the type of a send [node].
// TODO(johnniwinther): Rename this.
- TypeMask typeOfSend(T node);
+ AbstractValue typeOfSend(T node);
/// Returns the type of the getter in a complex send-set [node], for example,
/// the type of the `a.f` getter in `a.f += b`.
- TypeMask typeOfGetter(T node);
-
- /// Returns the type of the operator of a complex send-set [node], for
- /// example, the type of `+` in `a += b`.
- TypeMask typeOfOperator(T node);
+ AbstractValue typeOfGetter(T node);
/// Returns the type of the iterator in a [loop].
- TypeMask typeOfIterator(T node);
+ AbstractValue typeOfIterator(T node);
/// Returns the type of the `moveNext` call of an iterator in a [loop].
- TypeMask typeOfIteratorMoveNext(T node);
+ AbstractValue typeOfIteratorMoveNext(T node);
/// Returns the type of the `current` getter of an iterator in a [loop].
- TypeMask typeOfIteratorCurrent(T node);
+ AbstractValue typeOfIteratorCurrent(T node);
}
abstract class GlobalTypeInferenceMemberResult<T>
@@ -85,28 +76,27 @@
// TODO(sigmund): store relevant data & drop reference to inference engine.
final TypesInferrer<T> _inferrer;
final bool _isJsInterop;
- final TypeMask _dynamic;
GlobalTypeInferenceElementResultImpl(
- this._data, this._inferrer, this._isJsInterop, this._dynamic);
+ this._data, this._inferrer, this._isJsInterop);
bool get throwsAlways {
- TypeMask mask = this.returnType;
+ AbstractValue mask = this.returnType;
// Always throws if the return type was inferred to be non-null empty.
- return mask != null && mask.isEmpty;
+ return mask != null && _inferrer.abstractValueDomain.isEmpty(mask);
}
- TypeMask typeOfNewList(T node) => _inferrer.getTypeForNewList(node);
+ AbstractValue typeOfNewList(T node) => _inferrer.getTypeForNewList(node);
- TypeMask typeOfListLiteral(T node) => _inferrer.getTypeForNewList(node);
+ AbstractValue typeOfListLiteral(T node) => _inferrer.getTypeForNewList(node);
- TypeMask typeOfSend(T node) => _data?.typeOfSend(node);
- TypeMask typeOfGetter(T node) => _data?.typeOfGetter(node);
- TypeMask typeOfOperator(T node) => _data?.typeOfOperator(node);
- TypeMask typeOfIterator(T node) => _data?.typeOfIterator(node);
- TypeMask typeOfIteratorMoveNext(T node) =>
+ AbstractValue typeOfSend(T node) => _data?.typeOfSend(node);
+ AbstractValue typeOfGetter(T node) => _data?.typeOfGetter(node);
+ AbstractValue typeOfIterator(T node) => _data?.typeOfIterator(node);
+ AbstractValue typeOfIteratorMoveNext(T node) =>
_data?.typeOfIteratorMoveNext(node);
- TypeMask typeOfIteratorCurrent(T node) => _data?.typeOfIteratorCurrent(node);
+ AbstractValue typeOfIteratorCurrent(T node) =>
+ _data?.typeOfIteratorCurrent(node);
}
class GlobalTypeInferenceMemberResultImpl<T>
@@ -119,17 +109,18 @@
this._owner,
GlobalTypeInferenceElementData data,
TypesInferrer inferrer,
- bool isJsInterop,
- TypeMask _dynamic)
- : super(data, inferrer, isJsInterop, _dynamic);
+ bool isJsInterop)
+ : super(data, inferrer, isJsInterop);
bool get isCalledOnce => _inferrer.isMemberCalledOnce(_owner);
- TypeMask get returnType =>
- _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfMember(_owner);
+ AbstractValue get returnType => _isJsInterop
+ ? _inferrer.abstractValueDomain.dynamicType
+ : _inferrer.getReturnTypeOfMember(_owner);
- TypeMask get type =>
- _isJsInterop ? _dynamic : _inferrer.getTypeOfMember(_owner);
+ AbstractValue get type => _isJsInterop
+ ? _inferrer.abstractValueDomain.dynamicType
+ : _inferrer.getTypeOfMember(_owner);
}
class GlobalTypeInferenceParameterResultImpl<T>
@@ -138,107 +129,50 @@
// TODO(sigmund): delete, store data directly here.
final Local _owner;
- GlobalTypeInferenceParameterResultImpl(
- this._owner, TypesInferrer inferrer, TypeMask _dynamic)
- : super(null, inferrer, false, _dynamic);
+ GlobalTypeInferenceParameterResultImpl(this._owner, TypesInferrer inferrer)
+ : super(null, inferrer, false);
- TypeMask get returnType =>
- _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfParameter(_owner);
+ AbstractValue get returnType => _isJsInterop
+ ? _inferrer.abstractValueDomain.dynamicType
+ : _inferrer.getReturnTypeOfParameter(_owner);
- TypeMask get type =>
- _isJsInterop ? _dynamic : _inferrer.getTypeOfParameter(_owner);
+ AbstractValue get type => _isJsInterop
+ ? _inferrer.abstractValueDomain.dynamicType
+ : _inferrer.getTypeOfParameter(_owner);
}
/// Internal data used during type-inference to store intermediate results about
/// a single element.
abstract class GlobalTypeInferenceElementData<T> {
// TODO(johnniwinther): Remove this. Maybe split by access/invoke.
- TypeMask typeOfSend(T node);
- TypeMask typeOfGetter(T node);
- TypeMask typeOfOperator(T node);
+ AbstractValue typeOfSend(T node);
+ AbstractValue typeOfGetter(T node);
- void setTypeMask(T node, TypeMask mask);
+ void setTypeMask(T node, AbstractValue mask);
- void setGetterTypeMaskInComplexSendSet(T node, TypeMask mask);
+ AbstractValue typeOfIterator(T node);
- void setOperatorTypeMaskInComplexSendSet(T node, TypeMask mask);
+ AbstractValue typeOfIteratorMoveNext(T node);
- TypeMask typeOfIterator(T node);
+ AbstractValue typeOfIteratorCurrent(T node);
- TypeMask typeOfIteratorMoveNext(T node);
+ void setIteratorTypeMask(T node, AbstractValue mask);
- TypeMask typeOfIteratorCurrent(T node);
+ void setMoveNextTypeMask(T node, AbstractValue mask);
- void setIteratorTypeMask(T node, TypeMask mask);
-
- void setMoveNextTypeMask(T node, TypeMask mask);
-
- void setCurrentTypeMask(T node, TypeMask mask);
-}
-
-class AstGlobalTypeInferenceElementData
- extends GlobalTypeInferenceElementData<Node> {
- Map<Object, TypeMask> _typeMasks;
-
- TypeMask _get(Object node) => _typeMasks != null ? _typeMasks[node] : null;
- void _set(Object node, TypeMask mask) {
- _typeMasks ??= new Maplet<Object, TypeMask>();
- _typeMasks[node] = mask;
- }
-
- TypeMask typeOfSend(covariant Send node) => _get(node);
- TypeMask typeOfGetter(covariant SendSet node) => _get(node.selector);
- TypeMask typeOfOperator(covariant SendSet node) =>
- _get(node.assignmentOperator);
-
- void setTypeMask(covariant Send node, TypeMask mask) {
- _set(node, mask);
- }
-
- void setGetterTypeMaskInComplexSendSet(
- covariant SendSet node, TypeMask mask) {
- _set(node.selector, mask);
- }
-
- void setOperatorTypeMaskInComplexSendSet(
- covariant SendSet node, TypeMask mask) {
- _set(node.assignmentOperator, mask);
- }
-
- // TODO(sigmund): clean up. We store data about 3 selectors for "for in"
- // nodes: the iterator, move-next, and current element. Because our map keys
- // are nodes, we need to fabricate different keys to keep these selectors
- // separate. The current implementation does this by using
- // children of the for-in node (these children were picked arbitrarily).
-
- TypeMask typeOfIterator(covariant ForIn node) => _get(node);
-
- TypeMask typeOfIteratorMoveNext(covariant ForIn node) => _get(node.forToken);
-
- TypeMask typeOfIteratorCurrent(covariant ForIn node) => _get(node.inToken);
-
- void setIteratorTypeMask(covariant ForIn node, TypeMask mask) {
- _set(node, mask);
- }
-
- void setMoveNextTypeMask(covariant ForIn node, TypeMask mask) {
- _set(node.forToken, mask);
- }
-
- void setCurrentTypeMask(covariant ForIn node, TypeMask mask) {
- _set(node.inToken, mask);
- }
+ void setCurrentTypeMask(T node, AbstractValue mask);
}
/// API to interact with the global type-inference engine.
abstract class TypesInferrer<T> {
+ AbstractValueDomain get abstractValueDomain;
void analyzeMain(FunctionEntity element);
- TypeMask getReturnTypeOfMember(MemberEntity element);
- TypeMask getReturnTypeOfParameter(Local element);
- TypeMask getTypeOfMember(MemberEntity element);
- TypeMask getTypeOfParameter(Local element);
- TypeMask getTypeForNewList(T node);
- TypeMask getTypeOfSelector(Selector selector, TypeMask mask);
+ AbstractValue getReturnTypeOfMember(MemberEntity element);
+ AbstractValue getReturnTypeOfParameter(Local element);
+ AbstractValue getTypeOfMember(MemberEntity element);
+ AbstractValue getTypeOfParameter(Local element);
+ AbstractValue getTypeForNewList(T node);
+ AbstractValue getTypeOfSelector(Selector selector, AbstractValue receiver);
void clear();
bool isMemberCalledOnce(MemberEntity element);
bool isFixedArrayCheckedForGrowable(T node);
@@ -293,11 +227,9 @@
parameter, () => createParameterResult(_inferrer, parameter));
}
- TypeMask get dynamicType => closedWorld.abstractValueDomain.dynamicType;
-
/// Returns the type of a [selector] when applied to a receiver with the given
/// type [mask].
- TypeMask typeOfSelector(Selector selector, TypeMask mask) =>
+ AbstractValue typeOfSelector(Selector selector, AbstractValue mask) =>
_inferrer.getTypeOfSelector(selector, mask);
/// Returns whether a fixed-length constructor call goes through a growable
@@ -308,56 +240,6 @@
_inferrer.isFixedArrayCheckedForGrowable(ctorCall);
}
-/// Mixin that assert the types of the nodes used for querying type masks.
-abstract class AstGlobalTypeInferenceElementResultMixin
- implements GlobalTypeInferenceElementResultImpl<Node> {
- TypeMask typeOfNewList(covariant Send node) =>
- _inferrer.getTypeForNewList(node);
-
- TypeMask typeOfListLiteral(covariant LiteralList node) =>
- _inferrer.getTypeForNewList(node);
-
- TypeMask typeOfSend(covariant Send node) => _data?.typeOfSend(node);
- TypeMask typeOfGetter(covariant SendSet node) => _data?.typeOfGetter(node);
- TypeMask typeOfOperator(covariant SendSet node) =>
- _data?.typeOfOperator(node);
- TypeMask typeOfIterator(covariant ForIn node) => _data?.typeOfIterator(node);
- TypeMask typeOfIteratorMoveNext(covariant ForIn node) =>
- _data?.typeOfIteratorMoveNext(node);
- TypeMask typeOfIteratorCurrent(covariant ForIn node) =>
- _data?.typeOfIteratorCurrent(node);
-}
-
-class AstMemberResult = GlobalTypeInferenceMemberResultImpl<Node>
- with AstGlobalTypeInferenceElementResultMixin;
-
-class AstParameterResult = GlobalTypeInferenceParameterResultImpl<Node>
- with AstGlobalTypeInferenceElementResultMixin;
-
-class AstGlobalTypeInferenceResults extends GlobalTypeInferenceResults<Node> {
- AstGlobalTypeInferenceResults(
- TypesInferrer<Node> inferrer, ClosedWorld closedWorld)
- : super(inferrer, closedWorld);
-
- GlobalTypeInferenceMemberResult<Node> createMemberResult(
- TypeGraphInferrer<Node> inferrer, covariant MemberElement member,
- {bool isJsInterop: false}) {
- return new AstMemberResult(
- member,
- // We store data in the context of the enclosing method, even
- // for closure elements.
- inferrer.inferrer.lookupDataOfMember(member.memberContext),
- inferrer,
- isJsInterop,
- dynamicType);
- }
-
- GlobalTypeInferenceParameterResult<Node> createParameterResult(
- TypeGraphInferrer<Node> inferrer, Local parameter) {
- return new AstParameterResult(parameter, inferrer, dynamicType);
- }
-}
-
/// Global analysis that infers concrete types.
class GlobalTypeInferenceTask extends CompilerTask {
// TODO(sigmund): rename at the same time as our benchmarking tools.
diff --git a/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart b/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
index c6cf563..337975f 100644
--- a/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
+++ b/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
@@ -4,7 +4,6 @@
import '../common.dart';
import '../common_elements.dart';
-import '../elements/elements.dart' show ClassElement, MixinApplicationElement;
import '../elements/entities.dart';
import '../elements/types.dart' show InterfaceType;
import 'class_set.dart';
@@ -180,43 +179,3 @@
/// Returns all supertypes of [cls].
Iterable<InterfaceType> getSupertypes(covariant ClassEntity cls);
}
-
-class ElementClassQueries extends ClassQueries {
- final CommonElements commonElements;
-
- ElementClassQueries(this.commonElements);
-
- @override
- ClassEntity getDeclaration(ClassElement cls) {
- return cls.declaration;
- }
-
- @override
- ClassEntity getAppliedMixin(ClassElement cls) {
- if (cls.isMixinApplication) {
- MixinApplicationElement mixinApplication = cls;
- // Note: If [mixinApplication] is malformed [mixin] is `null`.
- return mixinApplication.mixin;
- }
- return null;
- }
-
- @override
- int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
-
- @override
- bool checkClass(ClassElement cls) => cls.isDeclaration;
-
- @override
- bool validateClass(ClassElement cls) => cls.isResolved;
-
- @override
- bool implementsFunction(ClassElement cls) =>
- cls.implementsFunction(commonElements);
-
- @override
- ClassEntity getSuperClass(ClassElement cls) => cls.superclass;
-
- @override
- Iterable<InterfaceType> getSupertypes(ClassElement cls) => cls.allSupertypes;
-}
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index c5a4869..3dd5e16 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -6,7 +6,6 @@
import 'dart:collection' show IterableBase;
-import '../elements/elements.dart' show ClassElement;
import '../elements/entities.dart' show ClassEntity;
import '../util/enumset.dart' show EnumSet;
import '../util/util.dart' show Link;
@@ -342,11 +341,12 @@
void printOn(StringBuffer sb, String indentation,
{bool instantiatedOnly: false,
bool sorted: true,
- ClassElement withRespectTo}) {
+ ClassEntity withRespectTo}) {
bool isRelatedTo(ClassEntity _subclass) {
- ClassElement subclass = _subclass;
- return subclass == withRespectTo ||
- subclass.implementsInterface(withRespectTo);
+ return true;
+ // TODO(johnniwinther): Support this for kernel based elements:
+ // return subclass == withRespectTo ||
+ // subclass.implementsInterface(withRespectTo);
}
sb.write(indentation);
@@ -406,7 +406,7 @@
String dump(
{String indentation: '',
bool instantiatedOnly: false,
- ClassElement withRespectTo}) {
+ ClassEntity withRespectTo}) {
StringBuffer sb = new StringBuffer();
printOn(sb, indentation,
instantiatedOnly: instantiatedOnly, withRespectTo: withRespectTo);
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index 12c547a0..2476b2b 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -637,104 +637,6 @@
}
}
-class ElementCodegenWorldBuilderImpl extends CodegenWorldBuilderImpl {
- final JavaScriptConstantCompiler _constants;
-
- ElementCodegenWorldBuilderImpl(
- this._constants,
- ElementEnvironment elementEnvironment,
- NativeBasicData nativeBasicData,
- ClosedWorld world,
- SelectorConstraintsStrategy selectorConstraintsStrategy)
- : super(elementEnvironment, nativeBasicData, world,
- selectorConstraintsStrategy);
-
- @override
- bool hasConstantFieldInitializer(FieldElement field) {
- return field.constant != null;
- }
-
- @override
- ConstantValue getConstantFieldInitializer(FieldElement field) {
- assert(field.constant != null,
- failedAt(field, "Field $field doesn't have a constant initial value."));
- return _constants.getConstantValue(field.constant);
- }
-
- /// Calls [f] with every instance field, together with its declarer, in an
- /// instance of [cls].
- void forEachInstanceField(
- ClassElement cls, void f(ClassEntity declarer, FieldEntity field)) {
- cls.implementation
- .forEachInstanceField(f, includeSuperAndInjectedMembers: true);
- }
-
- /// Calls [f] with every instance field of the immediate class [cls].
- void forEachDirectInstanceField(ClassElement cls, void f(FieldEntity field)) {
- cls.implementation.forEachInstanceField((ClassEntity _, FieldEntity field) {
- f(field);
- }, includeSuperAndInjectedMembers: false);
- }
-
- @override
- void forEachParameter(MethodElement function,
- void f(DartType type, String name, ConstantValue defaultValue)) {
- if (!function.hasFunctionSignature) return;
- function = function.implementation;
- FunctionSignature parameters = function.functionSignature;
- parameters.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- ConstantValue value;
- if (parameter.isOptional) {
- value = _constants.getConstantValue(parameter.constant);
- }
- f(parameter.type, parameter.name, value);
- });
- }
-
- @override
- void forEachParameterAsLocal(
- MethodElement function, void f(Local parameter)) {
- if (!function.hasFunctionSignature) return;
- function = function.implementation;
- FunctionSignature parameters = function.functionSignature;
- parameters.orderedForEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- f(parameter);
- });
- }
-
- @override
- void _processInstantiatedClassMember(
- ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) {
- assert(member.isDeclaration, failedAt(member));
- if (member.isMalformed) return;
- super._processInstantiatedClassMember(cls, member, memberUsed);
- }
-
- @override
- _MemberUsage _getMemberUsage(
- MemberElement member, MemberUsedCallback memberUsed) {
- assert(member.isDeclaration, failedAt(member));
- return super._getMemberUsage(member, memberUsed);
- }
-
- void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
- Element element = staticUse.element;
- assert(element.isDeclaration,
- failedAt(element, "Element ${element} is not the declaration."));
- super.registerStaticUse(staticUse, memberUsed);
- }
-
- void registerIsCheck(ResolutionDartType type) {
- // Even in checked mode, type annotations for return type and argument
- // types do not imply type checks, so there should never be a check
- // against the type variable of a typedef.
- assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
- super.registerIsCheck(type);
- }
-}
-
class KernelCodegenWorldBuilder extends CodegenWorldBuilderImpl {
final KernelToWorldBuilder _elementMap;
final GlobalLocalsMap _globalLocalsMap;
diff --git a/pkg/compiler/lib/src/universe/element_world_builder.dart b/pkg/compiler/lib/src/universe/element_world_builder.dart
deleted file mode 100644
index 5b25897..0000000
--- a/pkg/compiler/lib/src/universe/element_world_builder.dart
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of world_builder;
-
-/// [ResolutionEnqueuerWorldBuilder] based on the [Element] model.
-class ElementResolutionWorldBuilder extends ResolutionWorldBuilderBase {
- /// Used for testing the new more precise computation of instantiated types
- /// and classes.
- static bool useInstantiationMap = false;
-
- final Resolution _resolution;
-
- ElementResolutionWorldBuilder(
- JavaScriptBackend backend,
- this._resolution,
- NativeBasicData nativeBasicData,
- NativeDataBuilder nativeDataBuilder,
- InterceptorDataBuilder interceptorDataBuilder,
- BackendUsageBuilder backendUsageBuilder,
- RuntimeTypesNeedBuilder rtiNeedBuilder,
- NativeResolutionEnqueuer nativeResolutionEnqueuer,
- NoSuchMethodRegistry noSuchMethodRegistry,
- SelectorConstraintsStrategy selectorConstraintsStrategy,
- ClassHierarchyBuilder classHierarchyBuilder,
- ClassQueries classQueries)
- : super(
- backend.compiler.options,
- _resolution.elementEnvironment,
- _resolution.types,
- _resolution.commonElements,
- backend.constantSystem,
- nativeBasicData,
- nativeDataBuilder,
- interceptorDataBuilder,
- backendUsageBuilder,
- rtiNeedBuilder,
- nativeResolutionEnqueuer,
- noSuchMethodRegistry,
- selectorConstraintsStrategy,
- classHierarchyBuilder,
- classQueries);
-
- bool isImplemented(ClassElement cls) {
- return super.isImplemented(cls.declaration);
- }
-
- void registerTypeInstantiation(
- InterfaceType type, ClassUsedCallback classUsed,
- {ConstructorEntity constructor,
- bool byMirrors: false,
- bool isRedirection: false}) {
- ClassElement cls = type.element;
- cls.ensureResolved(_resolution);
- super.registerTypeInstantiation(type, classUsed,
- constructor: constructor,
- byMirrors: byMirrors,
- isRedirection: isRedirection);
- }
-
- /// Returns the instantiation map used for computing the closed world.
- ///
- /// If [useInstantiationMap] is `true`, redirections are removed and
- /// redirecting factories are converted to their effective target and type.
- Map<ClassEntity, InstantiationInfo> getInstantiationMap() {
- if (!useInstantiationMap) return _instantiationInfo;
-
- Map<ClassEntity, InstantiationInfo> instantiationMap =
- <ClassEntity, InstantiationInfo>{};
-
- InstantiationInfo infoFor(ClassEntity cls) {
- return instantiationMap.putIfAbsent(cls, () => new InstantiationInfo());
- }
-
- _instantiationInfo.forEach((cls, info) {
- if (info.instantiationMap != null) {
- info.instantiationMap.forEach((_constructor, Set<Instance> set) {
- ConstructorElement constructor = _constructor;
- for (Instance instance in set) {
- if (instance.isRedirection) {
- continue;
- }
- if (constructor == null || !constructor.isRedirectingFactory) {
- infoFor(cls)
- .addInstantiation(constructor, instance.type, instance.kind);
- } else {
- ConstructorElement target = constructor.effectiveTarget;
- ResolutionDartType targetType =
- constructor.computeEffectiveTargetType(instance.type);
- ClassElement cls = target.enclosingClass;
- bool isNative = _nativeBasicData.isNativeClass(cls);
- Instantiation kind;
- if (isNative) {
- kind = Instantiation.ABSTRACTLY_INSTANTIATED;
- } else if (cls.isAbstract) {
- kind = Instantiation.UNINSTANTIATED;
- } else {
- kind = Instantiation.DIRECTLY_INSTANTIATED;
- }
- if (targetType is ResolutionInterfaceType) {
- infoFor(targetType.element)
- .addInstantiation(target, targetType, kind);
- }
- }
- }
- });
- }
- });
- return instantiationMap;
- }
-
- void registerIsCheck(ResolutionDartType type) {
- type.computeUnaliased(_resolution);
- type = type.unaliased;
- // Even in checked mode, type annotations for return type and argument
- // types do not imply type checks, so there should never be a check
- // against the type variable of a typedef.
- assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
- super.registerIsCheck(type);
- }
-
- void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
- Element element = staticUse.element;
- assert(element.isDeclaration,
- failedAt(element, "Element ${element} is not the declaration."));
- super.registerStaticUse(staticUse, memberUsed);
- }
-
- _ClassUsage _createClassUsage(ClassElement cls) {
- cls.ensureResolved(_resolution);
- _resolution.ensureClassMembers(cls);
- return super._createClassUsage(cls);
- }
-
- void _processInstantiatedClassMember(
- ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) {
- assert(member.isDeclaration, failedAt(member));
- member.computeType(_resolution);
- super._processInstantiatedClassMember(cls, member, memberUsed);
- }
-
- ClosedWorld closeWorld() {
- Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses =
- populateHierarchyNodes();
- _closed = true;
-
- return _closedWorldCache = new ClosedWorldImpl(
- options: _options,
- elementEnvironment: _elementEnvironment,
- dartTypes: _dartTypes,
- commonElements: _commonElements,
- constantSystem: _constantSystem,
- nativeData: _nativeDataBuilder.close(),
- interceptorData: _interceptorDataBuilder.close(),
- backendUsage: _backendUsageBuilder.close(),
- noSuchMethodData: _noSuchMethodRegistry.close(),
- resolutionWorldBuilder: this,
- rtiNeedBuilder: _rtiNeedBuilder,
- implementedClasses: _implementedClasses,
- liveNativeClasses: _nativeResolutionEnqueuer.liveNativeClasses,
- liveInstanceMembers: _liveInstanceMembers,
- assignedInstanceMembers: computeAssignedInstanceMembers(),
- processedMembers: _processedMembers,
- allTypedefs: _allTypedefs,
- mixinUses: classHierarchyBuilder.mixinUses,
- typesImplementedBySubclasses: typesImplementedBySubclasses,
- classHierarchyNodes: classHierarchyBuilder.classHierarchyNodes,
- classSets: classHierarchyBuilder.classSets);
- }
-
- @override
- void forEachLocalFunction(void f(MemberEntity member, Local localFunction)) {
- for (LocalFunctionElement local in localFunctions) {
- f(local.memberContext, local);
- }
- }
-}
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 01f27b2..aee80f5 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -6,11 +6,9 @@
import '../common/names.dart' show Identifiers, Selectors;
import '../elements/entities.dart';
-import '../types/types.dart';
+import '../types/abstract_value_domain.dart';
import '../util/util.dart' show Hashing, Setlet;
-import '../world.dart' show ClosedWorld;
import 'selector.dart' show Selector;
-import 'world_builder.dart' show ReceiverConstraint;
// TODO(kasperl): This actually holds getters and setters just fine
// too and stricly they aren't functions. Maybe this needs a better
@@ -41,9 +39,9 @@
/// receiver with the given [constraint]. The returned elements may include
/// noSuchMethod handlers that are potential targets indirectly through the
/// noSuchMethod mechanism.
- Iterable<MemberEntity> filter(Selector selector,
- ReceiverConstraint constraint, ClosedWorld closedWorld) {
- return query(selector, constraint, closedWorld).functions;
+ Iterable<MemberEntity> filter(
+ Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+ return query(selector, receiver, domain).functions;
}
/// Returns the mask for the potential receivers of a dynamic call to
@@ -52,43 +50,38 @@
/// This will narrow the constraints of [constraint] to a [TypeMask] of the
/// set of classes that actually implement the selected member or implement
/// the handling 'noSuchMethod' where the selected member is unimplemented.
- TypeMask receiverType(Selector selector, ReceiverConstraint constraint,
- ClosedWorld closedWorld) {
- return query(selector, constraint, closedWorld).computeMask(closedWorld);
+ AbstractValue receiverType(
+ Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+ return query(selector, receiver, domain).computeMask(domain);
}
- SelectorMask _createSelectorMask(Selector selector,
- ReceiverConstraint constraint, ClosedWorld closedWorld) {
- return constraint != null
- ? new SelectorMask(selector, constraint)
- : new SelectorMask(
- selector,
- new TypeMask.subclass(
- closedWorld.commonElements.objectClass, closedWorld));
+ SelectorMask _createSelectorMask(
+ Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+ return receiver != null
+ ? new SelectorMask(selector, receiver)
+ : new SelectorMask(selector, domain.dynamicType);
}
/// Returns the set of functions that can be the target of a call to
/// [selector] on a receiver constrained by [constraint] including
/// 'noSuchMethod' methods where applicable.
- FunctionSetQuery query(Selector selector, ReceiverConstraint constraint,
- ClosedWorld closedWorld) {
+ FunctionSetQuery query(
+ Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
String name = selector.name;
- SelectorMask selectorMask =
- _createSelectorMask(selector, constraint, closedWorld);
+ SelectorMask selectorMask = _createSelectorMask(selector, receiver, domain);
SelectorMask noSuchMethodMask =
- new SelectorMask(Selectors.noSuchMethod_, selectorMask.constraint);
+ new SelectorMask(Selectors.noSuchMethod_, selectorMask.receiver);
FunctionSetNode node = _nodes[name];
FunctionSetNode noSuchMethods = _nodes[Identifiers.noSuchMethod_];
if (node != null) {
- return node.query(
- selectorMask, closedWorld, noSuchMethods, noSuchMethodMask);
+ return node.query(selectorMask, domain, noSuchMethods, noSuchMethodMask);
}
// If there is no method that matches [selector] we know we can
// only hit [:noSuchMethod:].
if (noSuchMethods == null) {
return const EmptyFunctionSetQuery();
}
- return noSuchMethods.query(noSuchMethodMask, closedWorld);
+ return noSuchMethods.query(noSuchMethodMask, domain);
}
void forEach(void action(MemberEntity member)) {
@@ -102,34 +95,32 @@
/// on a receiver constrained by [constraint].
class SelectorMask {
final Selector selector;
- final ReceiverConstraint constraint;
+ final AbstractValue receiver;
final int hashCode;
- SelectorMask(Selector selector, ReceiverConstraint constraint)
- : this.selector = selector,
- this.constraint = constraint,
- this.hashCode =
- Hashing.mixHashCodeBits(selector.hashCode, constraint.hashCode) {
- assert(constraint != null);
+ SelectorMask(this.selector, this.receiver)
+ : this.hashCode =
+ Hashing.mixHashCodeBits(selector.hashCode, receiver.hashCode) {
+ assert(receiver != null);
}
String get name => selector.name;
- bool applies(MemberEntity element, ClosedWorld closedWorld) {
+ bool applies(MemberEntity element, AbstractValueDomain domain) {
if (!selector.appliesUnnamed(element)) return false;
- return constraint.canHit(element, selector, closedWorld);
+ return domain.canHit(receiver, element, selector);
}
- bool needsNoSuchMethodHandling(ClosedWorld closedWorld) {
- return constraint.needsNoSuchMethodHandling(selector, closedWorld);
+ bool needsNoSuchMethodHandling(AbstractValueDomain domain) {
+ return domain.needsNoSuchMethodHandling(receiver, selector);
}
bool operator ==(other) {
if (identical(this, other)) return true;
- return selector == other.selector && constraint == other.constraint;
+ return selector == other.selector && receiver == other.receiver;
}
- String toString() => '($selector,$constraint)';
+ String toString() => '($selector,$receiver)';
}
/// A node in the [FunctionSet] caching all [FunctionSetQuery] object for
@@ -202,7 +193,7 @@
/// Returns the set of functions that can be the target of [selectorMask]
/// including no such method handling where applicable.
- FunctionSetQuery query(SelectorMask selectorMask, ClosedWorld closedWorld,
+ FunctionSetQuery query(SelectorMask selectorMask, AbstractValueDomain domain,
[FunctionSetNode noSuchMethods, SelectorMask noSuchMethodMask]) {
assert(selectorMask.name == name);
FunctionSetQuery result = cache[selectorMask];
@@ -210,7 +201,7 @@
Setlet<MemberEntity> functions;
for (MemberEntity element in elements) {
- if (selectorMask.applies(element, closedWorld)) {
+ if (selectorMask.applies(element, domain)) {
if (functions == null) {
// Defer the allocation of the functions set until we are
// sure we need it. This allows us to return immutable empty
@@ -225,9 +216,9 @@
// add [noSuchMethod] implementations that apply to [mask] as
// potential targets.
if (noSuchMethods != null &&
- selectorMask.needsNoSuchMethodHandling(closedWorld)) {
+ selectorMask.needsNoSuchMethodHandling(domain)) {
FunctionSetQuery noSuchMethodQuery =
- noSuchMethods.query(noSuchMethodMask, closedWorld);
+ noSuchMethods.query(noSuchMethodMask, domain);
if (!noSuchMethodQuery.functions.isEmpty) {
if (functions == null) {
functions =
@@ -263,7 +254,7 @@
const FunctionSetQuery();
/// Compute the type of all potential receivers of this function set.
- TypeMask computeMask(ClosedWorld closedWorld);
+ AbstractValue computeMask(AbstractValueDomain domain);
/// Returns all potential targets of this function set.
Iterable<MemberEntity> get functions;
@@ -273,8 +264,7 @@
const EmptyFunctionSetQuery();
@override
- TypeMask computeMask(ClosedWorld closedWorld) =>
- const TypeMask.nonNullEmpty();
+ AbstractValue computeMask(AbstractValueDomain domain) => domain.emptyType;
@override
Iterable<MemberEntity> get functions => const <MemberEntity>[];
@@ -286,31 +276,14 @@
@override
final Iterable<MemberEntity> functions;
- TypeMask _mask;
+ AbstractValue _receiver;
FullFunctionSetQuery(this.functions);
@override
- TypeMask computeMask(ClosedWorld closedWorld) {
- assert(closedWorld
- .hasAnyStrictSubclass(closedWorld.commonElements.objectClass));
- if (_mask != null) return _mask;
- return _mask = new TypeMask.unionOf(
- functions.expand((MemberEntity element) {
- ClassEntity cls = element.enclosingClass;
- return [cls]..addAll(closedWorld.mixinUsesOf(cls));
- }).map((cls) {
- if (closedWorld.commonElements.jsNullClass == cls) {
- return const TypeMask.empty();
- } else if (closedWorld.isInstantiated(cls)) {
- return new TypeMask.nonNullSubclass(cls, closedWorld);
- } else {
- // TODO(johnniwinther): Avoid the need for this case.
- return const TypeMask.empty();
- }
- }),
- closedWorld);
+ AbstractValue computeMask(AbstractValueDomain domain) {
+ return _receiver ??= domain.computeReceiver(functions);
}
- String toString() => '$_mask:$functions';
+ String toString() => '$_receiver:$functions';
}
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 3d03614..d4af193 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -6,8 +6,8 @@
import '../common.dart';
import '../common/names.dart' show Names;
-import '../elements/elements.dart' show Elements;
import '../elements/entities.dart';
+import '../elements/entity_utils.dart' as utils;
import '../elements/names.dart';
import '../elements/operators.dart';
import '../util/util.dart' show Hashing;
@@ -153,12 +153,12 @@
factory Selector.unaryOperator(String name) => new Selector(
SelectorKind.OPERATOR,
- new PublicName(Elements.constructOperatorName(name, true)),
+ new PublicName(utils.constructOperatorName(name, true)),
CallStructure.NO_ARGS);
factory Selector.binaryOperator(String name) => new Selector(
SelectorKind.OPERATOR,
- new PublicName(Elements.constructOperatorName(name, false)),
+ new PublicName(utils.constructOperatorName(name, false)),
CallStructure.ONE_ARG);
factory Selector.index() =>
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index d5c894e..0fcec7e 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -16,11 +16,9 @@
/// program.
library dart2js.universe.use;
-import '../closure.dart' show BoxFieldElement;
import '../common.dart';
import '../constants/values.dart';
import '../elements/types.dart';
-import '../elements/elements.dart' show Element;
import '../elements/entities.dart';
import '../js_model/closure.dart';
import '../util/util.dart' show equalElements, Hashing;
@@ -43,6 +41,29 @@
DynamicUse(this.selector);
+ /// Short textual representation use for testing.
+ String get shortText {
+ StringBuffer sb = new StringBuffer();
+ sb.write(selector.name);
+ if (typeArguments != null && typeArguments.isNotEmpty) {
+ sb.write('<');
+ sb.write(typeArguments.join(','));
+ sb.write('>');
+ }
+ if (selector.isCall) {
+ sb.write('(');
+ sb.write(selector.callStructure.positionalArgumentCount);
+ if (selector.callStructure.namedArgumentCount > 0) {
+ sb.write(',');
+ sb.write(selector.callStructure.getOrderedNamedArguments().join(','));
+ }
+ sb.write(')');
+ } else if (selector.isSetter) {
+ sb.write('=');
+ }
+ return sb.toString();
+ }
+
bool appliesUnnamed(MemberEntity element, World world) {
return selector.appliesUnnamed(element) &&
(mask == null || mask.canHit(element, selector, world));
@@ -149,11 +170,52 @@
{this.type, this.callStructure, typeArgumentsHash: 0})
: this.element = element,
this.hashCode = Hashing.objectsHash(
- element, kind, type, typeArgumentsHash, callStructure) {
- assert(
- !(element is Element && !element.isDeclaration),
- failedAt(element,
- "Static use element $element must be the declaration element."));
+ element, kind, type, typeArgumentsHash, callStructure);
+
+ /// Short textual representation use for testing.
+ String get shortText {
+ StringBuffer sb = new StringBuffer();
+ switch (kind) {
+ case StaticUseKind.FIELD_SET:
+ case StaticUseKind.SUPER_FIELD_SET:
+ case StaticUseKind.SET:
+ sb.write('set:');
+ break;
+ case StaticUseKind.INIT:
+ sb.write('init:');
+ break;
+ case StaticUseKind.CLOSURE:
+ sb.write('def:');
+ break;
+ default:
+ }
+ if (element is MemberEntity) {
+ MemberEntity member = element;
+ if (member.enclosingClass != null) {
+ sb.write(member.enclosingClass.name);
+ sb.write('.');
+ }
+ }
+ if (element.name == null) {
+ sb.write('<anonymous>');
+ } else {
+ sb.write(element.name);
+ }
+ if (typeArguments != null && typeArguments.isNotEmpty) {
+ sb.write('<');
+ sb.write(typeArguments.join(','));
+ sb.write('>');
+ }
+ if (callStructure != null) {
+ sb.write('(');
+ sb.write(callStructure.positionalArgumentCount);
+ if (callStructure.namedArgumentCount > 0) {
+ sb.write(',');
+ sb.write(callStructure.getOrderedNamedArguments().join(','));
+ }
+ sb.write(')');
+ }
+ return sb.toString();
}
List<DartType> get typeArguments => null;
@@ -417,9 +479,7 @@
/// Read access of an instance field or boxed field [element].
factory StaticUse.fieldGet(FieldEntity element) {
assert(
- element.isInstanceMember ||
- element is BoxFieldElement ||
- element is JRecordField,
+ element.isInstanceMember || element is JRecordField,
failedAt(element,
"Field init element $element must be an instance or boxed field."));
return new StaticUse.internal(element, StaticUseKind.FIELD_GET);
@@ -428,9 +488,7 @@
/// Write access of an instance field or boxed field [element].
factory StaticUse.fieldSet(FieldEntity element) {
assert(
- element.isInstanceMember ||
- element is BoxFieldElement ||
- element is JRecordField,
+ element.isInstanceMember || element is JRecordField,
failedAt(element,
"Field init element $element must be an instance or boxed field."));
return new StaticUse.internal(element, StaticUseKind.FIELD_SET);
@@ -533,6 +591,45 @@
this.kind = kind,
this.hashCode = Hashing.objectHash(type, Hashing.objectHash(kind));
+ /// Short textual representation use for testing.
+ String get shortText {
+ StringBuffer sb = new StringBuffer();
+ switch (kind) {
+ case TypeUseKind.IS_CHECK:
+ sb.write('is:');
+ break;
+ case TypeUseKind.AS_CAST:
+ sb.write('as:');
+ break;
+ case TypeUseKind.CHECKED_MODE_CHECK:
+ sb.write('check:');
+ break;
+ case TypeUseKind.CATCH_TYPE:
+ sb.write('catch:');
+ break;
+ case TypeUseKind.TYPE_LITERAL:
+ sb.write('lit:');
+ break;
+ case TypeUseKind.INSTANTIATION:
+ sb.write('inst:');
+ break;
+ case TypeUseKind.MIRROR_INSTANTIATION:
+ sb.write('mirror:');
+ break;
+ case TypeUseKind.NATIVE_INSTANTIATION:
+ sb.write('native:');
+ break;
+ case TypeUseKind.IMPLICIT_CAST:
+ sb.write('impl:');
+ break;
+ case TypeUseKind.PARAMETER_CHECK:
+ sb.write('param:');
+ break;
+ }
+ sb.write(type);
+ return sb.toString();
+ }
+
/// [type] used in an is check, like `e is T` or `e is! T`.
factory TypeUse.isCheck(DartType type) {
return new TypeUse.internal(type, TypeUseKind.IS_CHECK);
@@ -616,6 +713,11 @@
ConstantUse._(this.value, this.kind)
: this.hashCode = Hashing.objectHash(value, kind.hashCode);
+ /// Short textual representation use for testing.
+ String get shortText {
+ return value.toDartText();
+ }
+
/// Constant used as the initial value of a field.
ConstantUse.init(ConstantValue value) : this._(value, ConstantUseKind.DIRECT);
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index fdac83d..44d098b 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -8,18 +8,12 @@
import '../common.dart';
import '../common/names.dart' show Identifiers, Names;
-import '../common/resolution.dart' show Resolution;
import '../common_elements.dart';
import '../constants/constant_system.dart';
import '../constants/values.dart';
-import '../elements/elements.dart';
import '../elements/entities.dart';
-import '../elements/resolution_types.dart';
import '../elements/types.dart';
-import '../js_backend/backend.dart' show JavaScriptBackend;
import '../js_backend/backend_usage.dart' show BackendUsageBuilder;
-import '../js_backend/constant_handler_javascript.dart'
- show JavaScriptConstantCompiler;
import '../js_backend/interceptor_data.dart' show InterceptorDataBuilder;
import '../js_backend/native_data.dart' show NativeBasicData, NativeDataBuilder;
import '../js_backend/no_such_method_registry.dart';
@@ -32,7 +26,7 @@
import '../universe/class_set.dart';
import '../util/enumset.dart';
import '../util/util.dart';
-import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld;
+import '../world.dart' show World, ClosedWorld, OpenWorld;
import 'class_hierarchy_builder.dart' show ClassHierarchyBuilder, ClassQueries;
import 'selector.dart' show Selector;
import 'use.dart'
@@ -45,7 +39,6 @@
StaticUseKind;
part 'codegen_world_builder.dart';
-part 'element_world_builder.dart';
part 'member_usage.dart';
part 'resolution_world_builder.dart';
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
deleted file mode 100644
index 6edbf01..0000000
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// This file use methods that aren't used by dart2js.dart, but that we wish to
-/// keep anyway. This might be general API that isn't currently in use,
-/// debugging aids, or API only used for testing (see TODO below).
-
-library dart2js.use_unused_api;
-
-import '../compiler.dart' as api;
-import 'colors.dart' as colors;
-import 'compiler.dart' as compiler;
-import 'constants/constant_system.dart' as constants;
-import 'constants/constructors.dart' as constants;
-import 'constants/evaluation.dart' as constants;
-import 'constants/expressions.dart' as constants;
-import 'constants/values.dart' as constants;
-import 'dart2js.dart' as dart2js;
-import 'elements/resolution_types.dart' as dart_types;
-import 'deferred_load.dart' as deferred_load;
-import 'diagnostics/source_span.dart' as diagnostics;
-import 'elements/elements.dart' as elements;
-import 'elements/modelx.dart' as modelx;
-import 'elements/names.dart' as names;
-import 'elements/operators.dart' as operators;
-import 'elements/visitor.dart' as elements_visitor;
-import 'filenames.dart' as filenames;
-import 'inferrer/type_graph_inferrer.dart' as type_graph_inferrer;
-import 'io/location_provider.dart' as io;
-import 'io/source_map_builder.dart' as io;
-import 'js/js.dart' as js;
-import 'js_backend/js_backend.dart' as js_backend;
-import 'parser/partial_elements.dart'
- show PartialClassElement, PartialFunctionElement;
-import 'resolution/semantic_visitor.dart' as semantic_visitor;
-import 'script.dart';
-import 'source_file_provider.dart' as source_file_provider;
-import 'ssa/nodes.dart' as ssa;
-import 'tree/tree.dart' as tree;
-import 'util/util.dart' as util;
-import 'world.dart';
-
-class ElementVisitor extends elements_visitor.BaseElementVisitor {
- visitElement(e, a) {}
-}
-
-void main(List<String> arguments) {
- useApi(null);
- dart2js.main(arguments);
- names.Name.isPublicName(null);
- useConstant();
- useNode(null);
- useUtil(null);
- useSetlet(null);
- useImmutableEmptySet(null);
- useElementVisitor(new ElementVisitor());
- useJsNode(new js.Program(null));
- useJsNode(new js.NamedFunction(null, null));
- useJsNode(new js.ArrayHole());
- useJsOther(new js.SimpleJavaScriptPrintingContext());
- useJsBackend(null);
- useColor();
- useFilenames();
- useSsa(null);
- useIo();
- usedByTests();
- useElements();
- useCompiler(null);
- useTypes();
- useScript(null);
- useSemanticVisitor();
- useDeferred();
-}
-
-useApi([api.ReadStringFromUri uri, compiler.Compiler compiler]) {
- compiler.analyzeUri(null);
- new diagnostics.SourceSpan.fromNode(null, null);
-}
-
-class NullConstantConstructorVisitor
- extends constants.ConstantConstructorVisitor {
- @override
- visitGenerative(constants.GenerativeConstantConstructor constructor, arg) {}
-
- @override
- visitRedirectingFactory(
- constants.RedirectingFactoryConstantConstructor constructor, arg) {}
-
- @override
- visitRedirectingGenerative(
- constants.RedirectingGenerativeConstantConstructor constructor, arg) {}
-
- @override
- visitErroneous(constants.ErroneousConstantConstructor constructor, arg) {}
-}
-
-void useConstant(
- [constants.ConstantValue constant,
- constants.ConstantExpression expression,
- constants.ConstructedConstantExpression constructedConstant,
- constants.ConstantSystem cs,
- constants.EvaluationEnvironment env]) {
- constant.isObject;
- cs.isBool(constant);
- constructedConstant.computeInstanceType(null);
- constructedConstant.computeInstanceData(null);
- expression.evaluate(null, null);
- new NullConstantConstructorVisitor()
- ..visit(null, null)
- ..visitGenerative(null, null)
- ..visitRedirectingFactory(null, null)
- ..visitRedirectingGenerative(null, null);
-}
-
-void useNode(tree.Node node) {
- node
- ..asAsyncModifier()
- ..asAsyncForIn()
- ..asAwait()
- ..asBreakStatement()
- ..asCascade()
- ..asCatchBlock()
- ..asClassNode()
- ..asCombinator()
- ..asConditional()
- ..asContinueStatement()
- ..asEnum()
- ..asErrorExpression()
- ..asExport()
- ..asFor()
- ..asFunctionDeclaration()
- ..asIf()
- ..asImport()
- ..asLabeledStatement()
- ..asLibraryDependency()
- ..asLibraryName()
- ..asLiteralDouble()
- ..asLiteralList()
- ..asLiteralMap()
- ..asLiteralMapEntry()
- ..asLiteralNull()
- ..asLiteralSymbol()
- ..asMetadata()
- ..asModifiers()
- ..asPart()
- ..asPartOf()
- ..asRethrow()
- ..asReturn()
- ..asStatement()
- ..asStringInterpolation()
- ..asStringInterpolationPart()
- ..asStringJuxtaposition()
- ..asStringNode()
- ..asSwitchCase()
- ..asSwitchStatement()
- ..asSyncForIn()
- ..asTryStatement()
- ..asNominalTypeAnnotation()
- ..asTypeVariable()
- ..asTypedef()
- ..asWhile()
- ..asYield();
-}
-
-void useUtil(util.Link link) {
- link.reversePrependAll(link);
- link.copyWithout(link);
- util.longestCommonPrefixLength(null, null);
- new util.Pair(null, null);
-}
-
-void useSetlet(util.Setlet setlet) {
- setlet.difference(setlet);
- setlet.retainWhere(null);
-}
-
-void useImmutableEmptySet(util.ImmutableEmptySet set) {
- set.retainWhere(null);
-}
-
-void useElementVisitor(ElementVisitor visitor) {
- visitor
- ..visit(null, null)
- ..visitAbstractFieldElement(null, null)
- ..visitAmbiguousElement(null, null)
- ..visitBoxFieldElement(null, null)
- ..visitClassElement(null, null)
- ..visitClosureClassElement(null, null)
- ..visitClosureFieldElement(null, null)
- ..visitCompilationUnitElement(null, null)
- ..visitConstructorBodyElement(null, null)
- ..visitElement(null, null)
- ..visitErroneousElement(null, null)
- ..visitFieldParameterElement(null, null)
- ..visitFunctionElement(null, null)
- ..visitLibraryElement(null, null)
- ..visitMixinApplicationElement(null, null)
- ..visitPrefixElement(null, null)
- ..visitScopeContainerElement(null, null)
- ..visitTypeDeclarationElement(null, null)
- ..visitTypeVariableElement(null, null)
- ..visitTypedefElement(null, null)
- ..visitVariableElement(null, null)
- ..visitWarnOnUseElement(null, null);
-}
-
-useJsNode(js.Node node) {
- node.asVariableUse();
-}
-
-useJsOther(js.SimpleJavaScriptPrintingContext context) {
- context.getText();
-}
-
-useJsBackend(js_backend.JavaScriptBackend backend) {
- backend.getGeneratedCode(null);
-}
-
-useColor() {
- colors.white(null);
- colors.blue(null);
- colors.yellow(null);
- colors.black(null);
-}
-
-useFilenames() {
- filenames.appendSlash(null);
-}
-
-useSsa(ssa.HInstruction instruction) {
- instruction.isConstantNumber();
- new ssa.HAndOrBlockInformation(null, null, null);
- new ssa.HStatementSequenceInformation(null);
-}
-
-useIo([io.LineColumnMap map, io.LocationProvider provider]) {
- map
- ..addFirst(null, null, null)
- ..forEachLine(null)
- ..getFirstElementsInLine(null)
- ..forEachColumn(null, null);
-}
-
-usedByTests() {
- // TODO(ahe): We should try to avoid including API used only for tests. In
- // most cases, such API can be moved to a test library.
- ClosedWorldImpl closedWorld = null;
- type_graph_inferrer.TypeGraphInferrer typeGraphInferrer = null;
- source_file_provider.SourceFileProvider sourceFileProvider = null;
- sourceFileProvider.getUtf8SourceFile(null);
- closedWorld.hasAnyUserDefinedGetter(null, null);
- closedWorld.subclassesOf(null);
- closedWorld.getClassHierarchyNode(null);
- closedWorld.getClassSet(null);
- closedWorld.haveAnyCommonSubtypes(null, null);
- typeGraphInferrer.getCallersOfForTesting(null);
- dart_types.Types.sorted(null);
- new dart_types.Types(null).copy(null);
-}
-
-useElements(
- [elements.ClassElement e,
- names.Name n,
- modelx.FieldElementX f,
- PartialClassElement pce,
- PartialFunctionElement pfe,
- elements.LibraryElement l]) {
- e.lookupClassMember(null);
- e.lookupInterfaceMember(null);
- n.isAccessibleFrom(null);
- f.reuseElement();
- pce.copyWithEnclosing(null);
- pfe.copyWithEnclosing(null);
- l.forEachImport(null);
-}
-
-useCompiler(compiler.Compiler c) {
- c.libraryLoader
- ..reset()
- ..resetAsync(null)
- ..lookupLibrary(null);
- c.backend.constantCompilerTask.copyConstantValues(null);
- c.currentlyInUserCode();
-}
-
-useTypes() {}
-
-useScript(Script script) {
- script.copyWithFile(null);
-}
-
-useSemanticVisitor() {
- operators.UnaryOperator.fromKind(null);
- operators.BinaryOperator.fromKind(null);
- new semantic_visitor.BulkSendVisitor()..apply(null, null);
- new semantic_visitor.TraversalVisitor(null).apply(null, null);
- new semantic_visitor.BulkDeclarationVisitor().apply(null, null);
-}
-
-useDeferred([deferred_load.DeferredLoadTask task]) {
- task.dump();
-}
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index c781eb0..523bca7 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -5,20 +5,11 @@
library dart2js.world;
import 'dart:collection' show Queue;
-import 'closure.dart';
import 'common.dart';
import 'common/names.dart';
import 'common_elements.dart' show CommonElements, ElementEnvironment;
import 'constants/constant_system.dart';
import 'elements/entities.dart';
-import 'elements/elements.dart'
- show
- ClassElement,
- Element,
- MemberElement,
- MethodElement,
- MixinApplicationElement;
-import 'elements/resolution_types.dart';
import 'elements/types.dart';
import 'js_backend/backend_usage.dart' show BackendUsage;
import 'js_backend/interceptor_data.dart' show InterceptorData;
@@ -29,7 +20,7 @@
import 'ordered_typeset.dart';
import 'options.dart';
import 'types/abstract_value_domain.dart';
-import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
+import 'types/masks.dart' show CommonMasks, TypeMask;
import 'universe/class_set.dart';
import 'universe/function_set.dart' show FunctionSet;
import 'universe/selector.dart' show Selector;
@@ -288,11 +279,6 @@
/// methods defined in [ClosedWorld].
ClassSet getClassSet(ClassEntity cls);
- /// Return the cached mask for [base] with the given flags, or
- /// calls [createMask] to create the mask and cache it.
- // TODO(johnniwinther): Find a better strategy for caching these?
- TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask());
-
/// Returns `true` if the field [element] is known to be effectively final.
bool fieldNeverChanges(MemberEntity element);
@@ -523,21 +509,10 @@
@override
ClosedWorld get closedWorld => this;
- /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
- /// `FlatTypeMask.flags` property.
- final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks =
- new List<Map<ClassEntity, TypeMask>>.filled(8, null);
-
CommonMasks get abstractValueDomain {
return _commonMasks;
}
- TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
- Map<ClassEntity, TypeMask> cachedMasks =
- _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
- return cachedMasks.putIfAbsent(base, createMask);
- }
-
bool checkEntity(covariant Entity element);
bool checkClass(covariant ClassEntity cls);
@@ -1079,18 +1054,18 @@
if (includesClosureCall(selector, mask)) {
return abstractValueDomain.dynamicType;
}
- return _allFunctions.receiverType(selector, mask, this);
+ return _allFunctions.receiverType(selector, mask, abstractValueDomain);
}
Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask) {
_ensureFunctionSet();
- return _allFunctions.filter(selector, mask, this);
+ return _allFunctions.filter(selector, mask, abstractValueDomain);
}
bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) {
_ensureFunctionSet();
return _allFunctions
- .filter(selector, mask, this)
+ .filter(selector, mask, abstractValueDomain)
.any((each) => each.isGetter);
}
@@ -1142,7 +1117,8 @@
}
SideEffects sideEffects = new SideEffects.empty();
_ensureFunctionSet();
- for (MemberEntity e in _allFunctions.filter(selector, mask, this)) {
+ for (MemberEntity e
+ in _allFunctions.filter(selector, mask, abstractValueDomain)) {
if (e.isField) {
if (selector.isGetter) {
if (!fieldNeverChanges(e)) {
@@ -1268,10 +1244,6 @@
@override
String dump([ClassEntity cls]) {
- if (cls is! ClassElement) {
- // TODO(johnniwinther): Support [cls] as a [ClassEntity].
- cls = null;
- }
StringBuffer sb = new StringBuffer();
if (cls != null) {
sb.write("Classes in the closed world related to $cls:\n");
@@ -1294,178 +1266,6 @@
}
}
-class ClosedWorldImpl extends ClosedWorldBase with ClosedWorldRtiNeedMixin {
- final List<MemberEntity> liveInstanceMembers;
-
- ClosedWorldImpl(
- {CompilerOptions options,
- ElementEnvironment elementEnvironment,
- DartTypes dartTypes,
- CommonElements commonElements,
- ConstantSystem constantSystem,
- NativeData nativeData,
- InterceptorData interceptorData,
- BackendUsage backendUsage,
- NoSuchMethodData noSuchMethodData,
- ResolutionWorldBuilder resolutionWorldBuilder,
- RuntimeTypesNeedBuilder rtiNeedBuilder,
- Set<ClassEntity> implementedClasses,
- Iterable<ClassEntity> liveNativeClasses,
- Iterable<MemberEntity> liveInstanceMembers,
- Iterable<MemberEntity> assignedInstanceMembers,
- Iterable<MemberEntity> processedMembers,
- Set<TypedefEntity> allTypedefs,
- Map<ClassEntity, Set<ClassEntity>> mixinUses,
- Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
- Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
- Map<ClassEntity, ClassSet> classSets})
- : this.liveInstanceMembers =
- new List<MemberEntity>.from(liveInstanceMembers),
- super(
- elementEnvironment,
- dartTypes,
- commonElements,
- constantSystem,
- nativeData,
- interceptorData,
- backendUsage,
- noSuchMethodData,
- implementedClasses,
- liveNativeClasses,
- liveInstanceMembers,
- assignedInstanceMembers,
- processedMembers,
- allTypedefs,
- mixinUses,
- typesImplementedBySubclasses,
- classHierarchyNodes,
- classSets) {
- computeRtiNeed(resolutionWorldBuilder, rtiNeedBuilder, options);
- }
-
- bool checkClass(ClassElement cls) => cls.isDeclaration;
-
- bool checkEntity(Element element) => element.isDeclaration;
-
- bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
- assert(cls.isDeclaration, failedAt(cls, '$cls must be the declaration.'));
- assert(cls.isResolved, failedAt(cls, '$cls must be resolved.'));
-
- // TODO(johnniwinther): Reinsert this or similar invariant. Currently
- // various call sites use uninstantiated classes for isSubtypeOf or
- // isSubclassOf. Some are valid, some are not. Work out better invariants
- // to catch the latter.
- // if (mustBeInstantiated) {
- // assert(isInstantiated(cls), failedAt(cls, '$cls is not instantiated.'));
- // }
- return true;
- }
-
- OrderedTypeSet getOrderedTypeSet(ClassElement cls) =>
- cls.allSupertypesAndSelf;
-
- int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
-
- ClassEntity getSuperClass(ClassElement cls) => cls.superclass;
-
- Iterable<ClassEntity> getInterfaces(ClassElement cls) sync* {
- for (Link link = cls.interfaces; !link.isEmpty; link = link.tail) {
- yield link.head.element;
- }
- }
-
- bool isNamedMixinApplication(ClassElement cls) => cls.isNamedMixinApplication;
-
- ClassEntity getAppliedMixin(ClassElement cls) {
- if (cls.isMixinApplication) {
- MixinApplicationElement application = cls;
- return application.mixin;
- }
- return null;
- }
-
- @override
- bool hasElementIn(ClassEntity cls, Selector selector, Element element) {
- // Use [:implementation:] of [element]
- // because our function set only stores declarations.
- Element result = findMatchIn(cls, selector);
- return result == null
- ? false
- : result.implementation == element.implementation;
- }
-
- MemberElement findMatchIn(ClassElement cls, Selector selector,
- {ClassElement stopAtSuperclass}) {
- // Use the [:implementation] of [cls] in case the found [element]
- // is in the patch class.
- return cls.implementation
- .lookupByName(selector.memberName, stopAt: stopAtSuperclass);
- }
-
- /// Returns whether a [selector] call on an instance of [cls]
- /// will hit a method at runtime, and not go through [noSuchMethod].
- bool hasConcreteMatch(ClassElement cls, Selector selector,
- {ClassElement stopAtSuperclass}) {
- assert(
- isInstantiated(cls), failedAt(cls, '$cls has not been instantiated.'));
- MemberElement element = findMatchIn(cls, selector);
- if (element == null) return false;
-
- if (element.isAbstract) {
- ClassElement enclosingClass = element.enclosingClass;
- return hasConcreteMatch(enclosingClass.superclass, selector);
- }
- return selector.appliesUntyped(element);
- }
-
- void registerClosureClass(covariant ClosureClassElement cls) {
- ClassHierarchyNode parentNode = getClassHierarchyNode(cls.superclass);
- ClassHierarchyNode node = _classHierarchyNodes[cls] =
- new ClassHierarchyNode(parentNode, cls, cls.hierarchyDepth);
- for (ResolutionInterfaceType type in cls.allSupertypes) {
- ClassSet subtypeSet = getClassSet(type.element);
- subtypeSet.addSubtype(node);
- }
- _classSets[cls] = new ClassSet(node);
- _updateSuperClassHierarchyNodeForClass(node);
- node.isDirectlyInstantiated = true;
- MethodElement callMethod = cls.callMethod;
- assert(callMethod != null, failedAt(cls, "No call method in $cls"));
- assert(_allFunctions == null,
- failedAt(cls, "Function set has already be created."));
- // TODO(johnniwinther): Include the call method when we can also represent
- // the synthesized call methods for static and instance method
- // closurizations.
- //liveInstanceMembers.add(callMethod);
- }
-
- void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) {
- // Ensure that classes implicitly implementing `Function` are in its
- // subtype set.
- ClassElement cls = node.cls;
- if (cls != commonElements.functionClass &&
- cls.implementsFunction(commonElements)) {
- ClassSet subtypeSet = getClassSet(commonElements.functionClass);
- subtypeSet.addSubtype(node);
- }
- if (!node.isInstantiated && node.parentNode != null) {
- _updateSuperClassHierarchyNodeForClass(node.parentNode);
- }
- }
-
- SideEffects getSideEffectsOfElement(covariant MethodElement element) {
- // The type inferrer (where the side effects are being computed),
- // does not see generative constructor bodies because they are
- // created by the backend. Also, it does not make any distinction
- // between a constructor and its body for side effects. This
- // implies that currently, the side effects of a constructor body
- // contain the side effects of the initializers.
- assert(!element.isGenerativeConstructorBody);
- assert(!element.isField);
- return super.getSideEffectsOfElement(element);
- }
-}
-
abstract class ClosedWorldRtiNeedMixin implements ClosedWorld {
RuntimeTypesNeed _rtiNeed;
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index c2acf4f..c53371c 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -16,7 +16,8 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/generated/constant.dart' show DartObjectImpl;
+import 'package:analyzer/src/generated/constant.dart'
+ show DartObject, DartObjectImpl;
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/generated/resolver.dart'
show TypeProvider, NamespaceBuilder;
@@ -76,7 +77,7 @@
ClosureAnnotator,
JSTypeRefCodegen,
NullableTypeInference,
- SharedCompiler
+ SharedCompiler<LibraryElement>
implements AstVisitor<JS.Node> {
final AnalysisContext context;
final SummaryDataStore summaryData;
@@ -99,9 +100,6 @@
/// in the SDK to be generated before anything else.
final _internalSdkFunctions = <JS.ModuleItem>[];
- /// The list of output module items, in the order they need to be emitted in.
- final _moduleItems = <JS.ModuleItem>[];
-
/// Table of named and possibly hoisted types.
TypeTable _typeTable;
@@ -120,9 +118,6 @@
/// In an async* function, this represents the stream controller parameter.
JS.TemporaryId _asyncStarController;
- // TODO(jmesserly): fuse this with notNull check.
- final _privateNames =
- new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>();
final _initializingFormalTemps =
new HashMap<ParameterElement, JS.TemporaryId>();
@@ -319,7 +314,7 @@
}
JS.Program _emitModule(List<CompilationUnit> compilationUnits, String name) {
- if (_moduleItems.isNotEmpty) {
+ if (moduleItems.isNotEmpty) {
throw new StateError('Can only call emitModule once.');
}
@@ -423,7 +418,7 @@
items.addAll(_internalSdkFunctions);
// Add the module's code (produced by visiting compilation units, above)
- _copyAndFlattenBlocks(items, _moduleItems);
+ _copyAndFlattenBlocks(items, moduleItems);
// Build the module.
return new JS.Program(items, name: _buildUnit.name);
@@ -441,7 +436,7 @@
// Track the module name for each library in the module.
// This data is only required for debugging.
- _moduleItems.add(js
+ moduleItems.add(js
.statement('#.trackLibraries(#, #, ${JSModuleFile.sourceMapHoleID});', [
runtimeModule,
js.string(name),
@@ -603,7 +598,7 @@
// only run this on the outermost function, and not any closures.
inferNullableTypes(node);
- _moduleItems.add(node.accept(this) as JS.ModuleItem);
+ moduleItems.add(node.accept(this) as JS.ModuleItem);
_currentElement = savedElement;
}
@@ -666,7 +661,7 @@
if (isInternalSdk && element is FunctionElement) {
_internalSdkFunctions.add(item);
} else {
- _moduleItems.add(item);
+ moduleItems.add(item);
}
}
@@ -727,7 +722,7 @@
if (currentNames.containsKey(export.name)) return null;
var name = _emitTopLevelName(export);
- _moduleItems.add(js.statement(
+ moduleItems.add(js.statement(
'#.# = #;', [emitLibraryName(currentLibrary), name.selector, name]));
}
}
@@ -917,14 +912,17 @@
var jsTypeDef = _emitJSType(classElem);
if (jsTypeDef != null) return jsTypeDef;
- JS.Expression className;
- if (classElem.typeParameters.isNotEmpty) {
- // Generic classes will be defined inside a function that closes over the
- // type parameter. So we can use their local variable name directly.
- className = new JS.Identifier(classElem.name);
- } else {
- className = _emitTopLevelName(classElem);
- }
+ // Generic classes will be defined inside a function that closes over the
+ // type parameter. So we can use their local variable name directly.
+ //
+ // TODO(jmesserly): the special case for JSArray is to support its special
+ // type-tagging factory constructors. Those will go away once we fix:
+ // https://github.com/dart-lang/sdk/issues/31003
+ var className = classElem.typeParameters.isNotEmpty
+ ? (classElem == _jsArray
+ ? new JS.Identifier(classElem.name)
+ : new JS.TemporaryId(classElem.name))
+ : _emitTopLevelName(classElem);
var savedClassProperties = _classProperties;
_classProperties = new ClassPropertyModel.build(
@@ -1183,7 +1181,7 @@
// TODO(jmesserly): we could export these symbols, if we want to mark
// implemented interfaces for user-defined classes.
var id = new JS.TemporaryId("_is_${classElem.name}_default");
- _moduleItems.add(
+ moduleItems.add(
js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
isClassSymbol = id;
}
@@ -1274,20 +1272,21 @@
JS.Expression className,
JS.Expression heritage,
List<JS.Method> methods) {
- String name = classElem.name;
var typeParams = _emitTypeFormals(classElem.typeParameters);
var jsFields = options.closure
? classElem.fields.map(_emitTypeScriptField).toList()
: null;
- var classExpr = new JS.ClassExpression(
- new JS.Identifier(name), heritage, methods,
- typeParams: typeParams, fields: jsFields);
if (classElem.typeParameters.isNotEmpty) {
- return classExpr.toStatement();
- } else {
- return js.statement('# = #;', [className, classExpr]);
+ return new JS.ClassExpression(
+ className as JS.Identifier, heritage, methods,
+ typeParams: typeParams, fields: jsFields)
+ .toStatement();
}
+ var classExpr = new JS.ClassExpression(
+ new JS.TemporaryId(classElem.name), heritage, methods,
+ typeParams: typeParams, fields: jsFields);
+ return js.statement('# = #;', [className, classExpr]);
}
void _defineClass(
@@ -1719,9 +1718,9 @@
///
/// It will generate an `eatFood` that looks like:
///
- /// eatFood(...args) {
+ /// eatFood(food) {
/// return core.bool.as(this.noSuchMethod(
- /// new dart.InvocationImpl.new('eatFood', args)));
+ /// new dart.InvocationImpl.new('eatFood', [food])));
/// }
JS.Method _implementMockMember(ExecutableElement method, InterfaceType type) {
var invocationProps = <JS.Property>[];
@@ -1731,52 +1730,40 @@
var typeParams = _emitTypeFormals(method.type.typeFormals);
var fnArgs = new List<JS.Parameter>.from(typeParams);
- JS.Expression positionalArgs;
+ var args = _emitParametersForElement(method);
+ fnArgs.addAll(args);
+ var argInit = _emitArgumentInitializers(method);
if (method is PropertyAccessorElement) {
if (method.isGetter) {
addProperty('isGetter', js.boolean(true));
- positionalArgs = new JS.ArrayInitializer([]);
} else {
assert(method.isSetter);
addProperty('isSetter', js.boolean(true));
- var valueArg = new JS.TemporaryId('value');
- positionalArgs = new JS.ArrayInitializer([valueArg]);
- fnArgs.add(valueArg);
}
} else {
addProperty('isMethod', js.boolean(true));
- if (method.type.namedParameterTypes.isNotEmpty) {
- // Named parameters need to be emitted in the correct position (after
- // positional arguments) so we can detect them reliably.
- var args = _emitParametersForElement(method);
- fnArgs.addAll(args);
- addProperty('namedArguments', args.removeLast());
- positionalArgs = new JS.ArrayInitializer(args);
- } else {
- // In case we have optional parameters, we need to use rest args,
- // because sometimes mocks want to detect whether optional arguments
- // were passed, and this does not work reliably with undefined (should
- // not normally appear in DDC, but it can result from JS interop).
- //
- // TODO(jmesserly): perhaps we need to use rest args or destructuring
- // to get reliable optional argument passing in other scenarios? It
- // doesn't seem to occur outside of tests, perhaps due to the
- // combination of mockito and protobufs.
- positionalArgs = new JS.TemporaryId('args');
- fnArgs.add(new JS.RestParameter(positionalArgs));
- }
}
+ var positionalArgs = args;
+ var namedParameterTypes = method.type.namedParameterTypes;
+ if (namedParameterTypes.isNotEmpty) {
+ // Sort the names to match dart2js order.
+ var sortedNames = (namedParameterTypes.keys.toList())..sort();
+ var named = sortedNames
+ .map((n) => new JS.Property(_propertyName(n), new JS.Identifier(n)));
+ addProperty('namedArguments', new JS.ObjectInitializer(named.toList()));
+ positionalArgs.removeLast();
+ }
if (typeParams.isNotEmpty) {
addProperty('typeArguments', new JS.ArrayInitializer(typeParams));
}
var fnBody =
- js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
+ js.call('this.noSuchMethod(new #.InvocationImpl.new(#, [#], #))', [
runtimeModule,
_declareMemberName(method),
- positionalArgs,
+ args,
new JS.ObjectInitializer(invocationProps)
]);
@@ -1784,13 +1771,14 @@
fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]);
}
- var fn =
- new JS.Fun(fnArgs, fnBody.toReturn().toBlock(), typeParams: typeParams);
+ var fnBlock = argInit != null
+ ? new JS.Block([argInit, fnBody.toReturn()])
+ : fnBody.toReturn().toBlock();
return new JS.Method(
_declareMemberName(method,
useExtension: _extensionTypes.isNativeClass(type.element)),
- fn,
+ new JS.Fun(fnArgs, fnBlock, typeParams: typeParams),
isGetter: method is PropertyAccessorElement && method.isGetter,
isSetter: method is PropertyAccessorElement && method.isSetter,
isStatic: false);
@@ -1911,9 +1899,8 @@
return _emitInstanceCreationExpression(
element,
element.returnType as InterfaceType,
- node.constructorName,
- node.arguments,
- true);
+ () => _emitArgumentList(node.arguments),
+ isConst: true);
} else {
return _visitExpression(node.name);
}
@@ -2518,25 +2505,44 @@
/// Emits argument initializers, which handles optional/named args, as well
/// as generic type checks needed due to our covariance.
- JS.Statement _emitArgumentInitializers(
- ExecutableElement element, FormalParameterList parameters) {
- if (parameters == null) return null;
-
+ JS.Statement _emitArgumentInitializers(ExecutableElement element,
+ [FormalParameterList parameterNodes]) {
var body = <JS.Statement>[];
_emitCovarianceBoundsCheck(
element.typeParameters, _classProperties?.covariantParameters, body);
- for (var param in parameters.parameters) {
- var element = param.identifier.staticElement as ParameterElement;
- var jsParam = _emitParameter(element)
- ..sourceInformation = _nodeStart(param.identifier);
+ for (int i = 0, n = element.parameters.length; i < n; i++) {
+ var param = element.parameters[i];
+ var paramNode =
+ parameterNodes != null ? parameterNodes.parameters[i] : null;
+ var jsParam = _emitParameter(param);
+ if (parameterNodes != null) {
+ jsParam.sourceInformation = _nodeStart(paramNode.identifier);
+ }
if (param.isOptional) {
+ JS.Expression defaultValue;
+ if (paramNode != null) {
+ var paramDefault = (paramNode as DefaultFormalParameter).defaultValue;
+ if (paramDefault == null) {
+ defaultValue = new JS.LiteralNull();
+ } else if (_isJSUndefined(paramDefault)) {
+ defaultValue = null;
+ } else {
+ defaultValue = _visitExpression(paramDefault);
+ }
+ } else {
+ // TODO(jmesserly): it would be cleaner to emit the initializer
+ // Expression AST, but it does not seem to be fully resolved
+ // (for example, a list literal will not have the list type).
+ //
+ // So instead we use constant evaluation and emit the constant.
+ defaultValue = _emitDartObject(param.computeConstantValue());
+ }
if (param.isNamed) {
// Parameters will be passed using their real names, not the (possibly
// renamed) local variable.
- var paramName = js.string(param.identifier.name, "'");
- var defaultValue = _defaultParamValue(param);
+ var paramName = js.string(param.name, "'");
if (defaultValue != null) {
// TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming.
body.add(js.statement('let # = # && # in # ? #.# : #;', [
@@ -2558,7 +2564,6 @@
}
} else {
assert(param.isOptionalPositional);
- var defaultValue = _defaultParamValue(param);
if (defaultValue != null) {
body.add(js.statement(
'if (# === void 0) # = #;', [jsParam, jsParam, defaultValue]));
@@ -2566,12 +2571,11 @@
}
}
- var paramElement = resolutionMap.elementDeclaredByFormalParameter(param);
- if (_isCovariant(paramElement)) {
- var castType = _emitType(paramElement.type);
+ if (_isCovariant(param)) {
+ var castType = _emitType(param.type);
body.add(js.statement('#._check(#);', [castType, jsParam]));
}
- if (_annotatedNullCheck(paramElement)) {
+ if (_annotatedNullCheck(param)) {
body.add(_nullParameterCheck(jsParam));
}
}
@@ -2583,17 +2587,6 @@
(_classProperties?.covariantParameters?.contains(p) ?? false);
}
- JS.Expression _defaultParamValue(FormalParameter param) {
- if (param is DefaultFormalParameter && param.defaultValue != null) {
- var defaultValue = param.defaultValue;
- return _isJSUndefined(defaultValue)
- ? null
- : _visitExpression(defaultValue);
- } else {
- return new JS.LiteralNull();
- }
- }
-
bool _isJSUndefined(Expression expr) {
expr = expr is AsExpression ? expr.expression : expr;
if (expr is Identifier) {
@@ -3049,10 +3042,8 @@
// Directly emit constants.
if (element is VariableElement && element.isStatic && element.isConst) {
var val = element.computeConstantValue() as DartObjectImpl;
- var result = _emitDartObject(val);
- if (result != null) {
- return result;
- }
+ var result = val.isBoolNumStringOrNull ? _emitDartObject(val) : null;
+ if (result != null) return result;
}
// type literal
@@ -3071,65 +3062,71 @@
// library member
if (element.enclosingElement is CompilationUnitElement) {
- var result = _emitTopLevelName(accessor);
- if (element is FunctionElement &&
- _reifyTearoff(element, prefix ?? node)) {
- return _emitFunctionTagged(result, element.type);
- }
- return result;
+ return _emitLibraryMemberElement(accessor, prefix ?? node);
}
- var name = element.name;
-
// Unqualified class member. This could mean implicit-this, or implicit
// call to a static from the same class.
if (element is ClassMemberElement && element is! ConstructorElement) {
- bool isStatic = element.isStatic;
- var classElem = element.enclosingElement;
- var type = classElem.type;
- var member = _emitMemberName(name,
- isStatic: isStatic, type: type, element: accessor);
-
- // A static native element should just forward directly to the
- // JS type's member.
- //
- // TODO(jmesserly): this code path seems broken. It doesn't exist
- // elsewhere, such as [_emitAccess], so it will only take affect for
- // unqualified static access inside of the the same class.
- //
- // If we want this feature to work, we'll need to implement it in the
- // standard [_emitStaticClassName] code path, which will need to know the
- // member we're calling so it can determine whether to use the Dart class
- // name or the native JS class name.
- if (isStatic && _isExternal(element)) {
- var nativeName = _extensionTypes.getNativePeers(classElem);
- if (nativeName.isNotEmpty) {
- var memberName = getAnnotationName(element, isJSName) ?? member;
- return runtimeCall('global.#.#', [nativeName[0], memberName]);
- }
- }
-
- // For instance members, we add implicit-this.
- // For method tear-offs, we ensure it's a bound method.
- var target = isStatic ? _emitStaticClassName(classElem) : new JS.This();
- if (element is MethodElement && _reifyTearoff(element, prefix ?? node)) {
- if (isStatic) {
- // TODO(jmesserly): we could tag static/top-level function types once
- // in the module initialization, rather than at the point where they
- // escape.
- return _emitFunctionTagged(
- new JS.PropertyAccess(target, member), element.type);
- }
- return runtimeCall('bind(#, #)', [target, member]);
- }
- return new JS.PropertyAccess(target, member);
+ return _emitClassMemberElement(element, accessor, prefix ?? node);
}
if (element is ParameterElement) {
return _emitParameter(element);
}
- return new JS.Identifier(name);
+ return new JS.Identifier(element.name);
+ }
+
+ JS.Expression _emitLibraryMemberElement(Element element, Expression node) {
+ var result = _emitTopLevelName(element);
+ if (element is FunctionElement && _reifyTearoff(element, node)) {
+ return _emitFunctionTagged(result, element.type);
+ }
+ return result;
+ }
+
+ JS.Expression _emitClassMemberElement(
+ ClassMemberElement element, Element accessor, Expression node) {
+ bool isStatic = element.isStatic;
+ var classElem = element.enclosingElement;
+ var type = classElem.type;
+ var member = _emitMemberName(element.name,
+ isStatic: isStatic, type: type, element: accessor);
+
+ // A static native element should just forward directly to the
+ // JS type's member.
+ //
+ // TODO(jmesserly): this code path seems broken. It doesn't exist
+ // elsewhere, such as [_emitAccess], so it will only take affect for
+ // unqualified static access inside of the the same class.
+ //
+ // If we want this feature to work, we'll need to implement it in the
+ // standard [_emitStaticClassName] code path, which will need to know the
+ // member we're calling so it can determine whether to use the Dart class
+ // name or the native JS class name.
+ if (isStatic && _isExternal(element)) {
+ var nativeName = _extensionTypes.getNativePeers(classElem);
+ if (nativeName.isNotEmpty) {
+ var memberName = getAnnotationName(element, isJSName) ?? member;
+ return runtimeCall('global.#.#', [nativeName[0], memberName]);
+ }
+ }
+
+ // For instance members, we add implicit-this.
+ // For method tear-offs, we ensure it's a bound method.
+ var target = isStatic ? _emitStaticClassName(classElem) : new JS.This();
+ if (element is MethodElement && _reifyTearoff(element, node)) {
+ if (isStatic) {
+ // TODO(jmesserly): we could tag static/top-level function types once
+ // in the module initialization, rather than at the point where they
+ // escape.
+ return _emitFunctionTagged(
+ new JS.PropertyAccess(target, member), element.type);
+ }
+ return runtimeCall('bind(#, #)', [target, member]);
+ }
+ return new JS.PropertyAccess(target, member);
}
JS.Identifier _emitVariableDef(SimpleIdentifier id, {JS.TypeRef type}) {
@@ -4053,33 +4050,10 @@
source = (code as StringLiteral).stringValue;
}
- // TODO(vsm): Constructors in dart:html and friends are trying to
- // allocate a type defined on window/self, but this often conflicts a
- // with the generated extension class in scope. We really should
- // qualify explicitly in dart:html itself.
- var constructorPattern = new RegExp("new [A-Z][A-Za-z]+\\(");
- if (constructorPattern.matchAsPrefix(source) != null) {
- var containingClass = node.parent;
- while (containingClass != null && containingClass is! ClassDeclaration) {
- containingClass = containingClass.parent;
- }
- if (containingClass is ClassDeclaration &&
- _extensionTypes.isNativeClass(containingClass.element)) {
- var constructorName = source.substring(4, source.indexOf('('));
- var className = containingClass.name.name;
- if (className == constructorName) {
- source =
- source.replaceFirst('new $className(', 'new self.$className(');
- }
- }
- }
-
- // TODO(rnystrom): The JS() calls are almost never nested, and probably
- // really shouldn't be, but there are at least a couple of calls in the
- // HTML library where an argument to JS() is itself a JS() call. If those
- // go away, this can just assert(!_isInForeignJS).
- // Inside JS(), type names evaluate to the raw runtime type, not the
- // wrapped Type object.
+ // TODO(jmesserly): arguments to JS() that contain type literals evaluate to
+ // the raw runtime type instead of the wrapped Type object.
+ // We can clean this up by switching to `unwrapType(<type literal>)`, which
+ // the compiler will then optimize.
var wasInForeignJS = _isInForeignJS;
_isInForeignJS = true;
var jsArgs = templateArgs.map(_visitExpression).toList();
@@ -4130,7 +4104,7 @@
if (p.isPositional) {
jsParams.add(new JS.Identifier(p.name));
} else {
- jsParams.add(new JS.TemporaryId('namedArgs'));
+ jsParams.add(namedArgumentTemp);
break;
}
}
@@ -4304,7 +4278,7 @@
/// Emits a list of top-level field.
void _emitTopLevelFields(List<VariableDeclaration> fields) {
- _moduleItems.add(_emitLazyFields(
+ moduleItems.add(_emitLazyFields(
emitLibraryName(currentLibrary), fields, _emitTopLevelMemberName));
}
@@ -4324,7 +4298,7 @@
_isJSInvocation(init) ||
init is InstanceCreationExpression &&
isSdkInternalRuntime(init.staticElement.library)) {
- _moduleItems.add(closureAnnotate(
+ moduleItems.add(closureAnnotate(
js.statement('# = #;', [
_emitTopLevelName(field.element),
_visitInitializer(field.initializer, field.element)
@@ -4391,46 +4365,43 @@
return null;
}
- JS.Expression _emitConstructorName(
- ConstructorElement element, DartType type) {
+ JS.Expression _emitConstructorName(DartType type, String name) {
return _emitJSInterop(type.element) ??
new JS.PropertyAccess(
- _emitConstructorAccess(type), _constructorName(element.name));
+ _emitConstructorAccess(type), _constructorName(name));
}
@override
JS.Expression visitConstructorName(ConstructorName node) {
- return _emitConstructorName(node.staticElement, node.type.type);
+ return _emitConstructorName(node.type.type, node.staticElement.name);
}
- JS.Expression _emitInstanceCreationExpression(
- ConstructorElement element,
- InterfaceType type,
- SimpleIdentifier name,
- ArgumentList argumentList,
- bool isConst,
- [ConstructorName ctorNode]) {
+ JS.Expression _emitInstanceCreationExpression(ConstructorElement element,
+ InterfaceType type, List<JS.Expression> Function() emitArguments,
+ {bool isConst = false, ConstructorName ctorNode}) {
if (element == null) {
return _throwUnsafe('unresolved constructor: ${type?.name ?? '<null>'}'
- '.${name?.name ?? '<unnamed>'}');
+ '.${ctorNode?.name?.name ?? '<unnamed>'}');
}
- var classElem = element.enclosingElement;
+ var classElem = type.element;
if (_isObjectLiteral(classElem)) {
- return _emitObjectLiteral(argumentList);
+ var args = emitArguments();
+ return args.isEmpty ? js.call('{}') : args.single as JS.ObjectInitializer;
}
+ var name = element.name;
JS.Expression emitNew() {
- var args = _emitArgumentList(argumentList);
- if (argumentList.arguments.isEmpty && element.source.isInSystemLibrary) {
+ var args = emitArguments();
+ if (args.isEmpty && classElem.source.isInSystemLibrary) {
// Skip the slow SDK factory constructors when possible.
switch (classElem.name) {
case 'Map':
case 'HashMap':
case 'LinkedHashMap':
- if (element.name == '') {
+ if (name == '') {
return js.call('new #.new()', _emitMapImplType(type));
- } else if (element.name == 'identity') {
+ } else if (name == 'identity') {
return js.call(
'new #.new()', _emitMapImplType(type, identity: true));
}
@@ -4438,22 +4409,22 @@
case 'Set':
case 'HashSet':
case 'LinkedHashSet':
- if (element.name == '') {
+ if (name == '') {
return js.call('new #.new()', _emitSetImplType(type));
- } else if (element.name == 'identity') {
+ } else if (name == 'identity') {
return js.call(
'new #.new()', _emitSetImplType(type, identity: true));
}
break;
case 'List':
- if (element.name == '' && type is InterfaceType) {
+ if (name == '' && type is InterfaceType) {
return _emitList(type.typeArguments[0], []);
}
break;
}
}
// Native factory constructors are JS constructors - use new here.
- var ctor = _emitConstructorName(element, type);
+ var ctor = _emitConstructorName(type, name);
if (ctorNode != null) ctor.sourceInformation = _nodeSpan(ctorNode);
return element.isFactory && !_hasJSInteropAnnotation(classElem)
? new JS.Call(ctor, args)
@@ -4482,57 +4453,99 @@
bool _hasJSInteropAnnotation(Element e) =>
findAnnotation(e, isPublicJSAnnotation) != null;
- JS.Expression _emitObjectLiteral(ArgumentList argumentList) {
- var args = _emitArgumentList(argumentList);
- if (args.isEmpty) {
- return js.call('{}');
- }
- assert(args.single is JS.ObjectInitializer);
- return args.single;
- }
-
/// If the constant [value] is primitive, directly emit the
/// corresponding JavaScript. Otherwise, return null.
- JS.Expression _emitDartObject(DartObjectImpl value,
- {bool handleUnknown: false}) {
+ JS.Expression _emitDartObject(DartObject value, {bool handleUnknown: false}) {
if (value == null || value.isNull) {
return new JS.LiteralNull();
}
+ var type = value.type;
// Handle unknown value: when the declared variable wasn't found, and no
// explicit default value was passed either.
// TODO(jmesserly): ideally Analyzer would simply resolve this to the
// default value that is specified in the SDK. Instead we implement that
// here. `bool.fromEnvironment` defaults to `false`, the others to `null`:
// https://api.dartlang.org/stable/1.20.1/dart-core/bool/bool.fromEnvironment.html
- if (value.isUnknown) {
- if (!handleUnknown) {
- return null;
- } else {
- return value.type == types.boolType
- ? js.boolean(false)
- : new JS.LiteralNull();
- }
+ if (!value.hasKnownValue) {
+ if (!handleUnknown) return null;
+ return type == types.boolType ? js.boolean(false) : new JS.LiteralNull();
}
- if (value.type == types.boolType) {
- var boolValue = value.toBoolValue();
- return js.boolean(boolValue);
+ if (type == types.boolType) {
+ return js.boolean(value.toBoolValue());
}
- if (value.type == types.intType) {
- var intValue = value.toIntValue();
- return js.number(intValue);
+ if (type == types.intType) {
+ return js.number(value.toIntValue());
}
- if (value.type == types.stringType) {
+ if (type == types.doubleType) {
+ return js.number(value.toDoubleValue());
+ }
+ if (type == types.stringType) {
var stringValue = value.toStringValue();
return js.escapedString(stringValue);
}
- return null;
+ if (type == types.symbolType) {
+ return _emitDartSymbol(value.toSymbolValue());
+ }
+ if (type == types.typeType) {
+ return _emitType(value.toTypeValue());
+ }
+ if (type is InterfaceType) {
+ if (type.element == types.listType.element) {
+ return _cacheConst(() => _emitConstList(type.typeArguments[0],
+ value.toListValue().map(_emitDartObject).toList()));
+ }
+ if (type.element == types.mapType.element) {
+ return _cacheConst(() {
+ var entries = <JS.Expression>[];
+ value.toMapValue().forEach((key, value) {
+ entries.add(_emitDartObject(key));
+ entries.add(_emitDartObject(value));
+ });
+ return _emitConstMap(type, entries);
+ });
+ }
+ if (value is DartObjectImpl && value.isUserDefinedObject) {
+ var ctor = value.getInvocation();
+ var classElem = type.element;
+ if (classElem.isEnum) {
+ // TODO(jmesserly): we should be able to use `getField('index')` but
+ // in some cases Analyzer uses the name of the static field that
+ // contains the enum, rather than the `index` field, due to a bug.
+ //
+ // So we just grab the one instance field, regardless of its name.
+ var index = value.fields.values.single.toIntValue();
+ var field =
+ classElem.fields.where((f) => f.type == type).elementAt(index);
+ return _emitClassMemberElement(field, field.getter, null);
+ }
+ return _emitInstanceCreationExpression(ctor.constructor, type, () {
+ var args = ctor.positionalArguments.map(_emitDartObject).toList();
+ var named = <JS.Property>[];
+ ctor.namedArguments.forEach((name, value) {
+ named.add(
+ new JS.Property(_propertyName(name), _emitDartObject(value)));
+ });
+ if (named.isNotEmpty) args.add(new JS.ObjectInitializer(named));
+ return args;
+ }, isConst: true);
+ }
+ }
+ if (value is DartObjectImpl && type is FunctionType) {
+ Element element = value.toFunctionValue();
+ if (element.enclosingElement is CompilationUnitElement) {
+ return _emitLibraryMemberElement(element, null);
+ }
+ if (element is ClassMemberElement) {
+ return _emitClassMemberElement(element, element, null);
+ }
+ }
+ return _unreachable(value);
}
@override
visitInstanceCreationExpression(InstanceCreationExpression node) {
var element = resolutionMap.staticElementForConstructorReference(node);
var constructor = node.constructorName;
- var name = constructor.name;
if (node.isConst &&
element?.name == 'fromEnvironment' &&
element.library.isDartCore) {
@@ -4561,10 +4574,9 @@
return _emitInstanceCreationExpression(
element,
getType(constructor.type) as InterfaceType,
- name,
- node.argumentList,
- node.isConst,
- constructor);
+ () => _emitArgumentList(node.argumentList),
+ isConst: node.isConst,
+ ctorNode: constructor);
}
bool isPrimitiveType(DartType t) => _typeRep.isPrimitive(t);
@@ -4968,7 +4980,7 @@
if (_currentFunction == null || usesTypeParams) return jsExpr;
var temp = new JS.TemporaryId('const');
- _moduleItems.add(js.statement('let #;', [temp]));
+ moduleItems.add(js.statement('let #;', [temp]));
return js.call('# || (# = #)', [temp, temp, jsExpr]);
}
@@ -5504,9 +5516,7 @@
var createStreamIter = _emitInstanceCreationExpression(
streamIterator.element.unnamedConstructor,
streamIterator,
- null,
- ast.argumentList([node.iterable]),
- false);
+ () => [_visitExpression(node.iterable)]);
var iter = new JS.TemporaryId('iter');
var variable = node.identifier ?? node.loopVariable.identifier;
var init = _visitExpression(node.identifier);
@@ -5702,24 +5712,24 @@
@override
visitSymbolLiteral(SymbolLiteral node) {
- JS.Expression emitSymbol() {
- // TODO(vsm): Handle qualified symbols correctly.
- var last = node.components.last.toString();
- var name = js.string(node.components.join('.'), "'");
- if (last.startsWith('_')) {
- var nativeSymbol = _emitPrivateNameSymbol(currentLibrary, last);
- return js.call('new #.new(#, #)', [
- _emitConstructorAccess(privateSymbolClass.type),
- name,
- nativeSymbol
- ]);
- } else {
- return js
- .call('#.new(#)', [_emitConstructorAccess(types.symbolType), name]);
- }
- }
+ return _emitConst(() => _emitDartSymbol(node.components.join('.')));
+ }
- return _emitConst(emitSymbol);
+ JS.Expression _emitDartSymbol(String name) {
+ // TODO(vsm): Handle qualified symbols correctly.
+ var last = name.substring(name.lastIndexOf('.') + 1);
+ var jsName = js.string(name, "'");
+ if (last.startsWith('_')) {
+ var nativeSymbol = emitPrivateNameSymbol(currentLibrary, last);
+ return js.call('new #.new(#, #)', [
+ _emitConstructorAccess(privateSymbolClass.type),
+ jsName,
+ nativeSymbol
+ ]);
+ } else {
+ return js
+ .call('#.new(#)', [_emitConstructorAccess(types.symbolType), jsName]);
+ }
}
@override
@@ -5760,7 +5770,7 @@
entries.add(_visitExpression(e.key));
entries.add(_visitExpression(e.value));
}
- return new JS.ArrayInitializer(entries);
+ return entries;
}
var type = node.staticType as InterfaceType;
@@ -5769,11 +5779,15 @@
if (node.entries.isEmpty) {
return js.call('new #.new()', [mapType]);
}
- return js.call('new #.from(#)', [mapType, emitEntries()]);
+ return js.call('new #.from([#])', [mapType, emitEntries()]);
}
+ return _cacheConst(() => _emitConstMap(type, emitEntries()));
+ }
+
+ JS.Expression _emitConstMap(InterfaceType type, List<JS.Expression> entries) {
var typeArgs = type.typeArguments;
- return _cacheConst(() => runtimeCall('constMap(#, #, #)',
- [_emitType(typeArgs[0]), _emitType(typeArgs[1]), emitEntries()]));
+ return runtimeCall('constMap(#, #, [#])',
+ [_emitType(typeArgs[0]), _emitType(typeArgs[1]), entries]);
}
JS.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
@@ -6063,7 +6077,7 @@
}
if (name.startsWith('_')) {
- return _emitPrivateNameSymbol(currentLibrary, name);
+ return emitPrivateNameSymbol(currentLibrary, name);
}
useExtension ??= _isSymbolizedMember(type, name);
@@ -6185,17 +6199,6 @@
return false;
}
- JS.TemporaryId _emitPrivateNameSymbol(LibraryElement library, String name) {
- return _privateNames
- .putIfAbsent(library, () => new HashMap())
- .putIfAbsent(name, () {
- var id = new JS.TemporaryId(name);
- _moduleItems.add(
- js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
- return id;
- });
- }
-
/// Returns the canonical name to refer to the Dart library.
JS.Identifier emitLibraryName(LibraryElement library) {
// It's either one of the libraries in this module, or it's an import.
@@ -6277,7 +6280,7 @@
JS.Expression _throwUnsafe(String message) => runtimeCall(
'throw(Error(#))', js.escapedString("compile error: $message"));
- JS.Node _unreachable(AstNode node) {
+ JS.Node _unreachable(Object node) {
throw new UnsupportedError(
'tried to generate an unreachable node: `$node`');
}
diff --git a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
index d855eb6..928e5e4 100644
--- a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
@@ -76,6 +76,7 @@
/// inDeclarationContext, this method returns true if [node] is used in an
/// invocation context such as a MethodInvocation.
bool inInvocationContext(Expression node) {
+ if (node == null) return false;
var parent = node.parent;
while (parent is ParenthesizedExpression) {
node = parent;
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index deb7004..22d64ab 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -7,15 +7,17 @@
import 'dart:io' show File;
import 'package:analyzer/analyzer.dart'
- show AnalysisError, CompilationUnit, ErrorSeverity;
+ show AnalysisError, CompilationUnit, ErrorSeverity, ErrorType;
import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/element/element.dart' show LibraryElement;
+import 'package:analyzer/dart/element/element.dart'
+ show LibraryElement, UriReferencedElement;
import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
import 'package:analyzer/file_system/physical_file_system.dart'
show PhysicalResourceProvider;
import 'package:analyzer/src/context/builder.dart' show ContextBuilder;
import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
-import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode;
+import 'package:analyzer/src/error/codes.dart'
+ show StaticTypeWarningCode, StrongModeCode;
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, AnalysisEngine;
import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
@@ -192,6 +194,16 @@
librariesToCompile.addAll(library.importedLibraries);
librariesToCompile.addAll(library.exportedLibraries);
+ // TODO(jmesserly): remove "dart:mirrors" from DDC's SDK, and then remove
+ // this special case error message.
+ if (!compilingSdk && !options.emitMetadata) {
+ var node = _getDartMirrorsImport(library);
+ if (node != null) {
+ errors.add(new AnalysisError(library.source, node.uriOffset,
+ node.uriEnd, invalidImportDartMirrors));
+ }
+ }
+
var tree = context.resolveCompilationUnit(library.source, library);
trees.add(tree);
errors.addAll(context.computeErrors(library.source));
@@ -231,6 +243,15 @@
}
}
+UriReferencedElement _getDartMirrorsImport(LibraryElement library) {
+ return library.imports.firstWhere(_isDartMirrorsImort, orElse: () => null) ??
+ library.exports.firstWhere(_isDartMirrorsImort, orElse: () => null);
+}
+
+bool _isDartMirrorsImort(UriReferencedElement import) {
+ return import.uri == 'dart:mirrors';
+}
+
class CompilerOptions {
/// Whether to emit the source mapping file.
///
@@ -588,3 +609,8 @@
return new Uri.file(path.absolute(source));
}
}
+
+const invalidImportDartMirrors = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPORT_DART_MIRRORS',
+ 'Cannot import "dart:mirrors" in web applications (https://goo.gl/R1anEs).');
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart
index 0310d63..5c212f1 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_names.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -72,8 +72,8 @@
return node.name;
}
- void enterScope(FunctionExpression node) {
- scope = scope.functions[node];
+ void enterScope(Node node) {
+ scope = scope.childScopes[node];
}
void leaveScope() {
@@ -83,8 +83,7 @@
/// Represents a complete function scope in JS.
///
-/// We don't currently track ES6 block scopes, because we don't represent them
-/// in js_ast yet.
+/// We don't currently track ES6 block scopes.
class _FunctionScope {
/// The parent scope.
final _FunctionScope parent;
@@ -97,9 +96,9 @@
/// not collide with inside this scope.
final used = new HashSet<String>();
- /// Nested functions, these are visited after everything else so the names
+ /// Nested scopes, these are visited after everything else so the names
/// they might need are in scope.
- final functions = new Map<FunctionExpression, _FunctionScope>();
+ final childScopes = new Map<Node, _FunctionScope>();
/// New names assigned for temps and identifiers.
final renames = new HashMap<Object, String>();
@@ -118,7 +117,7 @@
_RenameVisitor.build(Node root) {
scope = rootScope;
root.accept(this);
- _finishFunctions();
+ _finishScopes();
_finishNames();
}
@@ -166,14 +165,22 @@
visitFunctionExpression(FunctionExpression node) {
// Visit nested functions after all identifiers are declared.
- scope.functions[node] = new _FunctionScope(scope);
+ scope.childScopes[node] = new _FunctionScope(scope);
}
- void _finishFunctions() {
- scope.functions.forEach((FunctionExpression f, _FunctionScope s) {
+ visitClassExpression(ClassExpression node) {
+ scope.childScopes[node] = new _FunctionScope(scope);
+ }
+
+ void _finishScopes() {
+ scope.childScopes.forEach((node, s) {
scope = s;
- super.visitFunctionExpression(f);
- _finishFunctions();
+ if (node is FunctionExpression) {
+ super.visitFunctionExpression(node);
+ } else {
+ super.visitClassExpression(node);
+ }
+ _finishScopes();
scope = scope.parent;
});
}
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 10e9782..d2fa9c5 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:collection';
import '../compiler/js_metalet.dart' as JS;
import '../compiler/js_names.dart' as JS;
import '../compiler/js_utils.dart' as JS;
@@ -12,7 +13,7 @@
///
/// This class should only implement functionality that depends purely on JS
/// classes, rather than on Analyzer/Kernel types.
-abstract class SharedCompiler {
+abstract class SharedCompiler<Library> {
/// When inside a `[]=` operator, this will be a non-null value that should be
/// returned by any `return;` statement.
///
@@ -22,6 +23,11 @@
JS.Identifier runtimeModule;
final namedArgumentTemp = new JS.TemporaryId('opts');
+ final _privateNames = new HashMap<Library, HashMap<String, JS.TemporaryId>>();
+
+ /// The list of output module items, in the order they need to be emitted in.
+ final moduleItems = <JS.ModuleItem>[];
+
/// When compiling the body of a `operator []=` method, this will be non-null
/// and will indicate the the value that should be returned from any `return;`
/// statements.
@@ -122,4 +128,19 @@
JS.Statement runtimeStatement(String code, [args]) {
return runtimeCall(code, args).toStatement();
}
+
+ JS.TemporaryId emitPrivateNameSymbol(Library library, String name) {
+ return _privateNames
+ .putIfAbsent(library, () => new HashMap())
+ .putIfAbsent(name, () {
+ var idName = name;
+ if (idName.endsWith('=')) {
+ idName = idName.replaceAll('=', '_');
+ }
+ var id = new JS.TemporaryId(idName);
+ moduleItems.add(
+ js.statement('const # = Symbol(#);', [id, js.string(name, "'")]));
+ return id;
+ });
+ }
}
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index ea97d34..58c8bbb 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -1130,6 +1130,7 @@
}
visitClassExpression(ClassExpression node) {
+ localNamer.enterScope(node);
out('class ');
visit(node.name);
outTypeParams(node.typeParams);
@@ -1161,6 +1162,7 @@
} else {
out('{}');
}
+ localNamer.leaveScope();
}
visitMethod(Method node) {
@@ -1545,13 +1547,13 @@
abstract class LocalNamer {
String getName(Identifier node);
- void enterScope(FunctionExpression node);
+ void enterScope(Node node);
void leaveScope();
}
class IdentityNamer implements LocalNamer {
String getName(Identifier node) => node.name;
- void enterScope(FunctionExpression node) {}
+ void enterScope(Node node) {}
void leaveScope() {}
}
@@ -1562,7 +1564,7 @@
int parameterNumber = 0;
int variableNumber = 0;
- void enterScope(FunctionExpression node) {
+ void enterScope(Node node) {
var vars = new VarCollector();
node.accept(vars);
maps.add(new Map<String, String>());
@@ -1688,10 +1690,11 @@
}
_scanVariableBinding(VariableBinding d) {
- if (d is Identifier)
+ if (d is Identifier) {
declare(d);
- else
+ } else {
d.accept(this);
+ }
}
visitRestParameter(RestParameter node) {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 0510037..b2b01e9 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -198,20 +198,25 @@
return new CompilerResult(compilerState, false);
}
+ var component = result.component;
+ var emitMetadata = argResults['emit-metadata'] as bool;
+ if (!emitMetadata && _checkForDartMirrorsImport(component)) {
+ return new CompilerResult(compilerState, false);
+ }
+
String output = argResults['out'];
var file = new File(output);
if (!file.parent.existsSync()) file.parent.createSync(recursive: true);
- // Useful for debugging:
- writeComponentToText(result.component, path: output + '.txt');
-
// TODO(jmesserly): Save .dill file so other modules can link in this one.
//await writeComponentToBinary(component, output);
- var component = result.component;
+
+ // Useful for debugging:
+ writeComponentToText(component, path: output + '.txt');
var compiler = new ProgramCompiler(component,
declaredVariables: declaredVariables,
- emitMetadata: argResults['emit-metadata'] as bool,
+ emitMetadata: emitMetadata,
enableAsserts: argResults['enable-asserts'] as bool);
var jsModule =
compiler.emitModule(component, result.inputSummaries, summaryUris);
@@ -385,3 +390,18 @@
'lib',
'_internal',
'ddc_sdk.dill');
+
+bool _checkForDartMirrorsImport(Component component) {
+ for (var library in component.libraries) {
+ if (library.isExternal) continue;
+ for (var dep in library.dependencies) {
+ var uri = dep.targetLibrary.importUri;
+ if (uri.scheme == 'dart' && uri.path == 'mirrors') {
+ print('${library.importUri}: Error: Cannot import "dart:mirrors" '
+ 'in web applications (https://goo.gl/R1anEs).');
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 819227d..0a66690 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -8,7 +8,8 @@
import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
-import 'package:kernel/kernel.dart' hide ConstantVisitor;
+import 'package:kernel/kernel.dart';
+import 'package:kernel/library_index.dart';
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
import 'package:source_span/source_span.dart' show SourceLocation;
@@ -20,6 +21,7 @@
import '../js_ast/js_ast.dart' as JS;
import '../js_ast/js_ast.dart' show js;
import '../js_ast/source_map_printer.dart' show NodeEnd, NodeSpan, HoverComment;
+import 'constants.dart';
import 'js_interop.dart';
import 'js_typerep.dart';
import 'kernel_helpers.dart';
@@ -29,14 +31,12 @@
import 'type_table.dart';
class ProgramCompiler extends Object
- with SharedCompiler
+ with SharedCompiler<Library>
implements
StatementVisitor<JS.Statement>,
ExpressionVisitor<JS.Expression>,
- DartTypeVisitor<JS.Expression> {
- /// The list of output module items, in the order they need to be emitted in.
- final _moduleItems = <JS.ModuleItem>[];
-
+ DartTypeVisitor<JS.Expression>,
+ ConstantVisitor<JS.Expression> {
/// The set of libraries we are currently compiling, and the temporaries used
/// to refer to them.
///
@@ -60,9 +60,6 @@
/// In an async* function, this represents the stream controller parameter.
JS.TemporaryId _asyncStarController;
- // TODO(jmesserly): fuse this with notNull check.
- final _privateNames = new HashMap<Library, HashMap<String, JS.TemporaryId>>();
-
JS.Identifier _extensionSymbolsModule;
final _extensionSymbols = new Map<String, JS.TemporaryId>();
@@ -134,8 +131,6 @@
final bool enableAsserts;
final bool replCompile;
- final Map<String, String> declaredVariables;
-
// Compilation of Kernel's [BreakStatement].
//
// Kernel represents Dart's `break` and `continue` uniformly as
@@ -199,7 +194,7 @@
/// The dart:async `StreamIterator<T>` type.
final Class _asyncStreamIteratorClass;
- final ConstantVisitor _constants;
+ final DevCompilerConstants _constants;
final NullableInference _nullableInference;
@@ -208,48 +203,36 @@
bool replCompile: false,
bool enableAsserts: true,
Map<String, String> declaredVariables: const {}}) {
- var nativeTypes = new NativeTypeSet(component);
+ var coreTypes = new CoreTypes(component);
var types = new TypeSchemaEnvironment(
- nativeTypes.coreTypes, new ClassHierarchy(component), true);
- return new ProgramCompiler._(
- nativeTypes, new JSTypeRep(types, nativeTypes.sdk),
+ coreTypes, new ClassHierarchy(component), true);
+ var constants = new DevCompilerConstants(types, declaredVariables);
+ var nativeTypes = new NativeTypeSet(coreTypes, constants);
+ var jsTypeRep = new JSTypeRep(types);
+ return new ProgramCompiler._(coreTypes, coreTypes.index, nativeTypes,
+ constants, types, jsTypeRep, new NullableInference(jsTypeRep),
emitMetadata: emitMetadata,
enableAsserts: enableAsserts,
- replCompile: replCompile,
- declaredVariables: declaredVariables);
+ replCompile: replCompile);
}
- ProgramCompiler._(NativeTypeSet nativeTypes, this._typeRep,
- {this.emitMetadata,
- this.enableAsserts,
- this.replCompile,
- this.declaredVariables})
- : _extensionTypes = nativeTypes,
- types = _typeRep.types,
- coreTypes = nativeTypes.coreTypes,
- _constants = new ConstantVisitor(nativeTypes.coreTypes),
- _jsArrayClass =
- nativeTypes.sdk.getClass('dart:_interceptors', 'JSArray'),
- _jsBoolClass = nativeTypes.sdk.getClass('dart:_interceptors', 'JSBool'),
- _jsNumberClass =
- nativeTypes.sdk.getClass('dart:_interceptors', 'JSNumber'),
- _jsStringClass =
- nativeTypes.sdk.getClass('dart:_interceptors', 'JSString'),
+ ProgramCompiler._(this.coreTypes, LibraryIndex sdk, this._extensionTypes,
+ this._constants, this.types, this._typeRep, this._nullableInference,
+ {this.emitMetadata, this.enableAsserts, this.replCompile})
+ : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'),
+ _jsBoolClass = sdk.getClass('dart:_interceptors', 'JSBool'),
+ _jsNumberClass = sdk.getClass('dart:_interceptors', 'JSNumber'),
+ _jsStringClass = sdk.getClass('dart:_interceptors', 'JSString'),
_asyncStreamIteratorClass =
- nativeTypes.sdk.getClass('dart:async', 'StreamIterator'),
- privateSymbolClass =
- nativeTypes.sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
- linkedHashMapImplClass =
- nativeTypes.sdk.getClass('dart:_js_helper', 'LinkedMap'),
+ sdk.getClass('dart:async', 'StreamIterator'),
+ privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
+ linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'),
identityHashMapImplClass =
- nativeTypes.sdk.getClass('dart:_js_helper', 'IdentityMap'),
- linkedHashSetImplClass =
- nativeTypes.sdk.getClass('dart:collection', '_HashSet'),
+ sdk.getClass('dart:_js_helper', 'IdentityMap'),
+ linkedHashSetImplClass = sdk.getClass('dart:collection', '_HashSet'),
identityHashSetImplClass =
- nativeTypes.sdk.getClass('dart:collection', '_IdentityHashSet'),
- syncIterableClass =
- nativeTypes.sdk.getClass('dart:_js_helper', 'SyncIterable'),
- _nullableInference = new NullableInference(_typeRep);
+ sdk.getClass('dart:collection', '_IdentityHashSet'),
+ syncIterableClass = sdk.getClass('dart:_js_helper', 'SyncIterable');
ClassHierarchy get hierarchy => types.hierarchy;
@@ -257,7 +240,7 @@
JS.Program emitModule(
Component buildUnit, List<Component> summaries, List<Uri> summaryUris) {
- if (_moduleItems.isNotEmpty) {
+ if (moduleItems.isNotEmpty) {
throw new StateError('Can only call emitModule once.');
}
_component = buildUnit;
@@ -352,7 +335,7 @@
items.addAll(_typeTable.discharge());
// Add the module's code (produced by visiting compilation units, above)
- _copyAndFlattenBlocks(items, _moduleItems);
+ _copyAndFlattenBlocks(items, moduleItems);
// Build the module.
return new JS.Program(items, name: buildUnit.root.name);
@@ -491,7 +474,7 @@
if (node is Procedure && node.name.name == 'main') {
// Don't allow redefining names from this library.
var name = _emitTopLevelName(export.node);
- _moduleItems.add(js.statement(
+ moduleItems.add(js.statement(
'#.# = #;', [emitLibraryName(library), name.selector, name]));
}
}
@@ -515,7 +498,7 @@
_currentLibrary = c.enclosingLibrary;
_currentUri = c.fileUri;
- _moduleItems.add(_emitClassDeclaration(c));
+ moduleItems.add(_emitClassDeclaration(c));
_currentClass = savedClass;
types.thisType = savedClass?.thisType;
@@ -548,14 +531,17 @@
var jsTypeDef = _emitJSType(c);
if (jsTypeDef != null) return jsTypeDef;
- JS.Expression className;
- if (c.typeParameters.isNotEmpty) {
- // Generic classes will be defined inside a function that closes over the
- // type parameter. So we can use their local variable name directly.
- className = new JS.Identifier(getLocalClassName(c));
- } else {
- className = _emitTopLevelName(c);
- }
+ // Generic classes will be defined inside a function that closes over the
+ // type parameter. So we can use their local variable name directly.
+ //
+ // TODO(jmesserly): the special case for JSArray is to support its special
+ // type-tagging factory constructors. Those will go away once we fix:
+ // https://github.com/dart-lang/sdk/issues/31003
+ var className = c.typeParameters.isNotEmpty
+ ? (c == _jsArrayClass
+ ? new JS.Identifier(c.name)
+ : new JS.TemporaryId(getLocalClassName(c)))
+ : _emitTopLevelName(c);
var savedClassProperties = _classProperties;
_classProperties =
@@ -636,14 +622,14 @@
JS.Statement _emitClassStatement(Class c, JS.Expression className,
JS.Expression heritage, List<JS.Method> methods) {
- var name = getLocalClassName(c);
- var classExpr =
- new JS.ClassExpression(new JS.Identifier(name), heritage, methods);
if (c.typeParameters.isNotEmpty) {
- return classExpr.toStatement();
- } else {
- return js.statement('# = #;', [className, classExpr]);
+ return new JS.ClassExpression(
+ className as JS.Identifier, heritage, methods)
+ .toStatement();
}
+ var classExpr = new JS.ClassExpression(
+ new JS.TemporaryId(getLocalClassName(c)), heritage, methods);
+ return js.statement('# = #;', [className, classExpr]);
}
void _defineClass(Class c, JS.Expression className, List<JS.Method> methods,
@@ -1059,7 +1045,7 @@
// TODO(jmesserly): we could export these symbols, if we want to mark
// implemented interfaces for user-defined classes.
var id = new JS.TemporaryId("_is_${getLocalClassName(c)}_default");
- _moduleItems.add(
+ moduleItems.add(
js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
isClassSymbol = id;
}
@@ -1219,9 +1205,6 @@
}
var classProcedures = c.procedures.where((p) => !p.isAbstract).toList();
- for (var m in _classProperties.mockMembers.values) {
- if (m is Procedure) classProcedures.add(m);
- }
for (var member in classProcedures) {
// Static getters/setters/methods cannot be called with dynamic dispatch,
// nor can they be torn off.
@@ -1276,9 +1259,6 @@
var staticFields = <JS.Property>[];
var classFields = c.fields.toList();
- for (var m in _classProperties.mockMembers.values) {
- if (m is Field) classFields.add(m);
- }
for (var field in classFields) {
// Only instance fields need to be saved for dynamic dispatch.
var isStatic = field.isStatic;
@@ -1644,11 +1624,6 @@
}
_currentUri = savedUri;
- _classProperties.mockMembers.forEach((String name, Member member) {
- jsMethods
- .add(_implementMockMember(member, c, isSetter: name.endsWith('=')));
- });
-
// If the type doesn't have an `iterator`, but claims to implement Iterable,
// we inject the adaptor method here, as it's less code size to put the
// helper on a parent class. This pattern is common in the core libraries
@@ -1674,7 +1649,7 @@
}
JS.Fun fn;
- if (member.isExternal) {
+ if (member.isExternal && !member.isNoSuchMethodForwarder) {
if (member.isStatic) {
// TODO(vsm): Do we need to handle this case?
return null;
@@ -1820,122 +1795,6 @@
return _emitJSInterop(type.classNode) ?? visitInterfaceType(type);
}
- /// Given a class C that implements method M from interface I, but does not
- /// declare M, this will generate an implementation that forwards to
- /// noSuchMethod.
- ///
- /// For example:
- ///
- /// class Cat {
- /// bool eatFood(String food) => true;
- /// }
- /// class MockCat implements Cat {
- /// noSuchMethod(Invocation invocation) => 3;
- /// }
- ///
- /// It will generate an `eatFood` that looks like:
- ///
- /// eatFood(...args) {
- /// return core.bool.as(this.noSuchMethod(
- /// new dart.InvocationImpl.new('eatFood', args)));
- /// }
- ///
- /// Same technique is applied if interface I has fields, and C doesn't declare
- /// neither the fields nor the corresponding getters and setters.
- JS.Method _implementMockMember(Member member, Class c, {bool isSetter}) {
- JS.Method implementMockMember(
- ProcedureKind procedureKind, DartType returnType,
- [List<TypeParameter> typeParameters,
- List<JS.Parameter> positionalParameters,
- List<VariableDeclaration> namedParameters]) {
- assert(procedureKind != ProcedureKind.Factory);
-
- var invocationProps = <JS.Property>[];
- addProperty(String name, JS.Expression value) {
- invocationProps.add(new JS.Property(js.string(name), value));
- }
-
- var typeParams = _emitTypeFormals(typeParameters ?? []);
- var fnArgs = new List<JS.Parameter>.from(typeParams);
- JS.Expression positionalArgs;
- if (procedureKind == ProcedureKind.Getter) {
- addProperty('isGetter', js.boolean(true));
- positionalArgs = new JS.ArrayInitializer([]);
- } else if (procedureKind == ProcedureKind.Setter) {
- addProperty('isSetter', js.boolean(true));
- var valueArg = new JS.TemporaryId('value');
- positionalArgs = new JS.ArrayInitializer([valueArg]);
- fnArgs.add(valueArg);
- } else {
- addProperty('isMethod', js.boolean(true));
- if (namedParameters.isNotEmpty) {
- // Named parameters need to be emitted in the correct position (after
- // positional arguments) so we can detect them reliably.
- addProperty('namedArguments', namedArgumentTemp);
- positionalArgs = new JS.ArrayInitializer(positionalParameters);
- fnArgs.addAll(positionalParameters);
- fnArgs.add(namedArgumentTemp);
- } else {
- // In case we have optional parameters, we need to use rest args,
- // because sometimes mocks want to detect whether optional arguments
- // were passed, and this does not work reliably with undefined (should
- // not normally appear in DDC, but it can result from JS interop).
- //
- // TODO(jmesserly): perhaps we need to use rest args or destructuring
- // to get reliable optional argument passing in other scenarios? It
- // doesn't seem to occur outside of tests, perhaps due to the
- // combination of mockito and protobufs.
- positionalArgs = new JS.TemporaryId('args');
- fnArgs.add(new JS.RestParameter(positionalArgs));
- }
- }
-
- if (typeParams.isNotEmpty) {
- addProperty('typeArguments', new JS.ArrayInitializer(typeParams));
- }
-
- var fnBody =
- js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
- runtimeModule,
- _declareMemberName(member),
- positionalArgs,
- new JS.ObjectInitializer(invocationProps)
- ]);
-
- returnType = _getTypeFromClass(returnType, member.enclosingClass, c);
- fnBody = _emitImplicitCast(fnBody, returnType);
-
- var fn = new JS.Fun(fnArgs, fnBody.toReturn().toBlock(),
- typeParams: typeParams);
-
- return new JS.Method(
- _declareMemberName(member,
- useExtension: _extensionTypes.isNativeClass(c)),
- fn,
- isGetter: procedureKind == ProcedureKind.Getter,
- isSetter: procedureKind == ProcedureKind.Setter,
- isStatic: false);
- }
-
- if (member is Field) {
- if (isSetter) {
- return implementMockMember(ProcedureKind.Setter, new VoidType());
- } else {
- return implementMockMember(ProcedureKind.Getter, member.type);
- }
- } else {
- var procedure = member as Procedure;
- var f = procedure.function;
- assert(procedure.isSetter == isSetter);
- return implementMockMember(
- procedure.kind,
- f.returnType,
- f.typeParameters,
- f.positionalParameters.map(_emitVariableRef).toList(),
- f.namedParameters);
- }
- }
-
/// This is called whenever a derived class needs to introduce a new field,
/// shadowing a field or getter/setter pair on its parent.
///
@@ -1945,34 +1804,27 @@
/// wrong behavior if a new field was declared.
List<JS.Method> _emitVirtualFieldAccessor(Field field) {
var virtualField = _classProperties.virtualFields[field];
- var result = <JS.Method>[];
var name = _declareMemberName(field);
- var mocks = _classProperties.mockMembers;
- if (!mocks.containsKey(field.name.name)) {
- var getter = js.fun('function() { return this[#]; }', [virtualField]);
- result.add(new JS.Method(name, getter, isGetter: true)
- ..sourceInformation = _nodeStart(field));
+ var getter = js.fun('function() { return this[#]; }', [virtualField]);
+ var jsGetter = new JS.Method(name, getter, isGetter: true)
+ ..sourceInformation = _nodeStart(field);
+
+ var args =
+ field.isFinal ? [new JS.Super(), name] : [new JS.This(), virtualField];
+
+ JS.Expression value = new JS.Identifier('value');
+ if (!field.isFinal && field.isGenericCovariantImpl) {
+ value = _emitImplicitCast(value, field.type);
}
+ args.add(value);
- if (!mocks.containsKey(field.name.name + '=')) {
- var args = field.isFinal
- ? [new JS.Super(), name]
- : [new JS.This(), virtualField];
+ var jsSetter = new JS.Method(
+ name, js.fun('function(value) { #[#] = #; }', args),
+ isSetter: true)
+ ..sourceInformation = _nodeStart(field);
- JS.Expression value = new JS.Identifier('value');
- if (!field.isFinal && field.isGenericCovariantImpl) {
- value = _emitImplicitCast(value, field.type);
- }
- args.add(value);
-
- result.add(new JS.Method(
- name, js.fun('function(value) { #[#] = #; }', args),
- isSetter: true)
- ..sourceInformation = _nodeStart(field));
- }
-
- return result;
+ return [jsGetter, jsSetter];
}
/// Provide Dart getters and setters that forward to the underlying native
@@ -2111,7 +1963,7 @@
}
_currentUri = savedUri;
- _moduleItems.add(result);
+ moduleItems.add(result);
}
void _emitTopLevelFields(List<Field> fields) {
@@ -2129,7 +1981,7 @@
init is BasicLiteral ||
init is StaticInvocation && isInlineJS(init.target)) {
_currentUri = field.fileUri;
- _moduleItems.add(js.statement('# = #;', [
+ moduleItems.add(js.statement('# = #;', [
_emitTopLevelName(field),
_visitInitializer(init, field.annotations)
]));
@@ -2143,7 +1995,7 @@
}
if (fields.isEmpty) return;
- _moduleItems.add(_emitLazyFields(
+ moduleItems.add(_emitLazyFields(
emitLibraryName(_currentLibrary), fields, _emitTopLevelMemberName));
}
@@ -2291,7 +2143,7 @@
}
if (name.startsWith('_')) {
- return _emitPrivateNameSymbol(_currentLibrary, name);
+ return emitPrivateNameSymbol(_currentLibrary, name);
}
useExtension ??= _isSymbolizedMember(type, name);
@@ -2372,17 +2224,6 @@
hierarchy.getDispatchTarget(c, new Name(name), setter: true));
}
- JS.TemporaryId _emitPrivateNameSymbol(Library library, String name) {
- return _privateNames
- .putIfAbsent(library, () => new HashMap())
- .putIfAbsent(name, () {
- var id = new JS.TemporaryId(name);
- _moduleItems.add(
- js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
- return id;
- });
- }
-
JS.Expression _emitStaticMemberName(String name, [NamedNode member]) {
if (member != null) {
var jsName = _emitJSInteropStaticMemberName(member);
@@ -2474,7 +2315,7 @@
var procedures = library.procedures
.where((p) => !p.isExternal && !p.isAbstract)
.toList();
- _moduleItems.addAll(procedures
+ moduleItems.addAll(procedures
.where((p) => !p.isAccessor)
.map(_emitLibraryFunction)
.toList());
@@ -2483,7 +2324,7 @@
void _emitLibraryAccessors(Iterable<Procedure> accessors) {
if (accessors.isEmpty) return;
- _moduleItems.add(runtimeStatement('copyProperties(#, { # })', [
+ moduleItems.add(runtimeStatement('copyProperties(#, { # })', [
emitLibraryName(_currentLibrary),
accessors.map(_emitLibraryAccessor).toList()
]));
@@ -3720,10 +3561,9 @@
@override
visitInvalidExpression(InvalidExpression node) => defaultExpression(node);
- // [ConstantExpression] is produced by the Kernel constant evaluator, which
- // we do not use.
@override
- visitConstantExpression(ConstantExpression node) => defaultExpression(node);
+ visitConstantExpression(ConstantExpression node) =>
+ node.constant.accept(this);
@override
visitVariableGet(VariableGet node) {
@@ -3867,6 +3707,11 @@
@override
visitStaticGet(StaticGet node) {
var target = node.target;
+ if (target is Field && target.isConst) {
+ var value = _constants.evaluate(target.initializer, cache: true);
+ if (value is PrimitiveConstant) return value.accept(this);
+ }
+
var result = _emitStaticTarget(target);
if (_reifyTearoff(target)) {
// TODO(jmesserly): we could tag static/top-level function types once
@@ -4069,7 +3914,10 @@
if (expr.value >= low && expr.value <= high) return expr.value;
return null;
}
- // TODO(jmesserly): other constant evaluation here once kernel supports it.
+ if (_constants.isConstant(expr)) {
+ var c = _constants.evaluate(expr);
+ if (c is IntConstant && c.value >= low && c.value <= high) return c.value;
+ }
return null;
}
@@ -4520,33 +4368,10 @@
source = (code as StringLiteral).value;
}
- // TODO(vsm): Constructors in dart:html and friends are trying to
- // allocate a type defined on window/self, but this often conflicts a
- // with the generated extension class in scope. We really should
- // qualify explicitly in dart:html itself.
- var constructorPattern = new RegExp("new [A-Z][A-Za-z]+\\(");
- if (constructorPattern.matchAsPrefix(source) != null) {
- var enclosingClass = node.parent;
- while (enclosingClass != null && enclosingClass is! Class) {
- enclosingClass = enclosingClass.parent;
- }
- if (enclosingClass is Class &&
- _extensionTypes.isNativeClass(enclosingClass)) {
- var constructorName = source.substring(4, source.indexOf('('));
- var className = enclosingClass.name;
- if (className == constructorName) {
- source =
- source.replaceFirst('new $className(', 'new self.$className(');
- }
- }
- }
-
- // TODO(rnystrom): The JS() calls are almost never nested, and probably
- // really shouldn't be, but there are at least a couple of calls in the
- // HTML library where an argument to JS() is itself a JS() call. If those
- // go away, this can just assert(!_isInForeignJS).
- // Inside JS(), type names evaluate to the raw runtime type, not the
- // wrapped Type object.
+ // TODO(jmesserly): arguments to JS() that contain type literals evaluate to
+ // the raw runtime type instead of the wrapped Type object.
+ // We can clean this up by switching to `unwrapType(<type literal>)`, which
+ // the compiler will then optimize.
var wasInForeignJS = _isInForeignJS;
_isInForeignJS = true;
var jsArgs = templateArgs.map(_visitExpression).toList();
@@ -4644,31 +4469,11 @@
? ctorClass.rawType
: new InterfaceType(ctorClass, args.types);
- if (node.isConst &&
- ctor.name.name == 'fromEnvironment' &&
- ctor.enclosingLibrary == coreTypes.coreLibrary &&
- args.positional.length == 1 &&
- // TODO(jmesserly): this does not correctly handle when the arguments to
- // fromEnvironment are constant non-literal values.
- args.positional[0] is BasicLiteral) {
- var varName = (args.positional[0] as StringLiteral).value;
- var value = declaredVariables[varName];
- var defaultArg = args.named.isNotEmpty ? args.named[0].value : null;
- if (ctorClass == coreTypes.stringClass) {
- if (value != null) return js.escapedString(value);
- return _visitExpression(defaultArg) ?? new JS.LiteralNull();
- } else if (ctorClass == coreTypes.intClass) {
- var intValue = int.parse(value ?? '', onError: (_) => null);
- if (intValue != null) return js.number(intValue);
- return _visitExpression(defaultArg) ?? new JS.LiteralNull();
- } else if (ctorClass == coreTypes.boolClass) {
- if (value == "true") return js.boolean(true);
- if (value == "false") return js.boolean(false);
- return _visitExpression(defaultArg) ?? js.boolean(false);
- } else {
- return _emitInvalidNode(node, '$ctorClass.fromEnvironment constant');
- }
+ if (isFromEnvironmentInvocation(coreTypes, node)) {
+ var value = _constants.evaluate(node);
+ if (value is PrimitiveConstant) return value.accept(this);
}
+
if (args.positional.isEmpty &&
args.named.isEmpty &&
ctorClass.enclosingLibrary.importUri.scheme == 'dart') {
@@ -4908,7 +4713,7 @@
var last = node.value.split('.').last;
var name = js.escapedString(node.value, "'");
if (last.startsWith('_')) {
- var nativeSymbol = _emitPrivateNameSymbol(_currentLibrary, last);
+ var nativeSymbol = emitPrivateNameSymbol(_currentLibrary, last);
return js.call('new #.new(#, #)', [
_emitConstructorAccess(privateSymbolClass.rawType),
name,
@@ -4938,7 +4743,7 @@
if (_currentFunction == null || usesTypeParams) return jsExpr;
var temp = new JS.TemporaryId('const');
- _moduleItems.add(js.statement('let #;', [temp]));
+ moduleItems.add(js.statement('let #;', [temp]));
return js.call('# || (# = #)', [temp, temp, jsExpr]);
}
@@ -5161,6 +4966,52 @@
bool _isObjectMemberCall(Expression target, String memberName) {
return isObjectMember(memberName) && isNullable(target);
}
+
+ /// Returns the name value of the `JSExportName` annotation (when compiling
+ /// the SDK), or `null` if there's none. This is used to control the name
+ /// under which functions are compiled and exported.
+ String getJSExportName(NamedNode n) {
+ var library = getLibrary(n);
+ if (library == null || library.importUri.scheme != 'dart') return null;
+
+ return getAnnotationName(n, isJSExportNameAnnotation);
+ }
+
+ /// If [node] has annotation matching [test] and the first argument is a
+ /// string, this returns the string value.
+ ///
+ /// Calls [findAnnotation] followed by [getNameFromAnnotation].
+ String getAnnotationName(NamedNode node, bool test(Expression value)) {
+ return _constants.getNameFromAnnotation(findAnnotation(node, test));
+ }
+
+ @override
+ visitNullConstant(NullConstant node) => new JS.LiteralNull();
+ @override
+ visitBoolConstant(BoolConstant node) => js.boolean(node.value);
+ @override
+ visitIntConstant(IntConstant node) => js.number(node.value);
+ @override
+ visitDoubleConstant(DoubleConstant node) => js.number(node.value);
+ @override
+ visitStringConstant(StringConstant node) => js.escapedString(node.value, '"');
+
+ // DDC does not currently use the non-primivite constant nodes; rather these
+ // are emitted via their normal expression nodes.
+ @override
+ defaultConstant(Constant node) => _emitInvalidNode(node);
+ @override
+ visitMapConstant(node) => defaultConstant(node);
+ @override
+ visitListConstant(node) => defaultConstant(node);
+ @override
+ visitInstanceConstant(node) => defaultConstant(node);
+ @override
+ visitTearOffConstant(node) => defaultConstant(node);
+ @override
+ visitTypeLiteralConstant(node) => defaultConstant(node);
+ @override
+ visitPartialInstantiationConstant(node) => defaultConstant(node);
}
bool isSdkInternalRuntime(Library l) =>
diff --git a/pkg/dev_compiler/lib/src/kernel/constants.dart b/pkg/dev_compiler/lib/src/kernel/constants.dart
new file mode 100644
index 0000000..fb88289
--- /dev/null
+++ b/pkg/dev_compiler/lib/src/kernel/constants.dart
@@ -0,0 +1,332 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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:kernel/core_types.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/constants.dart';
+import 'package:kernel/type_environment.dart';
+import 'kernel_helpers.dart';
+
+/// Implements constant evaluation for dev compiler:
+///
+/// [isConstant] determines if an expression is constant.
+/// [evaluate] computes the value of a constant expression, if available.
+class DevCompilerConstants {
+ final _ConstantVisitor _visitor;
+ final _ConstantEvaluator _evaluator;
+
+ DevCompilerConstants(
+ TypeEnvironment types, Map<String, String> declaredVariables)
+ : _visitor = new _ConstantVisitor(types.coreTypes),
+ _evaluator = new _ConstantEvaluator(types, declaredVariables);
+
+ /// Determines if an expression is constant.
+ bool isConstant(Expression e) => _visitor.isConstant(e);
+
+ /// Evaluates [e] to find its constant value, returning `null` if evaluation
+ /// failed, or if the constant was unavailable.
+ ///
+ /// Returns [NullConstant] to represent the `null` value.
+ ///
+ /// To avoid performance costs associated with try+catch on invalid constant
+ /// evaluation, call this after [isConstant] is known to be true.
+ Constant evaluate(Expression e, {bool cache: false}) {
+ if (e == null) return null;
+
+ try {
+ var result = cache ? _evaluator.evaluate(e) : e.accept(_evaluator);
+ return identical(result, _evaluator.unavailableConstant) ? null : result;
+ } on _AbortCurrentEvaluation {
+ // TODO(jmesserly): the try+catch is necessary because the front end is
+ // not issuing sufficient errors, so the constant evaluation can fail.
+ //
+ // It can also be caused by methods in the evaluator that don't understand
+ // unavailable constants.
+ return null;
+ }
+ }
+
+ /// If [node] is an annotation with a field named `name`, returns that field's
+ /// value.
+ ///
+ /// This assumes the `name` field is populated from a named argument `name:`
+ /// or from the first positional argument.
+ ///
+ /// For example:
+ ///
+ /// class MyAnnotation {
+ /// final String name;
+ /// // ...
+ /// const MyAnnotation(this.name/*, ... other params ... */);
+ /// }
+ ///
+ /// @MyAnnotation('FooBar')
+ /// main() { ... }
+ ///
+ /// Given the node for `@MyAnnotation('FooBar')` this will return `'FooBar'`.
+ String getNameFromAnnotation(ConstructorInvocation node) {
+ if (node == null) return null;
+
+ // TODO(jmesserly): this does not use the normal evaluation engine, because
+ // it won't work if we don't have the const constructor body available.
+ //
+ // We may need to address this in the kernel outline files.
+ Expression first;
+ var named = node.arguments.named;
+ if (named.isNotEmpty) {
+ first =
+ named.firstWhere((n) => n.name == 'name', orElse: () => null)?.value;
+ }
+ var positional = node.arguments.positional;
+ if (positional.isNotEmpty) first ??= positional[0];
+ if (first != null) {
+ first = _followConstFields(first);
+ if (first is StringLiteral) return first.value;
+ }
+ return null;
+ }
+
+ Expression _followConstFields(Expression expr) {
+ if (expr is StaticGet) {
+ var target = expr.target;
+ if (target is Field) {
+ return _followConstFields(target.initializer);
+ }
+ }
+ return expr;
+ }
+}
+
+/// Finds constant expressions as defined in Dart language spec 4th ed,
+/// 16.1 Constants.
+class _ConstantVisitor extends ExpressionVisitor<bool> {
+ final CoreTypes coreTypes;
+ _ConstantVisitor(this.coreTypes);
+
+ bool isConstant(Expression e) => e.accept(this);
+
+ defaultExpression(node) => false;
+ defaultBasicLiteral(node) => true;
+ visitTypeLiteral(node) => true; // TODO(jmesserly): deferred libraries?
+ visitSymbolLiteral(node) => true;
+ visitListLiteral(node) => node.isConst;
+ visitMapLiteral(node) => node.isConst;
+ visitStaticInvocation(node) {
+ return node.isConst ||
+ node.target == coreTypes.identicalProcedure &&
+ node.arguments.positional.every(isConstant) ||
+ isFromEnvironmentInvocation(coreTypes, node) &&
+ node.arguments.positional.every(isConstant) &&
+ node.arguments.named.every((n) => isConstant(n.value));
+ }
+
+ visitDirectMethodInvocation(node) {
+ return node.receiver is BasicLiteral &&
+ isOperatorMethodName(node.name.name) &&
+ node.arguments.positional.every((p) => p is BasicLiteral);
+ }
+
+ visitMethodInvocation(node) {
+ return node.receiver is BasicLiteral &&
+ isOperatorMethodName(node.name.name) &&
+ node.arguments.positional.every((p) => p is BasicLiteral);
+ }
+
+ visitConstructorInvocation(node) => node.isConst;
+ visitStringConcatenation(node) =>
+ node.expressions.every((e) => e is BasicLiteral);
+ visitStaticGet(node) {
+ var target = node.target;
+ return target is Procedure || target is Field && target.isConst;
+ }
+
+ visitVariableGet(node) => node.variable.isConst;
+ visitNot(node) {
+ var operand = node.operand;
+ return operand is BoolLiteral ||
+ operand is DirectMethodInvocation &&
+ visitDirectMethodInvocation(operand) ||
+ operand is MethodInvocation && visitMethodInvocation(operand);
+ }
+
+ visitLogicalExpression(node) =>
+ node.left is BoolLiteral && node.right is BoolLiteral;
+ visitConditionalExpression(node) =>
+ node.condition is BoolLiteral &&
+ node.then is BoolLiteral &&
+ node.otherwise is BoolLiteral;
+
+ visitLet(Let node) {
+ var init = node.variable.initializer;
+ return (init == null || isConstant(init)) && isConstant(node.body);
+ }
+}
+
+/// The visitor that evaluates constants, building on Kernel's
+/// [ConstantEvaluator] class (used by the VM) and fixing some of its behavior
+/// to work better for DDC.
+//
+// TODO(jmesserly): make some changes in the base class to make it a better fit
+// for compilers like DDC?
+class _ConstantEvaluator extends ConstantEvaluator {
+ final Map<String, String> declaredVariables;
+
+ /// Used to denote an unavailable constant value from another module
+ ///
+ // TODO(jmesserly): this happens when we try to evaluate constant values from
+ // an external library, that was from an outline kernel file. The kernel file
+ // does not contain the initializer value of the constant.
+ final Constant unavailableConstant;
+
+ _ConstantEvaluator(TypeEnvironment types, this.declaredVariables,
+ {bool enableAsserts})
+ : unavailableConstant = new InstanceConstant(
+ types.coreTypes.index
+ .getClass('dart:core', '_ConstantExpressionError')
+ .reference,
+ [],
+ {}),
+ super(new _ConstantsBackend(types.coreTypes), types, types.coreTypes,
+ true, enableAsserts, const _ErrorReporter()) {
+ env = new EvaluationEnvironment();
+ }
+
+ @override
+ visitVariableGet(node) {
+ // The base evaluator expects that variable declarations are visited during
+ // the transformation step, so it doesn't handle constant variables.
+ // Instead handle them here.
+ if (node.variable.isConst) {
+ return evaluate(node.variable.initializer);
+ }
+ // Fall back to the base evaluator for other cases (e.g. parameters of a
+ // constant constructor).
+ return super.visitVariableGet(node);
+ }
+
+ @override
+ visitStaticGet(StaticGet node) {
+ // Handle unavailable field constants. This happens if an external library
+ // only has its outline available.
+ var target = node.target;
+ if (target is Field &&
+ target.isConst &&
+ target.isInExternalLibrary &&
+ target.initializer == null) {
+ return unavailableConstant;
+ }
+ return super.visitStaticGet(node);
+ }
+
+ @override
+ visitConstructorInvocation(ConstructorInvocation node) {
+ // Handle unavailable constructor bodies.
+ // This happens if an external library only has its outline available.
+ var target = node.target;
+ if (target.isConst &&
+ target.isInExternalLibrary &&
+ target.function.body is EmptyStatement &&
+ target.initializers.isEmpty) {
+ return unavailableConstant;
+ }
+ return super.visitConstructorInvocation(node);
+ }
+
+ @override
+ visitStaticInvocation(node) {
+ // Handle int/bool/String.fromEnvironment constructors.
+ //
+ // (The VM handles this via its `native` calls and implements it in
+ // VmConstantsBackend.buildConstantForNative.)
+ var target = node.target;
+ if (isFromEnvironmentInvocation(coreTypes, node)) {
+ var firstArg = evaluatePositionalArguments(node.arguments)[0];
+ var defaultArg = evaluateNamedArguments(node.arguments)['defaultValue'];
+
+ var varName = (firstArg as StringConstant).value;
+ var value = declaredVariables[varName];
+ var targetClass = target.enclosingClass;
+
+ if (targetClass == coreTypes.stringClass) {
+ if (value != null) return canonicalize(new StringConstant(value));
+ return defaultArg ?? nullConstant;
+ } else if (targetClass == coreTypes.intClass) {
+ var intValue = int.parse(value ?? '', onError: (_) => null);
+ if (intValue != null) return canonicalize(new IntConstant(intValue));
+ return defaultArg ?? nullConstant;
+ } else if (targetClass == coreTypes.boolClass) {
+ if (value == "true") return trueConstant;
+ if (value == "false") return falseConstant;
+ return defaultArg ?? falseConstant;
+ }
+ }
+ return super.visitStaticInvocation(node);
+ }
+
+ @override
+ evaluateBinaryNumericOperation(String op, num a, num b, TreeNode node) {
+ // Use doubles to match JS number semantics.
+ return super
+ .evaluateBinaryNumericOperation(op, a.toDouble(), b.toDouble(), node);
+ }
+
+ @override
+ canonicalize(Constant constant) {
+ if (constant is DoubleConstant) {
+ // Convert to an integer when possible (matching the runtime behavior
+ // of `is int`).
+ var d = constant.value;
+ if (d.isFinite) {
+ var i = d.toInt();
+ if (d == i.toDouble()) return super.canonicalize(new IntConstant(i));
+ }
+ }
+ return super.canonicalize(constant);
+ }
+}
+
+/// Implement the class for compiler specific behavior.
+///
+/// This is mostly unused by DDC, because we don't use the global constant
+/// transformer.
+class _ConstantsBackend implements ConstantsBackend {
+ final CoreTypes coreTypes;
+ final Field symbolNameField;
+
+ _ConstantsBackend(this.coreTypes)
+ : symbolNameField = coreTypes.internalSymbolClass.fields
+ .firstWhere((f) => f.name.name == '_name');
+
+ @override
+ buildConstantForNative(
+ nativeName, typeArguments, positionalArguments, namedArguments) =>
+ throw new StateError('unreachable'); // DDC does not use VM native syntax
+
+ @override
+ buildSymbolConstant(StringConstant value) {
+ return new InstanceConstant(
+ coreTypes.internalSymbolClass.reference,
+ const <DartType>[],
+ <Reference, Constant>{symbolNameField.reference: value});
+ }
+
+ @override
+ lowerMapConstant(constant) => constant;
+
+ @override
+ lowerListConstant(constant) => constant;
+}
+
+class _ErrorReporter extends ErrorReporterBase {
+ const _ErrorReporter();
+
+ @override
+ report(context, message, node) => throw const _AbortCurrentEvaluation();
+}
+
+// TODO(jmesserly): this class is private in Kernel constants library, so
+// we have our own version.
+class _AbortCurrentEvaluation {
+ const _AbortCurrentEvaluation();
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/js_interop.dart b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
index 890edab..95145f6 100644
--- a/pkg/dev_compiler/lib/src/kernel/js_interop.dart
+++ b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
@@ -110,13 +110,3 @@
(n is Procedure && n.isExternal ||
n is Class && n.annotations.any(isPublicJSAnnotation));
}
-
-/// Returns the name value of the `JSExportName` annotation (when compiling
-/// the SDK), or `null` if there's none. This is used to control the name
-/// under which functions are compiled and exported.
-String getJSExportName(NamedNode n) {
- var library = getLibrary(n);
- if (library == null || library.importUri.scheme != 'dart') return null;
-
- return getAnnotationName(n, isJSExportNameAnnotation);
-}
diff --git a/pkg/dev_compiler/lib/src/kernel/js_typerep.dart b/pkg/dev_compiler/lib/src/kernel/js_typerep.dart
index 8b6500b..103e981 100644
--- a/pkg/dev_compiler/lib/src/kernel/js_typerep.dart
+++ b/pkg/dev_compiler/lib/src/kernel/js_typerep.dart
@@ -4,7 +4,6 @@
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
-import 'package:kernel/library_index.dart';
import 'package:kernel/type_environment.dart';
/// An abstraction of the JS types
@@ -89,17 +88,19 @@
class JSTypeRep {
final TypeEnvironment types;
final CoreTypes coreTypes;
- final LibraryIndex sdk;
final Class _jsBool;
final Class _jsNumber;
-
final Class _jsString;
- JSTypeRep(this.types, this.sdk)
+
+ JSTypeRep(this.types)
: coreTypes = types.coreTypes,
- _jsBool = sdk.getClass('dart:_interceptors', 'JSBool'),
- _jsNumber = sdk.getClass('dart:_interceptors', 'JSNumber'),
- _jsString = sdk.getClass('dart:_interceptors', 'JSString');
+ _jsBool =
+ types.coreTypes.index.getClass('dart:_interceptors', 'JSBool'),
+ _jsNumber =
+ types.coreTypes.index.getClass('dart:_interceptors', 'JSNumber'),
+ _jsString =
+ types.coreTypes.index.getClass('dart:_interceptors', 'JSString');
JSType typeFor(DartType type) {
while (type is TypeParameterType) {
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index d0043bb..dc11518 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -89,120 +89,6 @@
return false;
}
-/// If [node] has annotation matching [test] and the first argument is a
-/// string, this returns the string value.
-///
-/// Calls [findAnnotation] followed by [getNameFromAnnotation].
-String getAnnotationName(NamedNode node, bool test(Expression value)) {
- return getNameFromAnnotation(findAnnotation(node, test));
-}
-
-/// If [node] is an annotation and the first argument is a string, this returns
-/// the string value.
-///
-/// For example
-///
-/// class MyAnnotation {
-/// final String name;
-/// // ...
-/// const MyAnnotation(this.name/*, ... other params ... */);
-/// }
-///
-/// @MyAnnotation('FooBar')
-/// main() { ... }
-///
-/// Given teh node for `@MyAnnotation('FooBar')` this will return `'FooBar'`.
-String getNameFromAnnotation(ConstructorInvocation node) {
- if (node != null) {
- Expression first;
- if (node.arguments.named.isNotEmpty) {
- first = node.arguments.named
- .firstWhere((n) => n.name == 'name', orElse: () => null)
- ?.value;
- }
- if (node.arguments.positional.isNotEmpty) {
- first ??= node.arguments.positional[0];
- }
- if (first != null) {
- first = _followConstFields(first);
- if (first is StringLiteral) return first.value;
- }
- }
- return null;
-}
-
-Expression _followConstFields(Expression expr) {
- if (expr is StaticGet) {
- var target = expr.target;
- if (target is Field) {
- return _followConstFields(target.initializer);
- }
- }
- return expr;
-}
-
-/// Finds constant expressions as defined in Dart language spec 4th ed,
-/// 16.1 Constants
-class ConstantVisitor extends ExpressionVisitor<bool> {
- final CoreTypes coreTypes;
- ConstantVisitor(this.coreTypes);
-
- bool isConstant(Expression e) => e.accept(this) as bool;
-
- defaultExpression(node) => false;
- defaultBasicLiteral(node) => true;
- visitTypeLiteral(node) => true; // TODO(jmesserly): deferred libraries?
- visitSymbolLiteral(node) => true;
- visitListLiteral(node) => node.isConst;
- visitMapLiteral(node) => node.isConst;
- visitStaticInvocation(node) {
- return node.isConst ||
- node.target == coreTypes.identicalProcedure &&
- node.arguments.positional.every(isConstant);
- }
-
- visitDirectMethodInvocation(node) {
- return node.receiver is BasicLiteral &&
- isOperatorMethodName(node.name.name) &&
- node.arguments.positional.every((p) => p is BasicLiteral);
- }
-
- visitMethodInvocation(node) {
- return node.receiver is BasicLiteral &&
- isOperatorMethodName(node.name.name) &&
- node.arguments.positional.every((p) => p is BasicLiteral);
- }
-
- visitConstructorInvocation(node) => node.isConst;
- visitStringConcatenation(node) =>
- node.expressions.every((e) => e is BasicLiteral);
- visitStaticGet(node) {
- var target = node.target;
- return target is Procedure || target is Field && target.isConst;
- }
-
- visitVariableGet(node) => node.variable.isConst;
- visitNot(node) {
- var operand = node.operand;
- return operand is BoolLiteral ||
- operand is DirectMethodInvocation &&
- visitDirectMethodInvocation(operand) ||
- operand is MethodInvocation && visitMethodInvocation(operand);
- }
-
- visitLogicalExpression(node) =>
- node.left is BoolLiteral && node.right is BoolLiteral;
- visitConditionalExpression(node) =>
- node.condition is BoolLiteral &&
- node.then is BoolLiteral &&
- node.otherwise is BoolLiteral;
-
- visitLet(Let node) {
- var init = node.variable.initializer;
- return (init == null || isConstant(init)) && isConstant(node.body);
- }
-}
-
/// Returns true if [name] is an operator method that is available on primitive
/// types (`int`, `double`, `num`, `String`, `bool`).
///
@@ -233,6 +119,13 @@
return false;
}
+bool isFromEnvironmentInvocation(CoreTypes coreTypes, StaticInvocation node) {
+ var target = node.target;
+ return node.isConst &&
+ target.name.name == 'fromEnvironment' &&
+ target.enclosingLibrary == coreTypes.coreLibrary;
+}
+
/// Returns true if this class is of the form:
/// `class C = Object with M [implements I1, I2 ...];`
///
diff --git a/pkg/dev_compiler/lib/src/kernel/native_types.dart b/pkg/dev_compiler/lib/src/kernel/native_types.dart
index 1ac42bb..78876b4 100644
--- a/pkg/dev_compiler/lib/src/kernel/native_types.dart
+++ b/pkg/dev_compiler/lib/src/kernel/native_types.dart
@@ -5,8 +5,7 @@
import 'dart:collection';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
-import 'package:kernel/library_index.dart';
-import 'kernel_helpers.dart' show getNameFromAnnotation;
+import 'constants.dart';
/// Contains information about native JS types (those types provided by the
/// implementation) that are also provided by the Dart SDK.
@@ -27,7 +26,7 @@
/// `first` to the `Array.prototype`.
class NativeTypeSet {
final CoreTypes coreTypes;
- final LibraryIndex sdk;
+ final DevCompilerConstants constants;
// Abstract types that may be implemented by both native and non-native
// classes.
@@ -37,9 +36,7 @@
final _nativeTypes = new HashSet<Class>.identity();
final _pendingLibraries = new HashSet<Library>.identity();
- NativeTypeSet(Component component)
- : sdk = new LibraryIndex.coreLibraries(component),
- coreTypes = new CoreTypes(component) {
+ NativeTypeSet(this.coreTypes, this.constants) {
// First, core types:
// TODO(vsm): If we're analyzing against the main SDK, those
// types are not explicitly annotated.
@@ -48,6 +45,8 @@
_addExtensionType(coreTypes.doubleClass, true);
_addExtensionType(coreTypes.boolClass, true);
_addExtensionType(coreTypes.stringClass, true);
+
+ var sdk = coreTypes.index;
_addExtensionTypes(sdk.getLibrary('dart:_interceptors'));
_addExtensionTypes(sdk.getLibrary('dart:_native_typed_data'));
@@ -82,6 +81,7 @@
}
void _addExtensionTypesForLibrary(String library, List<String> classNames) {
+ var sdk = coreTypes.index;
for (var className in classNames) {
_addExtensionType(sdk.getClass(library, className), true);
}
@@ -125,7 +125,7 @@
/// referring to the JavaScript built-in `Array` type.
List<String> getNativePeers(Class c) {
if (c == coreTypes.objectClass) return ['Object'];
- var names = getNameFromAnnotation(_getNativeAnnotation(c));
+ var names = constants.getNameFromAnnotation(_getNativeAnnotation(c));
if (names == null) return const [];
// Omit the special name "!nonleaf" and any future hacks starting with "!"
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 51cad84..e630821 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -196,8 +196,6 @@
/// super.
final inheritedSetters = new HashSet<String>();
- final mockMembers = <String, Member>{};
-
final extensionMethods = new Set<String>();
final extensionAccessors = new Set<String>();
@@ -231,14 +229,12 @@
}
}
- _collectMockMembers(class_);
_collectExtensionMembers(class_);
var virtualAccessorNames = new HashSet<String>()
..addAll(inheritedGetters)
..addAll(inheritedSetters)
- ..addAll(extensionAccessors)
- ..addAll(mockMembers.values.map((m) => m.name.name));
+ ..addAll(extensionAccessors);
// Visit accessors in the current class, and see if they need to be
// generated differently based on the inherited fields/accessors.
@@ -258,62 +254,6 @@
CoreTypes get coreTypes => extensionTypes.coreTypes;
- void _collectMockMembers(Class class_) {
- // TODO(jmesserly): every type with nSM will generate new stubs for all
- // abstract members. For example:
- //
- // class C { m(); noSuchMethod(...) { ... } }
- // class D extends C { m(); noSuchMethod(...) { ... } }
- //
- // We'll generate D.m even though it is not necessary.
- //
- // Doing better is a bit tricky, as our current codegen strategy for the
- // mock methods encodes information about the number of arguments (and type
- // arguments) that D expects.
- if (!_hasNoSuchMethod(class_)) return;
-
- // Collect all unimplemented members.
- //
- // Initially, we track abstract and concrete members separately, then
- // remove concrete from the abstract set. This is done because abstract
- // members are allowed to "override" concrete ones in Dart.
- // (In that case, it will still be treated as a concrete member and can be
- // called at runtime.)
- var concreteMembers = new HashSet<String>();
-
- void addMember(Member m, bool classIsAbstract, {bool isSetter: false}) {
- var name = m.name.name;
- if (isSetter) name += '=';
- if (classIsAbstract || m.isAbstract) {
- mockMembers[name] = m;
- } else {
- concreteMembers.add(name);
- }
- }
-
- void visit(Class c, bool classIsAbstract) {
- if (c == null) return;
- visit(c.superclass, classIsAbstract);
- visit(c.mixedInClass, classIsAbstract);
- for (var i in c.implementedTypes) visit(i.classNode, true);
-
- for (var m in c.members) {
- if (m is Field) {
- if (m.isStatic) continue;
- addMember(m, classIsAbstract);
- if (m.hasSetter) addMember(m, classIsAbstract, isSetter: true);
- } else if (m is Procedure) {
- if (m.isStatic) continue;
- addMember(m, classIsAbstract, isSetter: m.isSetter);
- }
- }
- }
-
- visit(class_, false);
-
- concreteMembers.forEach(mockMembers.remove);
- }
-
void _collectExtensionMembers(Class class_) {
if (extensionTypes.isNativeClass(class_)) return;
@@ -327,17 +267,6 @@
// For members on this class, check them against all generic interfaces.
var seenConcreteMembers = new HashSet<String>();
_findExtensionMembers(class_, seenConcreteMembers, allNatives);
- // Add mock members. These are compiler-generated concrete members that
- // forward to `noSuchMethod`.
- for (var m in mockMembers.values) {
- var name = m.name.name;
- if (seenConcreteMembers.add(name) && allNatives.contains(name)) {
- var extMembers = m is Procedure && !m.isAccessor
- ? extensionMethods
- : extensionAccessors;
- extMembers.add(name);
- }
- }
// For members of the superclass, we may need to add checks because this
// class adds a new unsafe interface. Collect those checks.
@@ -421,17 +350,4 @@
var s = c.superclass;
if (s != null) _collectNativeMembers(s, members);
}
-
- /// Return `true` if the given [classElement] has a noSuchMethod() method
- /// distinct from the one declared in class Object, as per the Dart Language
- /// Specification (section 10.4).
- // TODO(jmesserly): this was taken from error_verifier.dart
- bool _hasNoSuchMethod(Class c) {
- // TODO(jmesserly): is this lookup fast in Kernel?
- // TODO(jmesserly): our old code may have matched an abstract nSM, but
- // that seems incorrect. So we now look for a dispatch target.
- var method = types.hierarchy.getDispatchTarget(c, new Name('noSuchMethod'));
- var definingClass = method?.enclosingClass;
- return definingClass != null && definingClass != coreTypes.objectClass;
- }
}
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index b1888c6..26dbc21 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:core' hide MapEntry;
import 'package:kernel/kernel.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/class_hierarchy.dart';
@@ -57,6 +58,9 @@
bool get nativeExtensionExpectsString => false;
@override
+ bool get enableNoSuchMethodForwarders => true;
+
+ @override
void performModularTransformationsOnLibraries(
CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
{void logger(String msg)}) {}
@@ -68,8 +72,40 @@
@override
Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
String name, Arguments arguments, int offset, bool isSuper) {
- // TODO(sigmund): implement;
- return new InvalidExpression(null);
+ // TODO(jmesserly): preserve source information?
+ // (These method are synthetic. Also unclear if the offset will correspond
+ // to the file where the class resides, or the file where the method we're
+ // mocking resides).
+ Expression createInvocation(String name, List<Expression> positional) {
+ var ctor = coreTypes.invocationClass.procedures
+ .firstWhere((c) => c.name.name == name);
+ return new StaticInvocation(ctor, new Arguments(positional));
+ }
+
+ if (name.startsWith('get:')) {
+ return createInvocation('getter', [new SymbolLiteral(name.substring(4))]);
+ }
+ if (name.startsWith('set:')) {
+ return createInvocation('setter', [
+ new SymbolLiteral(name.substring(4) + '='),
+ arguments.positional.single
+ ]);
+ }
+ var ctorArgs = <Expression>[new SymbolLiteral(name)];
+ bool isGeneric = arguments.types.isNotEmpty;
+ if (isGeneric) {
+ ctorArgs.add(new ListLiteral(
+ arguments.types.map((t) => new TypeLiteral(t)).toList()));
+ }
+ ctorArgs.add(new ListLiteral(arguments.positional));
+ if (arguments.named.isNotEmpty) {
+ ctorArgs.add(new MapLiteral(
+ arguments.named
+ .map((n) => new MapEntry(new SymbolLiteral(n.name), n.value))
+ .toList(),
+ keyType: coreTypes.symbolClass.rawType));
+ }
+ return createInvocation(isGeneric ? 'genericMethod' : 'method', ctorArgs);
}
@override
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index be94da4..dadc9018 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -9,7 +9,6 @@
import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
-import 'package:kernel/library_index.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:test/test.dart';
@@ -491,9 +490,9 @@
@override
visitComponent(Component node) {
inference ??= new NullableInference(new JSTypeRep(
- new TypeSchemaEnvironment(
- new CoreTypes(node), new ClassHierarchy(node), true),
- new LibraryIndex.coreLibraries(node)));
+ new TypeSchemaEnvironment(
+ new CoreTypes(node), new ClassHierarchy(node), true),
+ ));
if (useAnnotations) {
inference.allowNotNullDeclarations = useAnnotations;
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index b42781e..493b103 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -55,7 +55,7 @@
ProcessResult runDdc(String command, List<String> args) {
if (debug) {
// Use unbuilt script. This only works from a source checkout.
- args.insertAll(0, ['-c', path.join(ddcPath, 'bin', '${command}.dart')]);
+ args.insertAll(0, ['--preview-dart-2', '-c', path.join(ddcPath, 'bin', '${command}.dart')]);
command = dartBinary;
} else {
// Use built snapshot.
diff --git a/pkg/dev_compiler/tool/ddc b/pkg/dev_compiler/tool/ddc
index cc8f410..aa6f9d8 100755
--- a/pkg/dev_compiler/tool/ddc
+++ b/pkg/dev_compiler/tool/ddc
@@ -74,7 +74,7 @@
exit 1
fi
- dart -c $SDK_DIR/pkg/dev_compiler/bin/dartdevk.dart --modules=node \
+ $SDK_DIR/sdk/bin/dartdevk --modules=node \
--dart-sdk-summary=$GEN_DIR/kernel/ddc_sdk.dill \
-o $LIBROOT/$BASENAME.js $*
else
@@ -86,7 +86,7 @@
exit 1
fi
- dart -c $SDK_DIR/pkg/dev_compiler/bin/dartdevc.dart --modules=node \
+ $SDK_DIR/sdk/bin/dartdevc --modules=node \
--library-root=$LIBROOT --dart-sdk-summary=$GEN_DIR/ddc_sdk.sum \
-o $LIBROOT/$BASENAME.js $*
fi
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 7ae52ae..24d3768 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -602,6 +602,12 @@
@patch
class NoSuchMethodError {
+ final Object _receiver;
+ final Symbol _memberName;
+ final List _arguments;
+ final Map<Symbol, dynamic> _namedArguments;
+ final List _existingArgumentNames;
+
@patch
NoSuchMethodError(Object receiver, Symbol memberName,
List positionalArguments, Map<Symbol, dynamic> namedArguments,
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index ca353ba..b8b88e2 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -6,6 +6,7 @@
/// generator.
part of dart._runtime;
+// TODO(jmesserly): remove this in favor of _Invocation.
class InvocationImpl extends Invocation {
final Symbol memberName;
final List positionalArguments;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
index 3cac8a5..e392cfb 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
@@ -20,7 +20,9 @@
*/
factory JSArray.of(list) {
// TODO(sra): Move this to core.List for better readability.
- // Capture the parameterized ES6 'JSArray' class.
+ //
+ // TODO(jmesserly): this uses special compiler magic to close over the
+ // parameterized ES6 'JSArray' class.
JS('', '#.__proto__ = JSArray.prototype', list);
return JS('-dynamic', '#', list);
}
diff --git a/pkg/front_end/README.md b/pkg/front_end/README.md
index fd5aed2..6c4e0ed 100644
--- a/pkg/front_end/README.md
+++ b/pkg/front_end/README.md
@@ -13,4 +13,6 @@
[analyzer] package.
_Note:_ The APIs in this package are in an early state; developers should be
-careful about depending on this package.
+careful about depending on this package. In particular, there is no semver
+contract for release versions of this package. Please depend directly on individual
+versions.
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index 76e4075..f10c806 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -19,10 +19,10 @@
abstract class IncrementalKernelGenerator {
factory IncrementalKernelGenerator(CompilerOptions options, Uri entryPoint,
- [Uri bootstrapDill]) {
+ [Uri initializeFromDillUri]) {
return new IncrementalCompiler(
new CompilerContext(new ProcessedOptions(options, false, [entryPoint])),
- bootstrapDill);
+ initializeFromDillUri);
}
/// Returns a component whose libraries are the recompiled libraries,
@@ -61,6 +61,7 @@
String expression,
Map<String, DartType> definitions,
List<TypeParameter> typeDefinitions,
+ String syntheticProcedureName,
Uri libraryUri,
[String className,
bool isStatic = false]);
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 5407f55..1815328 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -176,7 +176,7 @@
/// where they were omitted by the programmer and not provided by the type
/// inference. The method returns the number of distinct type variables
/// that were instantiated in this library.
- int instantiateToBound(TypeBuilder dynamicType, TypeBuilder bottomType,
+ int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder bottomType,
ClassBuilder objectClass) {
return 0;
}
diff --git a/pkg/front_end/lib/src/fasta/deprecated_problems.dart b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
index 8ec0ce2..fd2e6dd 100644
--- a/pkg/front_end/lib/src/fasta/deprecated_problems.dart
+++ b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
@@ -94,13 +94,14 @@
hasCrashed = false;
}
-Future reportCrash(error, StackTrace trace, [Uri uri, int charOffset]) async {
+Future<T> reportCrash<T>(error, StackTrace trace,
+ [Uri uri, int charOffset]) async {
note(String note) async {
stderr.write(note);
await stderr.flush();
}
- if (hasCrashed) return new Future.error(error, trace);
+ if (hasCrashed) return new Future<T>.error(error, trace);
if (error is Crash) {
trace = error.trace ?? trace;
uri = error.uri ?? uri;
@@ -126,7 +127,8 @@
} on SocketException {
// Assume the crash logger isn't running.
await client.close(force: true);
- return new Future.error(new Crash(uri, charOffset, error, trace), trace);
+ return new Future<T>.error(
+ new Crash(uri, charOffset, error, trace), trace);
}
if (request != null) {
await note("\nSending crash report data");
@@ -147,7 +149,7 @@
}
await client.close(force: true);
await note("\n");
- return new Future.error(error, trace);
+ return new Future<T>.error(error, trace);
}
String safeToString(Object object) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes.dart b/pkg/front_end/lib/src/fasta/fasta_codes.dart
index 3d1368d..6e7dbc1 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes.dart
@@ -4,7 +4,7 @@
library fasta.codes;
-import 'package:kernel/ast.dart' show DartType;
+import 'package:kernel/ast.dart' show Constant, DartType;
import 'package:kernel/text/ast_to_text.dart' show NameSystem, Printer;
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index ae67c8e..e65d55b 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -726,6 +726,257 @@
tip: r"""Try removing either the 'const' keyword or the body.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstEvalContext = messageConstEvalContext;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstEvalContext =
+ const MessageCode("ConstEvalContext", message: r"""While analyzing:""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ Constant
+ constant)> templateConstEvalDuplicateKey = const Template<
+ Message Function(Constant constant)>(
+ messageTemplate:
+ r"""The key '#constant' conflicts with another existing key in the map.""",
+ withArguments: _withArgumentsConstEvalDuplicateKey);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant constant)> codeConstEvalDuplicateKey =
+ const Code<Message Function(Constant constant)>(
+ "ConstEvalDuplicateKey", templateConstEvalDuplicateKey,
+ analyzerCode: "EQUAL_KEYS_IN_MAP");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalDuplicateKey(Constant constant) {
+ return new Message(codeConstEvalDuplicateKey,
+ message:
+ """The key '$constant' conflicts with another existing key in the map.""",
+ arguments: {'constant': constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstEvalFailedAssertion = messageConstEvalFailedAssertion;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstEvalFailedAssertion = const MessageCode(
+ "ConstEvalFailedAssertion",
+ analyzerCode: "CONST_EVAL_THROWS_EXCEPTION",
+ message: r"""This assertion failed.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String string)>
+ templateConstEvalFailedAssertionWithMessage =
+ const Template<Message Function(String string)>(
+ messageTemplate: r"""This assertion failed with message: #string""",
+ withArguments: _withArgumentsConstEvalFailedAssertionWithMessage);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)>
+ codeConstEvalFailedAssertionWithMessage =
+ const Code<Message Function(String string)>(
+ "ConstEvalFailedAssertionWithMessage",
+ templateConstEvalFailedAssertionWithMessage,
+ analyzerCode: "CONST_EVAL_THROWS_EXCEPTION");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalFailedAssertionWithMessage(String string) {
+ return new Message(codeConstEvalFailedAssertionWithMessage,
+ message: """This assertion failed with message: $string""",
+ arguments: {'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String string,
+ Constant constant,
+ DartType _type,
+ DartType
+ _type2)> templateConstEvalInvalidBinaryOperandType = const Template<
+ Message Function(String string, Constant constant, DartType _type,
+ DartType _type2)>(
+ messageTemplate:
+ r"""Binary operator '#string' on '#constant' requires operand of type '#type', but was of type '#type2'.""",
+ withArguments: _withArgumentsConstEvalInvalidBinaryOperandType);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(
+ String string, Constant constant, DartType _type, DartType _type2)>
+ codeConstEvalInvalidBinaryOperandType = const Code<
+ Message Function(
+ String string, Constant constant, DartType _type, DartType _type2)>(
+ "ConstEvalInvalidBinaryOperandType",
+ templateConstEvalInvalidBinaryOperandType,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidBinaryOperandType(
+ String string, Constant constant, DartType _type, DartType _type2) {
+ NameSystem nameSystem = new NameSystem();
+ StringBuffer buffer = new StringBuffer();
+ new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
+ String type = '$buffer';
+
+ buffer = new StringBuffer();
+ new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
+ String type2 = '$buffer';
+
+ return new Message(codeConstEvalInvalidBinaryOperandType,
+ message:
+ """Binary operator '$string' on '$constant' requires operand of type '$type', but was of type '$type2'.""",
+ arguments: {
+ 'string': string,
+ 'constant': constant,
+ 'type': _type,
+ 'type2': _type2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String string,
+ Constant
+ constant)> templateConstEvalInvalidMethodInvocation = const Template<
+ Message Function(String string, Constant constant)>(
+ messageTemplate:
+ r"""The method '#string' can't be invoked on '#constant' within a const context.""",
+ withArguments: _withArgumentsConstEvalInvalidMethodInvocation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, Constant constant)>
+ codeConstEvalInvalidMethodInvocation =
+ const Code<Message Function(String string, Constant constant)>(
+ "ConstEvalInvalidMethodInvocation",
+ templateConstEvalInvalidMethodInvocation,
+ analyzerCode: "UNDEFINED_OPERATOR");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidMethodInvocation(
+ String string, Constant constant) {
+ return new Message(codeConstEvalInvalidMethodInvocation,
+ message:
+ """The method '$string' can't be invoked on '$constant' within a const context.""",
+ arguments: {'string': string, 'constant': constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String
+ name)> templateConstEvalInvalidStaticInvocation = const Template<
+ Message Function(String name)>(
+ messageTemplate:
+ r"""The invocation of '#name' is not allowed within a const context.""",
+ withArguments: _withArgumentsConstEvalInvalidStaticInvocation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeConstEvalInvalidStaticInvocation =
+ const Code<Message Function(String name)>(
+ "ConstEvalInvalidStaticInvocation",
+ templateConstEvalInvalidStaticInvocation,
+ analyzerCode: "CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidStaticInvocation(String name) {
+ return new Message(codeConstEvalInvalidStaticInvocation,
+ message:
+ """The invocation of '$name' is not allowed within a const context.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(Constant constant)>
+ templateConstEvalInvalidStringInterpolationOperand =
+ const Template<Message Function(Constant constant)>(
+ messageTemplate:
+ r"""The '#constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""",
+ withArguments:
+ _withArgumentsConstEvalInvalidStringInterpolationOperand);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant constant)>
+ codeConstEvalInvalidStringInterpolationOperand =
+ const Code<Message Function(Constant constant)>(
+ "ConstEvalInvalidStringInterpolationOperand",
+ templateConstEvalInvalidStringInterpolationOperand,
+ analyzerCode: "CONST_EVAL_TYPE_BOOL_NUM_STRING");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidStringInterpolationOperand(
+ Constant constant) {
+ return new Message(codeConstEvalInvalidStringInterpolationOperand,
+ message:
+ """The '$constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""",
+ arguments: {'constant': constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ Constant constant,
+ DartType _type,
+ DartType
+ _type2)> templateConstEvalInvalidType = const Template<
+ Message Function(Constant constant, DartType _type, DartType _type2)>(
+ messageTemplate:
+ r"""Expected constant '#constant' to be of type '#type', but was of type '#type2'.""",
+ withArguments: _withArgumentsConstEvalInvalidType);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant constant, DartType _type, DartType _type2)>
+ codeConstEvalInvalidType = const Code<
+ Message Function(Constant constant, DartType _type, DartType _type2)>(
+ "ConstEvalInvalidType",
+ templateConstEvalInvalidType,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidType(
+ Constant constant, DartType _type, DartType _type2) {
+ NameSystem nameSystem = new NameSystem();
+ StringBuffer buffer = new StringBuffer();
+ new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
+ String type = '$buffer';
+
+ buffer = new StringBuffer();
+ new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
+ String type2 = '$buffer';
+
+ return new Message(codeConstEvalInvalidType,
+ message:
+ """Expected constant '$constant' to be of type '$type', but was of type '$type2'.""",
+ arguments: {'constant': constant, 'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String
+ string)> templateConstEvalNonConstantLiteral = const Template<
+ Message Function(String string)>(
+ messageTemplate:
+ r"""Can't have a non-constant #string literal within a const context.""",
+ withArguments: _withArgumentsConstEvalNonConstantLiteral);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)> codeConstEvalNonConstantLiteral =
+ const Code<Message Function(String string)>(
+ "ConstEvalNonConstantLiteral", templateConstEvalNonConstantLiteral,
+ analyzerCode: "NON_CONSTANT_DEFAULT_VALUE");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalNonConstantLiteral(String string) {
+ return new Message(codeConstEvalNonConstantLiteral,
+ message:
+ """Can't have a non-constant $string literal within a const context.""",
+ arguments: {'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeConstFactory = messageConstFactory;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2141,7 +2392,7 @@
Read the SDK platform from <file>, which should be in Dill/Kernel IR format
and contain the Dart SDK.
- --target=none|vm|vmcc|vmreify|flutter
+ --target=dart2js|dart2js_server|dart_runner|flutter|flutter_runner|none|vm
Specify the target configuration.
--verify
@@ -2288,6 +2539,26 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeForInLoopExactlyOneVariable =
+ messageForInLoopExactlyOneVariable;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageForInLoopExactlyOneVariable = const MessageCode(
+ "ForInLoopExactlyOneVariable",
+ severity: Severity.error,
+ message: r"""A for-in loop can't have more than one loop variable.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeForInLoopNotAssignable = messageForInLoopNotAssignable;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageForInLoopNotAssignable = const MessageCode(
+ "ForInLoopNotAssignable",
+ severity: Severity.error,
+ message:
+ r"""Can't assign to this, so it can't be used in a for-in loop.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(String name)> templateFunctionHasNoSuchNamedParameter =
const Template<Message Function(String name)>(
@@ -5657,6 +5928,8 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageTypedefNotFunction = const MessageCode(
"TypedefNotFunction",
+ analyzerCode: "INVALID_GENERIC_FUNCTION_TYPE",
+ dart2jsCode: "*fatal*",
message: r"""Can't create typedef from non-function type.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index f23b510..0cfc1d8a 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -8,6 +8,8 @@
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+
import '../api_prototype/file_system.dart' show FileSystemEntity;
import 'package:kernel/kernel.dart'
@@ -75,6 +77,7 @@
Map<Uri, LibraryBuilder> userBuilders;
final Uri initializeFromDillUri;
bool initializedFromDill = false;
+ bool hasToCheckPackageUris = false;
KernelIncrementalTarget userCode;
@@ -93,6 +96,7 @@
if (this.invalidatedUris.contains(c.options.packagesUri)) {
bypassCache = true;
}
+ hasToCheckPackageUris = hasToCheckPackageUris || bypassCache;
UriTranslator uriTranslator =
await c.options.getUriTranslator(bypassCache: bypassCache);
ticker.logMs("Read packages file");
@@ -138,13 +142,18 @@
}
Set<Uri> invalidatedUris = this.invalidatedUris.toSet();
- this.invalidatedUris.clear();
if (fullComponent) {
invalidatedUris.add(entryPoint);
}
- List<LibraryBuilder> reusedLibraries =
- computeReusedLibraries(invalidatedUris, uriTranslator);
+ ClassHierarchy hierarchy = userCode?.loader?.hierarchy;
+ Set<LibraryBuilder> notReusedLibraries;
+ if (hierarchy != null) {
+ notReusedLibraries = new Set<LibraryBuilder>();
+ }
+ List<LibraryBuilder> reusedLibraries = computeReusedLibraries(
+ invalidatedUris, uriTranslator,
+ notReused: notReusedLibraries);
Set<Uri> reusedLibraryUris =
new Set<Uri>.from(reusedLibraries.map((b) => b.uri));
for (Uri uri in new Set<Uri>.from(dillLoadedData.loader.builders.keys)
@@ -153,6 +162,15 @@
userBuilders?.remove(uri);
}
+ if (hierarchy != null) {
+ List<Class> removedClasses = new List<Class>();
+ for (LibraryBuilder builder in notReusedLibraries) {
+ Library lib = builder.target;
+ removedClasses.addAll(lib.classes);
+ }
+ hierarchy.applyTreeChanges(removedClasses, const []);
+ }
+
if (userCode != null) {
ticker.logMs("Decided to reuse ${reusedLibraries.length}"
" of ${userCode.loader.builders.length} libraries");
@@ -170,6 +188,7 @@
dillLoadedData,
uriTranslator,
uriToSource: c.uriToSource);
+ userCode.loader.hierarchy = hierarchy;
for (LibraryBuilder library in reusedLibraries) {
userCode.loader.builders[library.uri] = library;
@@ -201,6 +220,8 @@
libraries: compiledLibraries, uriToSource: <Uri, Source>{});
}
if (componentWithDill != null) {
+ this.invalidatedUris.clear();
+ hasToCheckPackageUris = false;
userCodeOld?.loader?.releaseAncillaryResources();
userCodeOld?.loader?.builders?.clear();
userCodeOld = null;
@@ -217,9 +238,11 @@
List<Library> outputLibraries;
if (data.includeUserLoadedLibraries || fullComponent) {
- outputLibraries = computeTransitiveClosure(
- compiledLibraries, mainMethod, entryPoint, reusedLibraries, data);
+ outputLibraries = computeTransitiveClosure(compiledLibraries,
+ mainMethod, entryPoint, reusedLibraries, data, hierarchy);
} else {
+ computeTransitiveClosure(compiledLibraries, mainMethod, entryPoint,
+ reusedLibraries, data, hierarchy);
outputLibraries = compiledLibraries;
}
@@ -239,7 +262,8 @@
Procedure mainMethod,
Uri entry,
List<LibraryBuilder> reusedLibraries,
- IncrementalCompilerData data) {
+ IncrementalCompilerData data,
+ ClassHierarchy hierarchy) {
List<Library> result = new List<Library>.from(inputLibraries);
Map<Uri, Library> libraryMap = <Uri, Library>{};
for (Library library in inputLibraries) {
@@ -274,10 +298,16 @@
}
}
+ List<Class> removedClasses = new List<Class>();
for (Uri uri in potentiallyReferencedLibraries.keys) {
if (uri.scheme == "package") continue;
- userCode.loader.builders.remove(uri);
+ LibraryBuilder builder = userCode.loader.builders.remove(uri);
+ if (builder != null) {
+ Library lib = builder.target;
+ removedClasses.addAll(lib.classes);
+ }
}
+ hierarchy?.applyTreeChanges(removedClasses, const []);
return result;
}
@@ -360,6 +390,7 @@
String expression,
Map<String, DartType> definitions,
List<TypeParameter> typeDefinitions,
+ String syntheticProcedureName,
Uri libraryUri,
[String className,
bool isStatic = false]) async {
@@ -440,7 +471,7 @@
debugLibrary, className, className != null && !isStatic, parameters);
Procedure procedure = new Procedure(
- new Name("debugExpr"), ProcedureKind.Method, parameters,
+ new Name(syntheticProcedureName), ProcedureKind.Method, parameters,
isStatic: isStatic);
parameters.body = new ReturnStatement(compiledExpression)
@@ -459,11 +490,14 @@
}
List<LibraryBuilder> computeReusedLibraries(
- Set<Uri> invalidatedUris, UriTranslator uriTranslator) {
+ Set<Uri> invalidatedUris, UriTranslator uriTranslator,
+ {Set<LibraryBuilder> notReused}) {
if (userCode == null && userBuilders == null) {
return <LibraryBuilder>[];
}
+ List<LibraryBuilder> result = <LibraryBuilder>[];
+
// Maps all non-platform LibraryBuilders from their import URI.
Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
@@ -476,7 +510,8 @@
(importUri != fileUri && invalidatedUris.contains(fileUri))) {
return true;
}
- if (importUri.scheme == "package" &&
+ if (hasToCheckPackageUris &&
+ importUri.scheme == "package" &&
uriTranslator.translate(importUri, false) != fileUri) {
return true;
}
@@ -484,6 +519,10 @@
}
addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library) {
+ if (uri.scheme == "dart") {
+ result.add(library);
+ return;
+ }
builders[uri] = library;
if (isInvalidated(uri, library.target.fileUri)) {
invalidatedImportUris.add(uri);
@@ -547,13 +586,13 @@
workList.add(dependency);
}
}
+ notReused?.add(current);
}
}
// Builders contain mappings from part uri to builder, meaning the same
// builder can exist multiple times in the values list.
Set<Uri> seenUris = new Set<Uri>();
- List<LibraryBuilder> result = <LibraryBuilder>[];
for (LibraryBuilder builder in builders.values) {
if (builder.isPart) continue;
// TODO(jensj/ahe): This line can probably go away once
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 252270f..66003ca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -12,10 +12,30 @@
import '../fasta_codes.dart' show LocatedMessage, Message, noLength, Template;
+import 'forest.dart' show Forest;
+
import '../messages.dart' as messages show getLocationFromUri;
import '../modifier.dart' show Modifier, constMask, covariantMask, finalMask;
+import '../names.dart'
+ show
+ ampersandName,
+ barName,
+ callName,
+ caretName,
+ divisionName,
+ emptyName,
+ indexGetName,
+ indexSetName,
+ leftShiftName,
+ minusName,
+ multiplyName,
+ mustacheName,
+ percentName,
+ plusName,
+ rightShiftName;
+
import '../parser.dart'
show
Assert,
@@ -62,7 +82,32 @@
import 'constness.dart' show Constness;
-import 'frontend_accessors.dart' show buildIsNull;
+import 'expression_generator.dart'
+ show
+ BuilderHelper,
+ CalleeDesignation,
+ DeferredAccessGenerator,
+ ErroneousExpressionGenerator,
+ FastaAccessor,
+ FunctionTypeAccessor,
+ GeneratorImpl,
+ IncompleteError,
+ IncompletePropertyAccessor,
+ IncompleteSend,
+ IndexedAccessGenerator,
+ LargeIntAccessGenerator,
+ LoadLibraryGenerator,
+ ParenthesizedExpression,
+ ReadOnlyAccessGenerator,
+ SendAccessor,
+ StaticAccessGenerator,
+ SuperIndexedAccessGenerator,
+ ThisAccessGenerator,
+ ThisPropertyAccessGenerator,
+ TypeDeclarationAccessor,
+ UnresolvedAccessor,
+ VariableUseGenerator,
+ buildIsNull;
import 'redirecting_factory_body.dart'
show
@@ -71,10 +116,6 @@
getRedirectingFactoryBody,
getRedirectionTarget;
-import '../names.dart';
-
-import 'fasta_accessors.dart';
-
import 'kernel_api.dart';
import 'kernel_ast_api.dart' hide Expression, Statement;
@@ -83,6 +124,8 @@
import 'kernel_builder.dart';
+import 'type_algorithms.dart' show calculateBounds;
+
// TODO(ahe): Remove this and ensure all nodes have a location.
const noLocation = null;
@@ -201,8 +244,8 @@
ignoreMainInGetMainClosure = library.uri.scheme == 'dart' &&
(library.uri.path == "_builtin" || library.uri.path == "ui"),
needsImplicitSuperInitializer =
- coreTypes.objectClass != classBuilder?.cls,
- typePromoter = _typeInferrer.typePromoter,
+ coreTypes?.objectClass != classBuilder?.cls,
+ typePromoter = _typeInferrer?.typePromoter,
super(scope);
bool get hasParserError => recoverableErrors.isNotEmpty;
@@ -271,39 +314,18 @@
return list;
}
- Block popBlock(int count, Token beginToken) {
- List<dynamic /*kernel.Statement | List<kernel.Statement>*/ > statements =
- popList(count) ?? <kernel.Statement>[];
- List<kernel.Statement> copy;
- for (int i = 0; i < statements.length; i++) {
- var statement = statements[i];
- if (statement is List) {
- copy ??= new List<kernel.Statement>.from(statements.getRange(0, i));
- // TODO(sigmund): remove this assignment (issue #28651)
- Iterable subStatements = statement;
- copy.addAll(subStatements);
- } else if (copy != null) {
- copy.add(statement);
- }
- }
- return new ShadowBlock(copy ?? statements)
- ..fileOffset = offsetForToken(beginToken);
+ Statement popBlock(int count, Token openBrace, Token closeBrace) {
+ List<Statement> statements =
+ new List<Statement>.filled(count, null, growable: true);
+ popList(count, statements);
+ return forest.block(openBrace, statements, closeBrace);
}
- kernel.Statement popStatementIfNotNull(Object value) {
+ Statement popStatementIfNotNull(Object value) {
return value == null ? null : popStatement();
}
- kernel.Statement popStatement() {
- var statement = pop();
- if (statement is List) {
- return new Block(new List<kernel.Statement>.from(statement));
- } else if (statement is VariableDeclaration) {
- return new Block(<kernel.Statement>[statement]);
- } else {
- return statement;
- }
- }
+ Statement popStatement() => forest.wrapVariables(pop());
void ignore(Unhandled value) {
pop();
@@ -388,7 +410,8 @@
@override
JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) {
- return new JumpTarget(kind, functionNestingLevel, member, charOffset);
+ return new JumpTarget<Statement>(
+ kind, functionNestingLevel, member, charOffset);
}
@override
@@ -415,7 +438,7 @@
if (expression is Identifier) {
Identifier identifier = expression;
expression = new UnresolvedAccessor(
- this, new Name(identifier.name, library.library), identifier.token);
+ this, identifier.token, new Name(identifier.name, library.library));
}
if (name?.isNotEmpty ?? false) {
Token period = periodBeforeName ?? beginToken.next;
@@ -428,7 +451,7 @@
}
ConstantContext savedConstantContext = pop();
- if (expression is! StaticAccessor) {
+ if (expression is! StaticAccessGenerator) {
push(wrapInCompileTimeError(
toValue(expression), fasta.messageExpressionNotMetadata));
} else {
@@ -512,13 +535,13 @@
}
@override
- void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
+ void endBlockFunctionBody(int count, Token openBrace, Token closeBrace) {
debugEvent("BlockFunctionBody");
- if (beginToken == null) {
+ if (openBrace == null) {
assert(count == 0);
push(NullValue.Block);
} else {
- Block block = popBlock(count, beginToken);
+ Statement block = popBlock(count, openBrace, closeBrace);
exitLocalScope();
push(block);
}
@@ -633,7 +656,7 @@
}
@override
- void finishFunction(List annotations, FormalParameters formals,
+ void finishFunction(List annotations, FormalParameters<Arguments> formals,
AsyncMarker asyncModifier, kernel.Statement body) {
debugEvent("finishFunction");
typePromoter.finished();
@@ -673,18 +696,23 @@
if (builder.formals != null) {
// Illegal parameters were removed by the function builder.
// Add them as local variable to put them in scope of the body.
- List<kernel.Statement> statements = <kernel.Statement>[];
+ List<Statement> statements = <Statement>[];
for (KernelFormalParameterBuilder parameter in builder.formals) {
- statements.add(parameter.target);
+ statements.add(toStatement(parameter.target));
}
- statements.add(body);
- body = new Block(statements)..fileOffset = charOffset;
+ statements.add(toStatement(body));
+ body = toKernelStatement(
+ storeOffset(forest.block(null, statements, null), charOffset));
}
body = wrapInCompileTimeErrorStatement(
body, fasta.messageSetterWithWrongNumberOfFormals);
}
}
- if (!builder.isExternal) {
+ // No-such-method forwarders get their bodies injected during outline
+ // buliding, so we should skip them here.
+ bool isNoSuchMethodForwarder = (builder.function.parent is Procedure &&
+ (builder.function.parent as Procedure).isNoSuchMethodForwarder);
+ if (!builder.isExternal && !isNoSuchMethodForwarder) {
builder.body = body;
} else {
if (body != null) {
@@ -727,7 +755,8 @@
enterLocalScope(
null,
- new FormalParameters(parameters.positionalParameters, null, -1)
+ new FormalParameters<Arguments>(
+ parameters.positionalParameters, null, -1)
.computeFormalParameterScope(scope, member, this));
token = parser.parseExpression(parser.syntheticPreviousToken(token));
@@ -806,7 +835,7 @@
@override
void endExpressionStatement(Token token) {
debugEvent("ExpressionStatement");
- push(new ShadowExpressionStatement(toKernelExpression(popForEffect())));
+ push(forest.expressionStatement(popForEffect(), token));
}
@override
@@ -872,10 +901,16 @@
}
@override
+ void handleParenthesizedCondition(Token token) {
+ debugEvent("ParenthesizedCondition");
+ push(forest.parenthesizedCondition(token, popForValue(), token.endGroup));
+ }
+
+ @override
void handleParenthesizedExpression(Token token) {
debugEvent("ParenthesizedExpression");
push(new ParenthesizedExpression(
- this, toKernelExpression(popForValue()), token.endGroup));
+ this, token.endGroup, toKernelExpression(popForValue())));
}
@override
@@ -921,13 +956,13 @@
Expression expression = popForValue();
if (expression is ShadowCascadeExpression) {
push(expression);
- push(new VariableAccessor(this, token, expression.variable));
+ push(new VariableUseGenerator(this, token, expression.variable));
expression.extend();
} else {
VariableDeclaration variable = new ShadowVariableDeclaration.forValue(
toKernelExpression(expression), functionNestingLevel);
push(new ShadowCascadeExpression(variable));
- push(new VariableAccessor(this, token, variable));
+ push(new VariableUseGenerator(this, token, variable));
}
}
@@ -979,8 +1014,8 @@
Expression argument = popForValue();
var receiver = pop();
bool isSuper = false;
- if (receiver is ThisAccessor && receiver.isSuper) {
- ThisAccessor thisAccessorReceiver = receiver;
+ if (receiver is ThisAccessGenerator && receiver.isSuper) {
+ ThisAccessGenerator thisAccessorReceiver = receiver;
isSuper = true;
receiver = forest.thisExpression(thisAccessorReceiver.token);
}
@@ -1030,11 +1065,13 @@
new VariableDeclaration.forValue(toKernelExpression(a));
push(new ShadowIfNullExpression(
variable,
- new ConditionalExpression(
- buildIsNull(new VariableGet(variable), offsetForToken(token)),
- toKernelExpression(b),
- new VariableGet(variable),
- null))
+ toKernelExpression(forest.conditionalExpression(
+ toExpression(buildIsNull(
+ new VariableGet(variable), offsetForToken(token), this)),
+ token,
+ b,
+ null,
+ toExpression(new VariableGet(variable)))))
..fileOffset = offsetForToken(token));
}
@@ -1319,8 +1356,8 @@
/// Look up [name] in [scope] using [token] as location information (both to
/// report problems and as the file offset in the generated kernel code).
- /// [isQualified] should be true if [name] is a qualified access
- /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor]
+ /// [isQualified] should be true if [name] is a qualified access (which
+ /// implies that it shouldn't be turned into a [ThisPropertyAccessGenerator]
/// if the name doesn't resolve in the scope).
@override
scopeLookup(Scope scope, String name, Token token,
@@ -1341,16 +1378,16 @@
if (!isQualified && isInstanceContext) {
assert(builder == null);
if (constantContext != ConstantContext.none || member.isField) {
- return new UnresolvedAccessor(this, n, token);
+ return new UnresolvedAccessor(this, token, n);
}
- return new ThisPropertyAccessor(this, token, n, lookupInstanceMember(n),
- lookupInstanceMember(n, isSetter: true));
+ return new ThisPropertyAccessGenerator(this, token, n,
+ lookupInstanceMember(n), lookupInstanceMember(n, isSetter: true));
} else if (ignoreMainInGetMainClosure &&
name == "main" &&
member?.name == "_getMainClosure") {
return storeOffset(forest.literalNull(null), charOffset);
} else {
- return new UnresolvedAccessor(this, n, token);
+ return new UnresolvedAccessor(this, token, n);
}
} else if (builder.isTypeDeclaration) {
if (constantContext != ConstantContext.none &&
@@ -1360,9 +1397,9 @@
charOffset, "Not a constant expression.");
}
TypeDeclarationAccessor accessor = new TypeDeclarationAccessor(
- this, prefix, charOffset, builder, name, token);
+ this, token, prefix, charOffset, builder, name);
return (prefix?.deferred == true)
- ? new DeferredAccessor(this, token, prefix, accessor)
+ ? new DeferredAccessGenerator(this, token, prefix, accessor)
: accessor;
} else if (builder.isLocal) {
if (constantContext != ConstantContext.none &&
@@ -1374,19 +1411,19 @@
// An initializing formal parameter might be final without its
// VariableDeclaration being final. See
// [ProcedureBuilder.computeFormalParameterInitializerScope]. If that
- // wasn't the case, we could always use VariableAccessor.
+ // wasn't the case, we could always use [VariableUseGenerator].
if (builder.isFinal) {
var fact =
typePromoter.getFactForAccess(builder.target, functionNestingLevel);
var scope = typePromoter.currentScope;
- return new ReadOnlyAccessor(
+ return new ReadOnlyAccessGenerator(
this,
+ token,
new ShadowVariableGet(builder.target, fact, scope)
..fileOffset = charOffset,
- name,
- token);
+ name);
} else {
- return new VariableAccessor(this, token, builder.target);
+ return new VariableUseGenerator(this, token, builder.target);
}
} else if (builder.isInstanceMember) {
if (constantContext != ConstantContext.none &&
@@ -1409,13 +1446,13 @@
getter = builder.target;
setter = lookupInstanceMember(n, isSetter: true);
}
- return new ThisPropertyAccessor(this, token, n, getter, setter);
+ return new ThisPropertyAccessGenerator(this, token, n, getter, setter);
} else if (builder.isRegularMethod) {
assert(builder.isStatic || builder.isTopLevel);
- StaticAccessor accessor =
- new StaticAccessor(this, token, builder.target, null);
+ StaticAccessGenerator accessor =
+ new StaticAccessGenerator(this, token, builder.target, null);
return (prefix?.deferred == true)
- ? new DeferredAccessor(this, token, prefix, accessor)
+ ? new DeferredAccessGenerator(this, token, prefix, accessor)
: accessor;
} else if (builder is PrefixBuilder) {
if (constantContext != ConstantContext.none && builder.deferred) {
@@ -1429,7 +1466,7 @@
}
return builder;
} else if (builder is LoadLibraryBuilder) {
- return new LoadLibraryAccessor(this, token, builder);
+ return new LoadLibraryGenerator(this, token, builder);
} else {
if (builder.hasProblem && builder is! AccessErrorBuilder) return builder;
Builder setter;
@@ -1440,8 +1477,8 @@
} else if (builder.isField && !builder.isFinal) {
setter = builder;
}
- StaticAccessor accessor =
- new StaticAccessor.fromBuilder(this, builder, token, setter);
+ StaticAccessGenerator accessor =
+ new StaticAccessGenerator.fromBuilder(this, builder, token, setter);
if (constantContext != ConstantContext.none) {
Member readTarget = accessor.readTarget;
if (!(readTarget is Field && readTarget.isConst ||
@@ -1452,7 +1489,7 @@
}
}
return (prefix?.deferred == true)
- ? new DeferredAccessor(this, token, prefix, accessor)
+ ? new DeferredAccessGenerator(this, token, prefix, accessor)
: accessor;
}
}
@@ -1561,7 +1598,7 @@
debugEvent("LiteralInt");
int value = int.parse(token.lexeme, onError: (_) => null);
if (value == null) {
- push(new LargeIntAccessor(this, token));
+ push(new LargeIntAccessGenerator(this, token));
} else {
push(forest.literalInt(value, token));
}
@@ -1588,15 +1625,14 @@
push(deprecated_buildCompileTimeErrorStatement(
"Can't return from a constructor.", beginToken.charOffset));
} else {
- push(new ShadowReturnStatement(toKernelExpression(expression))
- ..fileOffset = beginToken.charOffset);
+ push(forest.returnStatement(beginToken, expression, endToken));
}
}
@override
void beginThenStatement(Token token) {
Expression condition = popForValue();
- typePromoter.enterThen(toKernelExpression(condition));
+ enterThenForTypePromotion(condition);
push(condition);
super.beginThenStatement(token);
}
@@ -1609,13 +1645,11 @@
@override
void endIfStatement(Token ifToken, Token elseToken) {
- kernel.Statement elsePart = popStatementIfNotNull(elseToken);
- kernel.Statement thenPart = popStatement();
+ Statement elsePart = popStatementIfNotNull(elseToken);
+ Statement thenPart = popStatement();
Expression condition = pop();
typePromoter.exitConditional();
- push(
- new ShadowIfStatement(toKernelExpression(condition), thenPart, elsePart)
- ..fileOffset = ifToken.charOffset);
+ push(forest.ifStatement(ifToken, condition, thenPart, elseToken, elsePart));
}
@override
@@ -1707,29 +1741,40 @@
@override
void endVariablesDeclaration(int count, Token endToken) {
debugEvent("VariablesDeclaration");
- List<VariableDeclaration> variables = popList(count);
- constantContext = pop();
- currentLocalVariableType = pop();
- currentLocalVariableModifiers = pop();
- List<Expression> annotations = pop();
- if (annotations != null) {
- for (VariableDeclaration variable in variables) {
+ if (count == 1) {
+ VariableDeclaration variable = pop();
+ constantContext = pop();
+ currentLocalVariableType = pop();
+ currentLocalVariableModifiers = pop();
+ List<Expression> annotations = pop();
+ if (annotations != null) {
for (Expression annotation in annotations) {
variable.addAnnotation(toKernelExpression(annotation));
}
}
- }
- if (variables.length != 1) {
- push(variables);
+ push(variable);
} else {
- push(variables.single);
+ List<VariableDeclaration> variables = popList(count,
+ new List<VariableDeclaration>.filled(count, null, growable: true));
+ constantContext = pop();
+ currentLocalVariableType = pop();
+ currentLocalVariableModifiers = pop();
+ List<Expression> annotations = pop();
+ if (annotations != null) {
+ for (VariableDeclaration variable in variables) {
+ for (Expression annotation in annotations) {
+ variable.addAnnotation(toKernelExpression(annotation));
+ }
+ }
+ }
+ push(forest.variablesDeclaration(variables, uri));
}
}
@override
- void endBlock(int count, Token beginToken, Token endToken) {
+ void endBlock(int count, Token openBrace, Token closeBrace) {
debugEvent("Block");
- Block block = popBlock(count, beginToken);
+ Statement block = popBlock(count, openBrace, closeBrace);
exitLocalScope();
push(block);
}
@@ -1766,7 +1811,7 @@
}
}
- void exitLoopOrSwitch(kernel.Statement statement) {
+ void exitLoopOrSwitch(Statement statement) {
if (compileTimeErrorInLoopOrSwitch != null) {
push(compileTimeErrorInLoopOrSwitch);
compileTimeErrorInLoopOrSwitch = null;
@@ -1781,14 +1826,6 @@
}
if (variableOrExpression is VariableDeclaration) {
return <VariableDeclaration>[variableOrExpression];
- } else if (variableOrExpression is List) {
- List<VariableDeclaration> variables = <VariableDeclaration>[];
- for (var v in variableOrExpression) {
- variables.addAll(buildVariableDeclarations(v));
- }
- return variables;
- } else if (variableOrExpression == null) {
- return <VariableDeclaration>[];
} else if (variableOrExpression is Expression) {
VariableDeclaration variable = new ShadowVariableDeclaration.forEffect(
toKernelExpression(variableOrExpression), functionNestingLevel);
@@ -1797,6 +1834,17 @@
VariableDeclaration variable = new ShadowVariableDeclaration.forEffect(
variableOrExpression.expression, functionNestingLevel);
return <VariableDeclaration>[variable];
+ } else if (forest.isVariablesDeclaration(variableOrExpression)) {
+ return forest
+ .variablesDeclarationExtractDeclarations(variableOrExpression);
+ } else if (variableOrExpression is List) {
+ List<VariableDeclaration> variables = <VariableDeclaration>[];
+ for (var v in variableOrExpression) {
+ variables.addAll(buildVariableDeclarations(v));
+ }
+ return variables;
+ } else if (variableOrExpression == null) {
+ return <VariableDeclaration>[];
}
return null;
}
@@ -1805,14 +1853,16 @@
void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
int updateExpressionCount, Token endToken) {
debugEvent("ForStatement");
- kernel.Statement body = popStatement();
+ Statement body = popStatement();
List<Expression> updates = popListForEffect(updateExpressionCount);
- kernel.Statement conditionStatement = popStatement();
+ Statement conditionStatement = popStatement();
+ kernel.Statement kernelConditionStatement =
+ toKernelStatement(conditionStatement);
Expression condition = null;
- if (conditionStatement is ExpressionStatement) {
- condition = toExpression(conditionStatement.expression);
+ if (kernelConditionStatement is ExpressionStatement) {
+ condition = toExpression(kernelConditionStatement.expression);
} else {
- assert(conditionStatement is EmptyStatement);
+ assert(kernelConditionStatement is EmptyStatement);
}
dynamic variableOrExpression = pop();
List<VariableDeclaration> variables =
@@ -1824,18 +1874,22 @@
exitLocalScope();
JumpTarget continueTarget = exitContinueTarget();
JumpTarget breakTarget = exitBreakTarget();
+ kernel.Statement kernelBody = toKernelStatement(body);
if (continueTarget.hasUsers) {
- body = new ShadowLabeledStatement(body);
- continueTarget.resolveContinues(body);
+ kernelBody = new ShadowLabeledStatement(kernelBody);
+ continueTarget.resolveContinues(forest, kernelBody);
}
- kernel.Statement result = new ShadowForStatement(variables,
- toKernelExpression(condition), toKernelExpressionList(updates), body)
+ kernel.Statement result = new ShadowForStatement(
+ variables,
+ toKernelExpression(condition),
+ toKernelExpressionList(updates),
+ kernelBody)
..fileOffset = forKeyword.charOffset;
if (breakTarget.hasUsers) {
result = new ShadowLabeledStatement(result);
- breakTarget.resolveBreaks(result);
+ breakTarget.resolveBreaks(forest, result);
}
- exitLoopOrSwitch(result);
+ exitLoopOrSwitch(toStatement(result));
}
@override
@@ -1960,15 +2014,18 @@
debugEvent("LiteralSymbol");
String value;
if (identifierCount == 1) {
- value = symbolPartToString(pop());
+ Object part = pop();
+ value = symbolPartToString(part);
+ push(forest.literalSymbolSingluar(value, hashToken, part));
} else {
- List parts = popList(identifierCount);
+ List<Identifier> parts = popList(identifierCount,
+ new List<Identifier>.filled(identifierCount, null, growable: true));
value = symbolPartToString(parts.first);
for (int i = 1; i < parts.length; i++) {
value += ".${symbolPartToString(parts[i])}";
}
+ push(forest.literalSymbolMultiple(value, hashToken, parts));
}
- push(forest.literalSymbol(value, hashToken));
}
@override
@@ -1986,7 +2043,7 @@
if (prefix is PrefixBuilder) {
name = scopeLookup(prefix.exportScope, suffix.name, beginToken,
isQualified: true, prefix: prefix);
- } else if (prefix is ErrorAccessor) {
+ } else if (prefix is ErroneousExpressionGenerator) {
push(prefix.buildErroneousTypeNotAPrefix(suffix));
return;
} else {
@@ -2041,7 +2098,7 @@
@override
void endFunctionType(Token functionToken, Token endToken) {
debugEvent("FunctionType");
- FormalParameters formals = pop();
+ FormalParameters<Arguments> formals = pop();
DartType returnType = pop();
List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
FunctionType type = formals.toFunctionType(returnType, typeVariables);
@@ -2121,9 +2178,10 @@
if (constantContext != ConstantContext.none) {
push(deprecated_buildCompileTimeError(
"Not a constant expression.", throwToken.charOffset));
+ // TODO(brianwilkerson): For analyzer, we need to produce the error above
+ // but then we need to produce the AST as in the `else` clause below.
} else {
- push(new ShadowThrow(toKernelExpression(expression))
- ..fileOffset = offsetForToken(throwToken));
+ push(forest.throwExpression(throwToken, expression));
}
}
@@ -2214,7 +2272,7 @@
if (inCatchClause || functionNestingLevel != 0) {
exitLocalScope();
}
- FormalParameters formals = pop();
+ FormalParameters<Arguments> formals = pop();
DartType returnType = pop();
List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
FunctionType type = formals.toFunctionType(returnType, typeVariables);
@@ -2266,8 +2324,12 @@
optional = pop();
count--;
}
- FormalParameters formals = new FormalParameters(
- popList(count) ?? <VariableDeclaration>[],
+ FormalParameters<Arguments> formals = new FormalParameters(
+ popList(
+ count,
+ new List<VariableDeclaration>.filled(count, null,
+ growable: true)) ??
+ <VariableDeclaration>[],
optional,
beginToken.charOffset);
constantContext = pop();
@@ -2303,7 +2365,7 @@
if (catchKeyword != null) {
exitLocalScope();
}
- FormalParameters catchParameters = popIfNotNull(catchKeyword);
+ FormalParameters<Arguments> catchParameters = popIfNotNull(catchKeyword);
DartType type = popIfNotNull(onKeyword) ?? const DynamicType();
VariableDeclaration exception;
VariableDeclaration stackTrace;
@@ -2318,10 +2380,14 @@
}
if (catchParameters.required.length > 2 ||
catchParameters.optional != null) {
- body = new Block(<kernel.Statement>[
- compileTimeErrorInTry ??= deprecated_buildCompileTimeErrorStatement(
- "Invalid catch arguments.", catchKeyword.next.charOffset)
- ]);
+ body = toKernelStatement(forest.block(
+ catchKeyword,
+ <Statement>[
+ toStatement(compileTimeErrorInTry ??=
+ deprecated_buildCompileTimeErrorStatement(
+ "Invalid catch arguments.", catchKeyword.next.charOffset))
+ ],
+ null));
}
}
push(new Catch(exception, body, guard: type, stackTrace: stackTrace)
@@ -2330,17 +2396,12 @@
@override
void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
- kernel.Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
- List<Catch> catches = popList(catchCount);
- kernel.Statement tryBlock = popStatement();
+ Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
+ Object catches = popList(catchCount);
+ Statement tryBlock = popStatement();
if (compileTimeErrorInTry == null) {
- if (catches != null) {
- tryBlock = new ShadowTryCatch(tryBlock, catches);
- }
- if (finallyBlock != null) {
- tryBlock = new ShadowTryFinally(tryBlock, finallyBlock);
- }
- push(tryBlock);
+ push(forest.tryStatement(
+ tryKeyword, tryBlock, catches, finallyKeyword, finallyBlock));
} else {
push(compileTimeErrorInTry);
compileTimeErrorInTry = null;
@@ -2359,15 +2420,15 @@
debugEvent("IndexedExpression");
Expression index = popForValue();
var receiver = pop();
- if (receiver is ThisAccessor && receiver.isSuper) {
- push(new SuperIndexAccessor(
+ if (receiver is ThisAccessGenerator && receiver.isSuper) {
+ push(new SuperIndexedAccessGenerator(
this,
openSquareBracket,
toKernelExpression(index),
lookupInstanceMember(indexGetName, isSuper: true),
lookupInstanceMember(indexSetName, isSuper: true)));
} else {
- push(IndexAccessor.make(
+ push(IndexedAccessGenerator.make<Arguments>(
this,
openSquareBracket,
toKernelExpression(toValue(receiver)),
@@ -2388,7 +2449,7 @@
if (optional("-", token)) {
operator = "unary-";
- if (receiver is LargeIntAccessor) {
+ if (receiver is LargeIntAccessGenerator) {
int value =
int.parse("-" + receiver.token.lexeme, onError: (_) => null);
if (value != null) {
@@ -2399,7 +2460,7 @@
}
bool isSuper = false;
Expression receiverValue;
- if (receiver is ThisAccessor && receiver.isSuper) {
+ if (receiver is ThisAccessGenerator && receiver.isSuper) {
isSuper = true;
receiverValue = forest.thisExpression(receiver.token);
} else {
@@ -2437,7 +2498,7 @@
debugEvent("UnaryPostfixAssignmentExpression");
var accessor = pop();
if (accessor is FastaAccessor) {
- push(new DelayedPostfixIncrement(
+ push(new DelayedPostfixIncrement<Arguments>(
this, token, accessor, incrementOperator(token), null));
} else {
push(wrapInCompileTimeError(toValue(accessor), fasta.messageNotAnLvalue));
@@ -2504,7 +2565,7 @@
? "${prefix.plainNameForRead}.${identifier.name}"
: "${prefix.plainNameForRead}.${identifier.name}.$suffix";
type = new UnresolvedAccessor(
- this, new Name(name, library.library), prefix.token);
+ this, prefix.token, new Name(name, library.library));
} else {
unhandled("${prefix.runtimeType}", "pushQualifiedReference",
start.charOffset, uri);
@@ -2725,8 +2786,8 @@
var type = pop();
PrefixBuilder deferredPrefix;
int checkOffset;
- if (type is DeferredAccessor) {
- DeferredAccessor accessor = type;
+ if (type is DeferredAccessGenerator) {
+ DeferredAccessGenerator accessor = type;
type = accessor.accessor;
deferredPrefix = accessor.builder;
checkOffset = accessor.token.charOffset;
@@ -2747,7 +2808,7 @@
push(deferredPrefix != null
? wrapInDeferredCheck(expression, deferredPrefix, checkOffset)
: expression);
- } else if (type is ErrorAccessor) {
+ } else if (type is ErroneousExpressionGenerator) {
push(type.buildError(arguments));
} else {
push(throwNoSuchMethodError(storeOffset(forest.literalNull(null), offset),
@@ -2877,7 +2938,7 @@
void handleThisExpression(Token token, IdentifierContext context) {
debugEvent("ThisExpression");
if (context.isScopeReference && isInstanceContext) {
- push(new ThisAccessor(this, token, inInitializer));
+ push(new ThisAccessGenerator(this, token, inInitializer));
} else {
push(new IncompleteError(this, token, fasta.messageThisAsIdentifier));
}
@@ -2889,7 +2950,7 @@
if (context.isScopeReference && isInstanceContext) {
Member member = this.member.target;
member.transformerFlags |= TransformerFlag.superCalls;
- push(new ThisAccessor(this, token, inInitializer, isSuper: true));
+ push(new ThisAccessGenerator(this, token, inInitializer, isSuper: true));
} else {
push(new IncompleteError(this, token, fasta.messageSuperAsIdentifier));
}
@@ -2967,10 +3028,10 @@
}
void pushNamedFunction(Token token, bool isFunctionExpression) {
- kernel.Statement body = popStatement();
+ Statement body = popStatement();
AsyncMarker asyncModifier = pop();
exitLocalScope();
- FormalParameters formals = pop();
+ FormalParameters<Arguments> formals = pop();
var declaration = pop();
var returnType = pop();
var hasImplicitReturnType = returnType == null;
@@ -2981,7 +3042,8 @@
if (!isFunctionExpression) {
annotations = pop(); // Metadata.
}
- FunctionNode function = formals.addToFunction(new FunctionNode(body,
+ FunctionNode function = formals.addToFunction(new FunctionNode(
+ toKernelStatement(body),
typeParameters: typeParameters,
asyncMarker: asyncModifier,
returnType: returnType)
@@ -3027,11 +3089,16 @@
// This must have been a compile-time error.
assert(isErroneousNode(variable.initializer));
- push(new Block(<kernel.Statement>[
- new ExpressionStatement(variable.initializer),
- declaration
- ])
- ..fileOffset = declaration.fileOffset);
+ push(storeOffset(
+ forest.block(
+ null,
+ <Statement>[
+ forest.expressionStatement(
+ toExpression(variable.initializer), token),
+ toStatement(declaration)
+ ],
+ null),
+ declaration.fileOffset));
variable.initializer = null;
} else {
push(declaration);
@@ -3058,14 +3125,16 @@
@override
void endFunctionExpression(Token beginToken, Token token) {
debugEvent("FunctionExpression");
- kernel.Statement body = popStatement();
+ Statement body = popStatement();
AsyncMarker asyncModifier = pop();
exitLocalScope();
- FormalParameters formals = pop();
+ FormalParameters<Arguments> formals = pop();
exitFunction();
List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
- FunctionNode function = formals.addToFunction(new FunctionNode(body,
- typeParameters: typeParameters, asyncMarker: asyncModifier)
+ FunctionNode function = formals.addToFunction(new FunctionNode(
+ toKernelStatement(body),
+ typeParameters: typeParameters,
+ asyncMarker: asyncModifier)
..fileOffset = beginToken.charOffset
..fileEndOffset = token.charOffset);
if (constantContext != ConstantContext.none) {
@@ -3082,19 +3151,18 @@
Token doKeyword, Token whileKeyword, Token endToken) {
debugEvent("DoWhileStatement");
Expression condition = popForValue();
- kernel.Statement body = popStatement();
+ Statement body = popStatement();
JumpTarget continueTarget = exitContinueTarget();
JumpTarget breakTarget = exitBreakTarget();
if (continueTarget.hasUsers) {
- body = new ShadowLabeledStatement(body);
- continueTarget.resolveContinues(body);
+ body = forest.syntheticLabeledStatement(body);
+ continueTarget.resolveContinues(forest, body);
}
- kernel.Statement result =
- new ShadowDoStatement(body, toKernelExpression(condition))
- ..fileOffset = doKeyword.charOffset;
+ Statement result =
+ forest.doStatement(doKeyword, body, whileKeyword, condition, endToken);
if (breakTarget.hasUsers) {
- result = new ShadowLabeledStatement(result);
- breakTarget.resolveBreaks(result);
+ result = forest.syntheticLabeledStatement(result);
+ breakTarget.resolveBreaks(forest, result);
}
exitLoopOrSwitch(result);
}
@@ -3116,15 +3184,16 @@
void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
Token inKeyword, Token endToken) {
debugEvent("ForIn");
- kernel.Statement body = popStatement();
+ Statement body = popStatement();
Expression expression = popForValue();
var lvalue = pop();
exitLocalScope();
JumpTarget continueTarget = exitContinueTarget();
JumpTarget breakTarget = exitBreakTarget();
+ kernel.Statement kernelBody = toKernelStatement(body);
if (continueTarget.hasUsers) {
- body = new ShadowLabeledStatement(body);
- continueTarget.resolveContinues(body);
+ kernelBody = new ShadowLabeledStatement(kernelBody);
+ continueTarget.resolveContinues(forest, kernelBody);
}
VariableDeclaration variable;
bool declaresVariable = false;
@@ -3155,27 +3224,31 @@
new ShadowVariableGet(variable, fact, scope)
..fileOffset = inKeyword.offset,
voidContext: true);
- body = combineStatements(
- new ShadowLoopAssignmentStatement(syntheticAssignment), body);
+ kernelBody = combineStatements(
+ new ShadowLoopAssignmentStatement(syntheticAssignment), kernelBody);
} else {
+ Message message = forest.isVariablesDeclaration(lvalue)
+ ? fasta.messageForInLoopExactlyOneVariable
+ : fasta.messageForInLoopNotAssignable;
+ Token token = forToken.next.next;
variable = new VariableDeclaration.forValue(toKernelExpression(
- deprecated_buildCompileTimeError("Expected lvalue, but got ${lvalue}",
- forToken.next.next.charOffset)));
+ buildCompileTimeError(
+ message, offsetForToken(token), lengthForToken(token))));
}
kernel.Statement result = new ShadowForInStatement(
variable,
toKernelExpression(expression),
- body,
+ kernelBody,
declaresVariable,
syntheticAssignment,
isAsync: awaitToken != null)
..fileOffset = awaitToken?.charOffset ?? forToken.charOffset
- ..bodyOffset = body.fileOffset;
+ ..bodyOffset = kernelBody.fileOffset;
if (breakTarget.hasUsers) {
result = new ShadowLabeledStatement(result);
- breakTarget.resolveBreaks(result);
+ breakTarget.resolveBreaks(forest, result);
}
- exitLoopOrSwitch(result);
+ exitLoopOrSwitch(toStatement(result));
}
@override
@@ -3190,8 +3263,8 @@
debugEvent("beginLabeledStatement");
List<Label> labels = popList(labelCount);
enterLocalScope(null, scope.createNestedLabelScope());
- LabelTarget target =
- new LabelTarget(member, functionNestingLevel, token.charOffset);
+ LabelTarget target = new LabelTarget<Statement>(
+ member, functionNestingLevel, token.charOffset);
for (Label label in labels) {
scope.declareLabel(label.name, target);
}
@@ -3201,30 +3274,30 @@
@override
void endLabeledStatement(int labelCount) {
debugEvent("LabeledStatement");
- kernel.Statement statement = popStatement();
+ Statement statement = popStatement();
LabelTarget target = pop();
exitLocalScope();
+ kernel.Statement kernelStatement = toKernelStatement(statement);
if (target.breakTarget.hasUsers) {
- if (statement is! LabeledStatement) {
- statement = new ShadowLabeledStatement(statement);
+ if (kernelStatement is! LabeledStatement) {
+ kernelStatement = new ShadowLabeledStatement(kernelStatement);
}
- target.breakTarget.resolveBreaks(statement);
+ target.breakTarget.resolveBreaks(forest, kernelStatement);
}
if (target.continueTarget.hasUsers) {
- if (statement is! LabeledStatement) {
- statement = new ShadowLabeledStatement(statement);
+ if (kernelStatement is! LabeledStatement) {
+ kernelStatement = new ShadowLabeledStatement(kernelStatement);
}
- target.continueTarget.resolveContinues(statement);
+ target.continueTarget.resolveContinues(forest, kernelStatement);
}
- push(statement);
+ push(kernelStatement);
}
@override
void endRethrowStatement(Token rethrowToken, Token endToken) {
debugEvent("RethrowStatement");
if (inCatchBlock) {
- push(new ShadowExpressionStatement(
- new ShadowRethrow()..fileOffset = offsetForToken(rethrowToken)));
+ push(forest.rethrowStatement(rethrowToken, endToken));
} else {
push(deprecated_buildCompileTimeErrorStatement(
"'rethrow' can only be used in catch clauses.",
@@ -3241,20 +3314,18 @@
@override
void endWhileStatement(Token whileKeyword, Token endToken) {
debugEvent("WhileStatement");
- kernel.Statement body = popStatement();
+ Statement body = popStatement();
Expression condition = popForValue();
JumpTarget continueTarget = exitContinueTarget();
JumpTarget breakTarget = exitBreakTarget();
if (continueTarget.hasUsers) {
- body = new ShadowLabeledStatement(body);
- continueTarget.resolveContinues(body);
+ body = forest.syntheticLabeledStatement(body);
+ continueTarget.resolveContinues(forest, body);
}
- kernel.Statement result =
- new ShadowWhileStatement(toKernelExpression(condition), body)
- ..fileOffset = whileKeyword.charOffset;
+ Statement result = forest.whileStatement(whileKeyword, condition, body);
if (breakTarget.hasUsers) {
- result = new ShadowLabeledStatement(result);
- breakTarget.resolveBreaks(result);
+ result = forest.syntheticLabeledStatement(result);
+ breakTarget.resolveBreaks(forest, result);
}
exitLoopOrSwitch(result);
}
@@ -3262,7 +3333,7 @@
@override
void handleEmptyStatement(Token token) {
debugEvent("EmptyStatement");
- push(new EmptyStatement());
+ push(forest.emptyStatement(token));
}
@override
@@ -3341,9 +3412,7 @@
@override
void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
debugEvent("YieldStatement");
- push(new ShadowYieldStatement(toKernelExpression(popForValue()),
- isYieldStar: starToken != null)
- ..fileOffset = yieldToken.charOffset);
+ push(forest.yieldStatement(yieldToken, starToken, popForValue(), endToken));
}
@override
@@ -3402,7 +3471,7 @@
// We always create a block here so that we later know that there's always
// one synthetic block when we finish compiling the switch statement and
// check this switch case to see if it falls through to the next case.
- Block block = popBlock(statementCount, firstToken);
+ Statement block = popBlock(statementCount, firstToken, null);
exitLocalScope();
List<Label> labels = pop();
List<Expression> expressions = pop();
@@ -3410,8 +3479,8 @@
for (Expression expression in expressions) {
expressionOffsets.add(forest.readOffset(expression));
}
- push(new SwitchCase(
- toKernelExpressionList(expressions), expressionOffsets, block,
+ push(new SwitchCase(toKernelExpressionList(expressions), expressionOffsets,
+ toKernelStatement(block),
isDefault: defaultKeyword != null)
..fileOffset = firstToken.charOffset);
push(labels);
@@ -3431,9 +3500,9 @@
..fileOffset = switchKeyword.charOffset;
if (target.hasUsers) {
result = new ShadowLabeledStatement(result);
- target.resolveBreaks(result);
+ target.resolveBreaks(forest, result);
}
- exitLoopOrSwitch(result);
+ exitLoopOrSwitch(toStatement(result));
}
@override
@@ -3447,7 +3516,7 @@
for (Label label in labels) {
JumpTarget target = switchScope.lookupLabel(label.name);
if (target != null) {
- target.resolveGotos(current);
+ target.resolveGotos(forest, current);
}
}
}
@@ -3458,7 +3527,7 @@
// declarations in the switch case.
TreeNode lastNode =
block.statements.isEmpty ? null : block.statements.last;
- if (lastNode is Block) {
+ if (forest.isBlock(lastNode)) {
// This is a non-synthetic block.
Block block = lastNode;
lastNode = block.statements.isEmpty ? null : block.statements.last;
@@ -3581,9 +3650,25 @@
void beginTypeVariables(Token token) {
debugEvent("beginTypeVariables");
OutlineBuilder listener = new OutlineBuilder(library);
+ // TODO(dmitryas): [ClassMemberParser] shouldn't be used to parse and build
+ // the type variables for the local function. It also causes the unresolved
+ // types from the bounds of the type variables to appear in [library.types].
+ // See the code that resolves them below.
new ClassMemberParser(listener)
.parseTypeVariablesOpt(new Token.eof(-1)..next = token);
enterFunctionTypeScope(listener.pop());
+
+ // The invocation of [enterFunctionTypeScope] above has put the type
+ // variables into the scope, and now the possibly unresolved types from
+ // the bounds of the variables can be resolved. This is needed to apply
+ // instantiate-to-bound later.
+ // TODO(dmitryas): Move the resolution to the appropriate place once
+ // [ClassMemberParser] is not used to build the type variables for the local
+ // function. See the comment above.
+ for (UnresolvedType t in library.types) {
+ t.resolveIn(scope);
+ }
+ library.types.clear();
}
@override
@@ -3616,15 +3701,40 @@
variable.parameter.addAnnotation(toKernelExpression(annotation));
}
}
- push(variable
- ..finish(library, library.loader.target.objectClassBuilder,
- library.loader.target.dynamicType));
+ push(variable);
}
@override
void endTypeVariables(int count, Token beginToken, Token endToken) {
debugEvent("TypeVariables");
- push(popList(count) ?? NullValue.TypeVariables);
+ List<KernelTypeVariableBuilder> typeVariables = popList(count);
+ if (typeVariables != null) {
+ if (library.loader.target.strongMode) {
+ List<KernelTypeBuilder> calculatedBounds = calculateBounds(
+ typeVariables,
+ library.loader.target.dynamicType,
+ library.loader.target.bottomType,
+ library.loader.target.objectClassBuilder);
+ for (int i = 0; i < typeVariables.length; ++i) {
+ typeVariables[i].defaultType = calculatedBounds[i];
+ typeVariables[i].defaultType.resolveIn(
+ scope, typeVariables[i].charOffset, typeVariables[i].fileUri);
+ typeVariables[i].finish(
+ library,
+ library.loader.target.objectClassBuilder,
+ library.loader.target.dynamicType);
+ }
+ } else {
+ for (int i = 0; i < typeVariables.length; ++i) {
+ typeVariables[i].defaultType = library.loader.target.dynamicType;
+ typeVariables[i].finish(
+ library,
+ library.loader.target.objectClassBuilder,
+ library.loader.target.dynamicType);
+ }
+ }
+ }
+ push(typeVariables ?? NullValue.TypeVariables);
}
List<TypeParameter> typeVariableBuildersToKernel(List typeVariableBuilders) {
@@ -3871,7 +3981,7 @@
@override
void handleOperator(Token token) {
debugEvent("Operator");
- push(new Operator(token.stringValue, token.charOffset));
+ push(new Operator(token, token.charOffset));
}
@override
@@ -3898,10 +4008,13 @@
if (member.isNative) {
push(NullValue.FunctionBody);
} else {
- push(new Block(<kernel.Statement>[
- deprecated_buildCompileTimeErrorStatement(
- "Expected '{'.", token.charOffset)
- ]));
+ push(forest.block(
+ token,
+ <Statement>[
+ toStatement(deprecated_buildCompileTimeErrorStatement(
+ "Expected '{'.", token.charOffset))
+ ],
+ null));
}
}
@@ -3960,7 +4073,7 @@
}
if (isSuper) {
// We can ignore [isNullAware] on super sends.
- assert(receiver is ThisExpression);
+ assert(forest.isThisExpression(receiver));
Member target = lookupInstanceMember(name, isSuper: true);
if (target == null || (target is Procedure && !target.isAccessor)) {
@@ -3994,14 +4107,17 @@
new VariableDeclaration.forValue(toKernelExpression(receiver));
return toExpression(new ShadowNullAwareMethodInvocation(
variable,
- new ConditionalExpression(
- buildIsNull(new VariableGet(variable), offset),
- toKernelExpression(storeOffset(forest.literalNull(null), offset)),
- new MethodInvocation(new VariableGet(variable), name,
- forest.castArguments(arguments), interfaceTarget)
- ..fileOffset = offset,
- null)
- ..fileOffset = offset)
+ toKernelExpression(storeOffset(
+ forest.conditionalExpression(
+ toExpression(
+ buildIsNull(new VariableGet(variable), offset, this)),
+ null,
+ storeOffset(forest.literalNull(null), offset),
+ null,
+ toExpression(new MethodInvocation(new VariableGet(variable),
+ name, forest.castArguments(arguments), interfaceTarget)
+ ..fileOffset = offset)),
+ offset)))
..fileOffset = offset);
} else {
return toExpression(new ShadowMethodInvocation(
@@ -4079,6 +4195,20 @@
return expressions as dynamic;
}
+ // TODO(ahe): Remove this method once Forest API is complete.
+ kernel.Statement toKernelStatement(Statement statement) {
+ return statement as dynamic;
+ }
+
+ // TODO(ahe): Remove this method once Forest API is complete.
+ Statement toStatement(kernel.Statement statement) {
+ return statement as dynamic;
+ }
+
+ /// TODO(ahe): This method is temporarily implemented by subclasses. Once type
+ /// promotion is independent of shadow nodes, remove this method.
+ void enterThenForTypePromotion(Expression condition);
+
bool isErroneousNode(TreeNode node) {
return library.loader.handledErrors.isNotEmpty &&
forest.isErroneousNode(node);
@@ -4097,11 +4227,12 @@
}
class Operator {
- final String name;
+ final Token token;
+ String get name => token.stringValue;
final int charOffset;
- Operator(this.name, this.charOffset);
+ Operator(this.token, this.charOffset);
String toString() => "operator($name)";
}
@@ -4123,8 +4254,9 @@
String toString() => "label($name)";
}
-abstract class ContextAccessor<Arguments> extends FastaAccessor<Arguments> {
- final BuilderHelper helper;
+abstract class ContextAccessor<Arguments> extends FastaAccessor<Arguments>
+ with GeneratorImpl {
+ final BuilderHelper<dynamic, dynamic, Arguments> helper;
final FastaAccessor accessor;
@@ -4194,10 +4326,12 @@
final String assignmentOperator;
- DelayedAssignment(BuilderHelper helper, Token token, FastaAccessor accessor,
- this.value, this.assignmentOperator)
+ DelayedAssignment(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, FastaAccessor accessor, this.value, this.assignmentOperator)
: super(helper, token, accessor);
+ String get debugName => "DelayedAssignment";
+
kernel.Expression buildSimpleRead() {
return handleAssignment(false);
}
@@ -4258,13 +4392,20 @@
@override
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- if (!identical("=", assignmentOperator) ||
- !accessor.isThisPropertyAccessor) {
+ if (!identical("=", assignmentOperator) || !accessor.isThisPropertyAccess) {
return accessor.buildFieldInitializer(initializedFields);
}
return helper.buildFieldInitializer(
false, accessor.plainNameForRead, offsetForToken(token), value);
}
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", value: ");
+ printNodeOn(value, sink);
+ sink.write(", assignmentOperator: ");
+ sink.write(assignmentOperator);
+ }
}
class DelayedPostfixIncrement<Arguments> extends ContextAccessor<Arguments> {
@@ -4272,10 +4413,16 @@
final Procedure interfaceTarget;
- DelayedPostfixIncrement(BuilderHelper helper, Token token,
- FastaAccessor accessor, this.binaryOperator, this.interfaceTarget)
+ DelayedPostfixIncrement(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ FastaAccessor accessor,
+ this.binaryOperator,
+ this.interfaceTarget)
: super(helper, token, accessor);
+ String get debugName => "DelayedPostfixIncrement";
+
kernel.Expression buildSimpleRead() {
return accessor.buildPostfixIncrement(binaryOperator,
offset: offsetForToken(token),
@@ -4289,10 +4436,18 @@
voidContext: true,
interfaceTarget: interfaceTarget);
}
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", binaryOperator: ");
+ sink.write(binaryOperator.name);
+ sink.write(", interfaceTarget: ");
+ printQualifiedNameOn(interfaceTarget, sink);
+ }
}
-class JumpTarget extends Builder {
- final List<kernel.Statement> users = <kernel.Statement>[];
+class JumpTarget<Statement> extends Builder {
+ final List<Statement> users = <Statement>[];
final JumpTargetKind kind;
@@ -4310,41 +4465,44 @@
bool get hasUsers => users.isNotEmpty;
- void addBreak(BreakStatement statement) {
+ void addBreak(Statement statement) {
assert(isBreakTarget);
users.add(statement);
}
- void addContinue(BreakStatement statement) {
+ void addContinue(Statement statement) {
assert(isContinueTarget);
users.add(statement);
}
- void addGoto(ContinueSwitchStatement statement) {
+ void addGoto(Statement statement) {
assert(isGotoTarget);
users.add(statement);
}
- void resolveBreaks(LabeledStatement target) {
+ void resolveBreaks(
+ Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
assert(isBreakTarget);
- for (BreakStatement user in users) {
- user.target = target;
+ for (Statement user in users) {
+ forest.resolveBreak(target, user);
}
users.clear();
}
- void resolveContinues(LabeledStatement target) {
+ void resolveContinues(
+ Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
assert(isContinueTarget);
- for (BreakStatement user in users) {
- user.target = target;
+ for (Statement user in users) {
+ forest.resolveContinue(target, user);
}
users.clear();
}
- void resolveGotos(SwitchCase target) {
+ void resolveGotos(
+ Forest<dynamic, Statement, dynamic, dynamic> forest, Object target) {
assert(isGotoTarget);
- for (ContinueSwitchStatement user in users) {
- user.target = target;
+ for (Statement user in users) {
+ forest.resolveContinueInSwitch(target, user);
}
users.clear();
}
@@ -4353,7 +4511,7 @@
String get fullNameForErrors => "<jump-target>";
}
-class LabelTarget extends Builder implements JumpTarget {
+class LabelTarget<Statement> extends Builder implements JumpTarget<Statement> {
final JumpTarget breakTarget;
final JumpTarget continueTarget;
@@ -4361,15 +4519,15 @@
final int functionNestingLevel;
LabelTarget(MemberBuilder member, this.functionNestingLevel, int charOffset)
- : breakTarget = new JumpTarget(
+ : breakTarget = new JumpTarget<Statement>(
JumpTargetKind.Break, functionNestingLevel, member, charOffset),
- continueTarget = new JumpTarget(
+ continueTarget = new JumpTarget<Statement>(
JumpTargetKind.Continue, functionNestingLevel, member, charOffset),
super(member, charOffset, member.fileUri);
bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers;
- List<kernel.Statement> get users => unsupported("users", charOffset, fileUri);
+ List<Statement> get users => unsupported("users", charOffset, fileUri);
JumpTargetKind get kind => unsupported("kind", charOffset, fileUri);
@@ -4379,27 +4537,30 @@
bool get isGotoTarget => false;
- void addBreak(BreakStatement statement) {
+ void addBreak(Statement statement) {
breakTarget.addBreak(statement);
}
- void addContinue(BreakStatement statement) {
+ void addContinue(Statement statement) {
continueTarget.addContinue(statement);
}
- void addGoto(ContinueSwitchStatement statement) {
+ void addGoto(Statement statement) {
unsupported("addGoto", charOffset, fileUri);
}
- void resolveBreaks(LabeledStatement target) {
- breakTarget.resolveBreaks(target);
+ void resolveBreaks(
+ Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+ breakTarget.resolveBreaks(forest, target);
}
- void resolveContinues(LabeledStatement target) {
- continueTarget.resolveContinues(target);
+ void resolveContinues(
+ Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+ continueTarget.resolveContinues(forest, target);
}
- void resolveGotos(SwitchCase target) {
+ void resolveGotos(
+ Forest<dynamic, Statement, dynamic, dynamic> forest, Object target) {
unsupported("resolveGotos", charOffset, fileUri);
}
@@ -4415,7 +4576,7 @@
OptionalFormals(this.kind, this.formals);
}
-class FormalParameters {
+class FormalParameters<Arguments> {
final List<VariableDeclaration> required;
final OptionalFormals optional;
final int charOffset;
@@ -4466,8 +4627,8 @@
typeParameters: typeParameters);
}
- Scope computeFormalParameterScope(
- Scope parent, Builder builder, BuilderHelper helper) {
+ Scope computeFormalParameterScope(Scope parent, Builder builder,
+ BuilderHelper<dynamic, dynamic, Arguments> helper) {
if (required.length == 0 && optional == null) return parent;
Map<String, Builder> local = <String, Builder>{};
@@ -4521,7 +4682,7 @@
return node.name;
} else if (node is Builder) {
return node.fullNameForErrors;
- } else if (node is ThisAccessor) {
+ } else if (node is ThisAccessGenerator) {
return node.isSuper ? "super" : "this";
} else if (node is FastaAccessor) {
return node.plainNameForRead;
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
new file mode 100644
index 0000000..291cf8a
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -0,0 +1,1752 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A library to help transform compounds and null-aware accessors into
+/// let expressions.
+library fasta.expression_generator;
+
+import '../../scanner/token.dart' show Token;
+
+import '../constant_context.dart' show ConstantContext;
+
+import '../fasta_codes.dart'
+ show
+ LocatedMessage,
+ messageInvalidInitializer,
+ messageLoadLibraryTakesNoArguments,
+ messageSuperAsExpression,
+ templateDeferredTypeAnnotation,
+ templateIntegerLiteralIsOutOfRange,
+ templateNotAPrefixInTypeAnnotation,
+ templateNotAType,
+ templateUnresolvedPrefixInTypeAnnotation;
+
+import '../messages.dart' show Message, noLength;
+
+import '../names.dart'
+ show callName, equalsName, indexGetName, indexSetName, lengthName;
+
+import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
+
+import '../problems.dart' show unhandled, unimplemented, unsupported;
+
+import '../scope.dart' show AccessErrorBuilder, ProblemBuilder, Scope;
+
+import '../type_inference/type_promotion.dart' show TypePromoter;
+
+import 'body_builder.dart' show Identifier, noLocation;
+
+import 'constness.dart' show Constness;
+
+import 'forest.dart' show Forest;
+
+import 'kernel_builder.dart' show LoadLibraryBuilder, PrefixBuilder;
+
+import 'kernel_api.dart' show NameSystem, printNodeOn, printQualifiedNameOn;
+
+import 'kernel_ast_api.dart'
+ show
+ Constructor,
+ DartType,
+ Field,
+ FunctionNode,
+ FunctionType,
+ Initializer,
+ InvalidType,
+ Let,
+ Member,
+ Name,
+ Procedure,
+ PropertySet,
+ ShadowComplexAssignment,
+ ShadowIllegalAssignment,
+ ShadowIndexAssign,
+ ShadowMethodInvocation,
+ ShadowNullAwarePropertyGet,
+ ShadowPropertyAssign,
+ ShadowPropertyGet,
+ ShadowStaticAssignment,
+ ShadowSuperMethodInvocation,
+ ShadowSuperPropertyGet,
+ ShadowVariableAssignment,
+ ShadowVariableDeclaration,
+ ShadowVariableGet,
+ StaticGet,
+ StaticSet,
+ SuperMethodInvocation,
+ SuperPropertySet,
+ Throw,
+ TreeNode,
+ TypeParameter,
+ TypeParameterType,
+ VariableDeclaration,
+ VariableGet,
+ VariableSet;
+
+import 'kernel_ast_api.dart' as kernel show Expression, Node, Statement;
+
+import 'kernel_builder.dart'
+ show
+ Builder,
+ BuiltinTypeBuilder,
+ FunctionTypeAliasBuilder,
+ KernelClassBuilder,
+ KernelFunctionTypeAliasBuilder,
+ KernelInvalidTypeBuilder,
+ KernelPrefixBuilder,
+ KernelTypeVariableBuilder,
+ LibraryBuilder,
+ LoadLibraryBuilder,
+ PrefixBuilder,
+ TypeDeclarationBuilder;
+
+part 'expression_generator_impl.dart';
+
+/// An [Accessor] represents a subexpression for which we can't yet build a
+/// kernel [kernel.Expression] because we don't yet know the context in which
+/// it is used.
+///
+/// Once the context is known, an [Accessor] can be converted into an
+/// [kernel.Expression] by calling a "build" method.
+///
+/// For example, when building a kernel representation for `a[x] = b`, after
+/// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
+/// generate an invocation of `operator[]` or `operator[]=`, so we generate an
+/// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be
+/// called.
+// TODO(ahe): Move this into [Generator] when all uses have been updated.
+abstract class Accessor<Arguments> {
+ final BuilderHelper<dynamic, dynamic, Arguments> helper;
+ final Token token;
+
+ Accessor(this.helper, this.token);
+
+ Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
+ helper.forest;
+
+ /// Builds an [kernel.Expression] representing a read from the accessor.
+ kernel.Expression buildSimpleRead() {
+ return _finish(_makeSimpleRead(), null);
+ }
+
+ /// Builds an [kernel.Expression] representing an assignment with the
+ /// accessor on the LHS and [value] on the RHS.
+ ///
+ /// The returned expression evaluates to the assigned value, unless
+ /// [voidContext] is true, in which case it may evaluate to anything.
+ kernel.Expression buildAssignment(kernel.Expression value,
+ {bool voidContext: false}) {
+ var complexAssignment = startComplexAssignment(value);
+ return _finish(_makeSimpleWrite(value, voidContext, complexAssignment),
+ complexAssignment);
+ }
+
+ /// Returns an [kernel.Expression] representing a null-aware assignment
+ /// (`??=`) with the accessor on the LHS and [value] on the RHS.
+ ///
+ /// The returned expression evaluates to the assigned value, unless
+ /// [voidContext] is true, in which case it may evaluate to anything.
+ ///
+ /// [type] is the static type of the RHS.
+ kernel.Expression buildNullAwareAssignment(
+ kernel.Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ var complexAssignment = startComplexAssignment(value);
+ if (voidContext) {
+ var nullAwareCombiner = helper.storeOffset(
+ forest.conditionalExpression(
+ buildIsNull(_makeRead(complexAssignment), offset, helper),
+ null,
+ _makeWrite(value, false, complexAssignment),
+ null,
+ helper.storeOffset(forest.literalNull(null), offset)),
+ offset);
+ complexAssignment?.nullAwareCombiner = nullAwareCombiner;
+ return _finish(nullAwareCombiner, complexAssignment);
+ }
+ var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment));
+ var nullAwareCombiner = helper.storeOffset(
+ forest.conditionalExpression(
+ buildIsNull(new VariableGet(tmp), offset, helper),
+ null,
+ _makeWrite(value, false, complexAssignment),
+ null,
+ new VariableGet(tmp)),
+ offset);
+ complexAssignment?.nullAwareCombiner = nullAwareCombiner;
+ return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
+ }
+
+ /// Returns an [kernel.Expression] representing a compound assignment
+ /// (e.g. `+=`) with the accessor on the LHS and [value] on the RHS.
+ kernel.Expression buildCompoundAssignment(
+ Name binaryOperator, kernel.Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false}) {
+ var complexAssignment = startComplexAssignment(value);
+ complexAssignment?.isPreIncDec = isPreIncDec;
+ var combiner = makeBinary(_makeRead(complexAssignment), binaryOperator,
+ interfaceTarget, value, helper,
+ offset: offset);
+ complexAssignment?.combiner = combiner;
+ return _finish(_makeWrite(combiner, voidContext, complexAssignment),
+ complexAssignment);
+ }
+
+ /// Returns an [kernel.Expression] representing a pre-increment or
+ /// pre-decrement of the accessor.
+ kernel.Expression buildPrefixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ return buildCompoundAssignment(
+ binaryOperator, helper.storeOffset(forest.literalInt(1, null), offset),
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPreIncDec: true);
+ }
+
+ /// Returns an [kernel.Expression] representing a post-increment or
+ /// post-decrement of the accessor.
+ kernel.Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ if (voidContext) {
+ return buildPrefixIncrement(binaryOperator,
+ offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
+ }
+ var rhs = helper.storeOffset(forest.literalInt(1, null), offset);
+ var complexAssignment = startComplexAssignment(rhs);
+ var value = new VariableDeclaration.forValue(_makeRead(complexAssignment));
+ valueAccess() => new VariableGet(value);
+ var combiner = makeBinary(
+ valueAccess(), binaryOperator, interfaceTarget, rhs, helper,
+ offset: offset);
+ complexAssignment?.combiner = combiner;
+ complexAssignment?.isPostIncDec = true;
+ var dummy = new ShadowVariableDeclaration.forValue(
+ _makeWrite(combiner, true, complexAssignment),
+ helper.functionNestingLevel);
+ return _finish(
+ makeLet(value, makeLet(dummy, valueAccess())), complexAssignment);
+ }
+
+ kernel.Expression _makeSimpleRead() => _makeRead(null);
+
+ kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return _makeWrite(value, voidContext, complexAssignment);
+ }
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment);
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment);
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+ if (complexAssignment != null) {
+ complexAssignment.desugared = body;
+ return complexAssignment;
+ } else {
+ return body;
+ }
+ }
+
+ /// Returns an [kernel.Expression] representing a compile-time error.
+ ///
+ /// At runtime, an exception will be thrown.
+ makeInvalidRead() {
+ return unhandled("compile-time error", "$runtimeType",
+ offsetForToken(token), helper.uri);
+ }
+
+ /// Returns an [kernel.Expression] representing a compile-time error wrapping
+ /// [value].
+ ///
+ /// At runtime, [value] will be evaluated before throwing an exception.
+ makeInvalidWrite(kernel.Expression value) {
+ return unhandled("compile-time error", "$runtimeType",
+ offsetForToken(token), helper.uri);
+ }
+
+ /// Creates a data structure for tracking the desugaring of a complex
+ /// assignment expression whose right hand side is [rhs].
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowIllegalAssignment(rhs);
+}
+
+// TODO(ahe): Merge classes [Accessor] and [FastaAccessor] into this.
+abstract class Generator<Arguments> = Accessor<Arguments>
+ with FastaAccessor<Arguments>;
+
+class VariableUseGenerator<Arguments> extends Generator<Arguments> {
+ final VariableDeclaration variable;
+
+ final DartType promotedType;
+
+ VariableUseGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.variable,
+ [this.promotedType])
+ : super(helper, token);
+
+ String get plainNameForRead => variable.name;
+
+ String get debugName => "VariableUseGenerator";
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ var fact = helper.typePromoter
+ .getFactForAccess(variable, helper.functionNestingLevel);
+ var scope = helper.typePromoter.currentScope;
+ var read = new ShadowVariableGet(variable, fact, scope)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ helper.typePromoter.mutateVariable(variable, helper.functionNestingLevel);
+ var write = variable.isFinal || variable.isConst
+ ? makeInvalidWrite(value)
+ : new VariableSet(variable, value)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ @override
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
+ adjustForImplicitCall(plainNameForRead, offset),
+ isImplicitCall: true);
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowVariableAssignment(rhs);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", variable: ");
+ printNodeOn(variable, sink, syntheticNames: syntheticNames);
+ sink.write(", promotedType: ");
+ printNodeOn(promotedType, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class PropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+ final kernel.Expression receiver;
+
+ final Name name;
+
+ final Member getter;
+
+ final Member setter;
+
+ VariableDeclaration _receiverVariable;
+
+ PropertyAccessGenerator.internal(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ this.receiver,
+ this.name,
+ this.getter,
+ this.setter)
+ : super(helper, token);
+
+ static FastaAccessor<Arguments> make<Arguments>(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ kernel.Expression receiver,
+ Name name,
+ Member getter,
+ Member setter,
+ bool isNullAware) {
+ if (helper.forest.isThisExpression(receiver)) {
+ return unsupported("ThisExpression", offsetForToken(token), helper.uri);
+ } else {
+ return isNullAware
+ ? new NullAwarePropertyAccessGenerator(
+ helper, token, receiver, name, getter, setter, null)
+ : new PropertyAccessGenerator.internal(
+ helper, token, receiver, name, getter, setter);
+ }
+ }
+
+ String get plainNameForRead => name.name;
+
+ String get debugName => "PropertyAccessGenerator";
+
+ bool get isThisPropertyAccess => forest.isThisExpression(receiver);
+
+ kernel.Expression _makeSimpleRead() =>
+ new ShadowPropertyGet(receiver, name, getter)
+ ..fileOffset = offsetForToken(token);
+
+ kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ var write = new PropertySet(receiver, name, value, setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ receiverAccess() {
+ _receiverVariable ??= new VariableDeclaration.forValue(receiver);
+ return new VariableGet(_receiverVariable)
+ ..fileOffset = offsetForToken(token);
+ }
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ var read = new ShadowPropertyGet(receiverAccess(), name, getter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ var write = new PropertySet(receiverAccess(), name, value, setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+ return super._finish(makeLet(_receiverVariable, body), complexAssignment);
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.buildMethodInvocation(receiver, name, arguments, offset);
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowPropertyAssign(receiver, rhs);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", _receiverVariable: ");
+ printNodeOn(_receiverVariable, sink, syntheticNames: syntheticNames);
+ sink.write(", receiver: ");
+ printNodeOn(receiver, sink, syntheticNames: syntheticNames);
+ sink.write(", name: ");
+ sink.write(name.name);
+ sink.write(", getter: ");
+ printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+ sink.write(", setter: ");
+ printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+ }
+}
+
+/// Special case of [PropertyAccessGenerator] to avoid creating an indirect
+/// access to 'this'.
+class ThisPropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+ final Name name;
+
+ final Member getter;
+
+ final Member setter;
+
+ ThisPropertyAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.name, this.getter, this.setter)
+ : super(helper, token);
+
+ String get plainNameForRead => name.name;
+
+ String get debugName => "ThisPropertyAccessGenerator";
+
+ bool get isThisPropertyAccess => true;
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ if (getter == null) {
+ helper.warnUnresolvedGet(name, offsetForToken(token));
+ }
+ var read = new ShadowPropertyGet(forest.thisExpression(token), name, getter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (setter == null) {
+ helper.warnUnresolvedSet(name, offsetForToken(token));
+ }
+ var write =
+ new PropertySet(forest.thisExpression(token), name, value, setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ Member interfaceTarget = getter;
+ if (interfaceTarget == null) {
+ helper.warnUnresolvedMethod(name, offset);
+ }
+ if (interfaceTarget is Field) {
+ // TODO(ahe): In strong mode we should probably rewrite this to
+ // `this.name.call(arguments)`.
+ interfaceTarget = null;
+ }
+ return helper.buildMethodInvocation(
+ forest.thisExpression(null), name, arguments, offset,
+ interfaceTarget: interfaceTarget);
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowPropertyAssign(null, rhs);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", name: ");
+ sink.write(name.name);
+ sink.write(", getter: ");
+ printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+ sink.write(", setter: ");
+ printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class NullAwarePropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+ final VariableDeclaration receiver;
+
+ final kernel.Expression receiverExpression;
+
+ final Name name;
+
+ final Member getter;
+
+ final Member setter;
+
+ final DartType type;
+
+ NullAwarePropertyAccessGenerator(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ this.receiverExpression,
+ this.name,
+ this.getter,
+ this.setter,
+ this.type)
+ : this.receiver = makeOrReuseVariable(receiverExpression),
+ super(helper, token);
+
+ String get plainNameForRead => name.name;
+
+ String get debugName => "NullAwarePropertyAccessGenerator";
+
+ kernel.Expression receiverAccess() => new VariableGet(receiver);
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ var read = new ShadowPropertyGet(receiverAccess(), name, getter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ var write = new PropertySet(receiverAccess(), name, value, setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+ var offset = offsetForToken(token);
+ var nullAwareGuard = helper.storeOffset(
+ forest.conditionalExpression(
+ buildIsNull(receiverAccess(), offset, helper),
+ null,
+ helper.storeOffset(forest.literalNull(null), offset),
+ null,
+ body),
+ offset);
+ if (complexAssignment != null) {
+ body = makeLet(receiver, nullAwareGuard);
+ ShadowPropertyAssign kernelPropertyAssign = complexAssignment;
+ kernelPropertyAssign.nullAwareGuard = nullAwareGuard;
+ kernelPropertyAssign.desugared = body;
+ return kernelPropertyAssign;
+ } else {
+ return new ShadowNullAwarePropertyGet(receiver, nullAwareGuard)
+ ..fileOffset = offset;
+ }
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return unimplemented("doInvocation", offset, uri);
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowPropertyAssign(receiverExpression, rhs);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", receiver: ");
+ printNodeOn(receiver, sink, syntheticNames: syntheticNames);
+ sink.write(", receiverExpression: ");
+ printNodeOn(receiverExpression, sink, syntheticNames: syntheticNames);
+ sink.write(", name: ");
+ sink.write(name.name);
+ sink.write(", getter: ");
+ printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+ sink.write(", setter: ");
+ printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+ sink.write(", type: ");
+ printNodeOn(type, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class SuperPropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+ final Name name;
+
+ final Member getter;
+
+ final Member setter;
+
+ SuperPropertyAccessGenerator(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ this.name,
+ this.getter,
+ this.setter)
+ : super(helper, token);
+
+ String get plainNameForRead => name.name;
+
+ String get debugName => "SuperPropertyAccessGenerator";
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ if (getter == null) {
+ helper.warnUnresolvedGet(name, offsetForToken(token), isSuper: true);
+ }
+ // TODO(ahe): Use [DirectPropertyGet] when possible.
+ var read = new ShadowSuperPropertyGet(name, getter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (setter == null) {
+ helper.warnUnresolvedSet(name, offsetForToken(token), isSuper: true);
+ }
+ // TODO(ahe): Use [DirectPropertySet] when possible.
+ var write = new SuperPropertySet(name, value, setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ if (helper.constantContext != ConstantContext.none) {
+ helper.deprecated_addCompileTimeError(
+ offset, "Not a constant expression.");
+ }
+ if (getter == null || isFieldOrGetter(getter)) {
+ return helper.buildMethodInvocation(
+ buildSimpleRead(), callName, arguments, offset,
+ // This isn't a constant expression, but we have checked if a
+ // constant expression error should be emitted already.
+ isConstantExpression: true,
+ isImplicitCall: true);
+ } else {
+ // TODO(ahe): This could be something like "super.property(...)" where
+ // property is a setter.
+ return unhandled("${getter.runtimeType}", "doInvocation", offset, uri);
+ }
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowPropertyAssign(null, rhs, isSuper: true);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", name: ");
+ sink.write(name.name);
+ sink.write(", getter: ");
+ printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+ sink.write(", setter: ");
+ printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class IndexedAccessGenerator<Arguments> extends Generator<Arguments> {
+ final kernel.Expression receiver;
+
+ final kernel.Expression index;
+
+ final Procedure getter;
+
+ final Procedure setter;
+
+ VariableDeclaration receiverVariable;
+
+ VariableDeclaration indexVariable;
+
+ IndexedAccessGenerator.internal(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ this.receiver,
+ this.index,
+ this.getter,
+ this.setter)
+ : super(helper, token);
+
+ static FastaAccessor<Arguments> make<Arguments>(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ kernel.Expression receiver,
+ kernel.Expression index,
+ Procedure getter,
+ Procedure setter) {
+ if (helper.forest.isThisExpression(receiver)) {
+ return new ThisIndexedAccessGenerator(
+ helper, token, index, getter, setter);
+ } else {
+ return new IndexedAccessGenerator.internal(
+ helper, token, receiver, index, getter, setter);
+ }
+ }
+
+ String get plainNameForRead => "[]";
+
+ String get plainNameForWrite => "[]=";
+
+ String get debugName => "IndexedAccessGenerator";
+
+ kernel.Expression _makeSimpleRead() {
+ var read = new ShadowMethodInvocation(
+ receiver,
+ indexGetName,
+ forest
+ .castArguments(forest.arguments(<kernel.Expression>[index], token)),
+ interfaceTarget: getter)
+ ..fileOffset = offsetForToken(token);
+ return read;
+ }
+
+ kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+ var write = new ShadowMethodInvocation(
+ receiver,
+ indexSetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[index, value], token)),
+ interfaceTarget: setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ receiverAccess() {
+ // We cannot reuse the receiver if it is a variable since it might be
+ // reassigned in the index expression.
+ receiverVariable ??= new VariableDeclaration.forValue(receiver);
+ return new VariableGet(receiverVariable)
+ ..fileOffset = offsetForToken(token);
+ }
+
+ indexAccess() {
+ indexVariable ??= new VariableDeclaration.forValue(index);
+ return new VariableGet(indexVariable)..fileOffset = offsetForToken(token);
+ }
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ var read = new ShadowMethodInvocation(
+ receiverAccess(),
+ indexGetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[indexAccess()], token)),
+ interfaceTarget: getter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+ var write = new ShadowMethodInvocation(
+ receiverAccess(),
+ indexSetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[indexAccess(), value], token)),
+ interfaceTarget: setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ // TODO(dmitryas): remove this method after the "[]=" operator of the Context
+ // class is made to return a value.
+ _makeWriteAndReturn(
+ kernel.Expression value, ShadowComplexAssignment complexAssignment) {
+ // The call to []= does not return the value like direct-style assignments
+ // do. We need to bind the value in a let.
+ var valueVariable = new VariableDeclaration.forValue(value);
+ var write = new ShadowMethodInvocation(
+ receiverAccess(),
+ indexSetName,
+ forest.castArguments(forest.arguments(
+ <kernel.Expression>[indexAccess(), new VariableGet(valueVariable)],
+ token)),
+ interfaceTarget: setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ var dummy = new ShadowVariableDeclaration.forValue(
+ write, helper.functionNestingLevel);
+ return makeLet(
+ valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+ }
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+ return super._finish(
+ makeLet(receiverVariable, makeLet(indexVariable, body)),
+ complexAssignment);
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.buildMethodInvocation(
+ buildSimpleRead(), callName, arguments, forest.readOffset(arguments),
+ isImplicitCall: true);
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowIndexAssign(receiver, index, rhs);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", receiver: ");
+ printNodeOn(receiver, sink, syntheticNames: syntheticNames);
+ sink.write(", index: ");
+ printNodeOn(index, sink, syntheticNames: syntheticNames);
+ sink.write(", getter: ");
+ printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+ sink.write(", setter: ");
+ printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+ sink.write(", receiverVariable: ");
+ printNodeOn(receiverVariable, sink, syntheticNames: syntheticNames);
+ sink.write(", indexVariable: ");
+ printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+ }
+}
+
+/// Special case of [IndexedAccessGenerator] to avoid creating an indirect
+/// access to 'this'.
+class ThisIndexedAccessGenerator<Arguments> extends Generator<Arguments> {
+ final kernel.Expression index;
+
+ final Procedure getter;
+
+ final Procedure setter;
+
+ VariableDeclaration indexVariable;
+
+ ThisIndexedAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.index, this.getter, this.setter)
+ : super(helper, token);
+
+ String get plainNameForRead => "[]";
+
+ String get plainNameForWrite => "[]=";
+
+ String get debugName => "ThisIndexedAccessGenerator";
+
+ kernel.Expression _makeSimpleRead() {
+ return new ShadowMethodInvocation(
+ forest.thisExpression(token),
+ indexGetName,
+ forest
+ .castArguments(forest.arguments(<kernel.Expression>[index], token)),
+ interfaceTarget: getter)
+ ..fileOffset = offsetForToken(token);
+ }
+
+ kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+ var write = new ShadowMethodInvocation(
+ forest.thisExpression(token),
+ indexSetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[index, value], token)),
+ interfaceTarget: setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ indexAccess() {
+ indexVariable ??= new VariableDeclaration.forValue(index);
+ return new VariableGet(indexVariable);
+ }
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ var read = new ShadowMethodInvocation(
+ forest.thisExpression(token),
+ indexGetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[indexAccess()], token)),
+ interfaceTarget: getter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+ var write = new ShadowMethodInvocation(
+ forest.thisExpression(token),
+ indexSetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[indexAccess(), value], token)),
+ interfaceTarget: setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ _makeWriteAndReturn(
+ kernel.Expression value, ShadowComplexAssignment complexAssignment) {
+ var valueVariable = new VariableDeclaration.forValue(value);
+ var write = new ShadowMethodInvocation(
+ forest.thisExpression(token),
+ indexSetName,
+ forest.castArguments(forest.arguments(
+ <kernel.Expression>[indexAccess(), new VariableGet(valueVariable)],
+ token)),
+ interfaceTarget: setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ var dummy = new VariableDeclaration.forValue(write);
+ return makeLet(
+ valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+ }
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+ return super._finish(makeLet(indexVariable, body), complexAssignment);
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.buildMethodInvocation(
+ buildSimpleRead(), callName, arguments, offset,
+ isImplicitCall: true);
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowIndexAssign(null, index, rhs);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", index: ");
+ printNodeOn(index, sink, syntheticNames: syntheticNames);
+ sink.write(", getter: ");
+ printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+ sink.write(", setter: ");
+ printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+ sink.write(", indexVariable: ");
+ printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class SuperIndexedAccessGenerator<Arguments> extends Generator<Arguments> {
+ final kernel.Expression index;
+
+ final Member getter;
+
+ final Member setter;
+
+ VariableDeclaration indexVariable;
+
+ SuperIndexedAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.index, this.getter, this.setter)
+ : super(helper, token);
+
+ String get plainNameForRead => "[]";
+
+ String get plainNameForWrite => "[]=";
+
+ String get debugName => "SuperIndexedAccessGenerator";
+
+ indexAccess() {
+ indexVariable ??= new VariableDeclaration.forValue(index);
+ return new VariableGet(indexVariable);
+ }
+
+ kernel.Expression _makeSimpleRead() {
+ if (getter == null) {
+ helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+ isSuper: true);
+ }
+ // TODO(ahe): Use [DirectMethodInvocation] when possible.
+ return new ShadowSuperMethodInvocation(
+ indexGetName,
+ forest
+ .castArguments(forest.arguments(<kernel.Expression>[index], token)),
+ getter)
+ ..fileOffset = offsetForToken(token);
+ }
+
+ kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+ if (setter == null) {
+ helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+ isSuper: true);
+ }
+ var write = new SuperMethodInvocation(
+ indexSetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[index, value], token)),
+ setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ if (getter == null) {
+ helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+ isSuper: true);
+ }
+ var read = new SuperMethodInvocation(
+ indexGetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[indexAccess()], token)),
+ getter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+ if (setter == null) {
+ helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+ isSuper: true);
+ }
+ var write = new SuperMethodInvocation(
+ indexSetName,
+ forest.castArguments(
+ forest.arguments(<kernel.Expression>[indexAccess(), value], token)),
+ setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ _makeWriteAndReturn(
+ kernel.Expression value, ShadowComplexAssignment complexAssignment) {
+ var valueVariable = new VariableDeclaration.forValue(value);
+ if (setter == null) {
+ helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+ isSuper: true);
+ }
+ var write = new SuperMethodInvocation(
+ indexSetName,
+ forest.castArguments(forest.arguments(
+ <kernel.Expression>[indexAccess(), new VariableGet(valueVariable)],
+ token)),
+ setter)
+ ..fileOffset = offsetForToken(token);
+ complexAssignment?.write = write;
+ var dummy = new VariableDeclaration.forValue(write);
+ return makeLet(
+ valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+ }
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+ return super._finish(makeLet(indexVariable, body), complexAssignment);
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.buildMethodInvocation(
+ buildSimpleRead(), callName, arguments, offset,
+ isImplicitCall: true);
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowIndexAssign(null, index, rhs, isSuper: true);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", index: ");
+ printNodeOn(index, sink, syntheticNames: syntheticNames);
+ sink.write(", getter: ");
+ printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+ sink.write(", setter: ");
+ printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+ sink.write(", indexVariable: ");
+ printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class StaticAccessGenerator<Arguments> extends Generator<Arguments> {
+ final Member readTarget;
+
+ final Member writeTarget;
+
+ StaticAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.readTarget, this.writeTarget)
+ : assert(readTarget != null || writeTarget != null),
+ super(helper, token);
+
+ factory StaticAccessGenerator.fromBuilder(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Builder builder,
+ Token token,
+ Builder builderSetter) {
+ if (builder is AccessErrorBuilder) {
+ AccessErrorBuilder error = builder;
+ builder = error.builder;
+ // We should only see an access error here if we've looked up a setter
+ // when not explicitly looking for a setter.
+ assert(builder.isSetter);
+ } else if (builder.target == null) {
+ return unhandled(
+ "${builder.runtimeType}",
+ "StaticAccessGenerator.fromBuilder",
+ offsetForToken(token),
+ helper.uri);
+ }
+ Member getter = builder.target.hasGetter ? builder.target : null;
+ Member setter = builder.target.hasSetter ? builder.target : null;
+ if (setter == null) {
+ if (builderSetter?.target?.hasSetter ?? false) {
+ setter = builderSetter.target;
+ }
+ }
+ return new StaticAccessGenerator(helper, token, getter, setter);
+ }
+
+ String get plainNameForRead => (readTarget ?? writeTarget).name.name;
+
+ String get debugName => "StaticAccessGenerator";
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ if (readTarget == null) {
+ return makeInvalidRead();
+ } else {
+ var read = helper.makeStaticGet(readTarget, token);
+ complexAssignment?.read = read;
+ return read;
+ }
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ kernel.Expression write;
+ if (writeTarget == null) {
+ write = makeInvalidWrite(value);
+ } else {
+ write = new StaticSet(writeTarget, value);
+ complexAssignment?.write = write;
+ }
+ write.fileOffset = offsetForToken(token);
+ return write;
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ if (helper.constantContext != ConstantContext.none &&
+ !helper.isIdentical(readTarget)) {
+ helper.deprecated_addCompileTimeError(
+ offset, "Not a constant expression.");
+ }
+ if (readTarget == null || isFieldOrGetter(readTarget)) {
+ return helper.buildMethodInvocation(buildSimpleRead(), callName,
+ arguments, offset + (readTarget?.name?.name?.length ?? 0),
+ // This isn't a constant expression, but we have checked if a
+ // constant expression error should be emitted already.
+ isConstantExpression: true,
+ isImplicitCall: true);
+ } else {
+ return helper.buildStaticInvocation(readTarget, arguments,
+ charOffset: offset);
+ }
+ }
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowStaticAssignment(rhs);
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", readTarget: ");
+ printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
+ sink.write(", writeTarget: ");
+ printQualifiedNameOn(writeTarget, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class LoadLibraryGenerator<Arguments> extends Generator<Arguments> {
+ final LoadLibraryBuilder builder;
+
+ LoadLibraryGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.builder)
+ : super(helper, token);
+
+ String get plainNameForRead => 'loadLibrary';
+
+ String get debugName => "LoadLibraryGenerator";
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ var read =
+ helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
+ complexAssignment?.read = read;
+ return read;
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ kernel.Expression write = makeInvalidWrite(value);
+ write.fileOffset = offsetForToken(token);
+ return write;
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ if (forest.argumentsPositional(arguments).length > 0 ||
+ forest.argumentsNamed(arguments).length > 0) {
+ helper.addProblemErrorIfConst(
+ messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
+ }
+ return builder.createLoadLibrary(offset, forest);
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", builder: ");
+ sink.write(builder);
+ }
+}
+
+class DeferredAccessGenerator<Arguments> extends Generator<Arguments> {
+ final PrefixBuilder builder;
+
+ final FastaAccessor accessor;
+
+ DeferredAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.builder, this.accessor)
+ : super(helper, token);
+
+ String get plainNameForRead {
+ return unsupported(
+ "deferredAccessor.plainNameForRead", offsetForToken(token), uri);
+ }
+
+ String get debugName => "DeferredAccessGenerator";
+
+ kernel.Expression _makeSimpleRead() {
+ return helper.wrapInDeferredCheck(
+ accessor._makeSimpleRead(), builder, token.charOffset);
+ }
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ return helper.wrapInDeferredCheck(
+ accessor._makeRead(complexAssignment), builder, token.charOffset);
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return helper.wrapInDeferredCheck(
+ accessor._makeWrite(value, voidContext, complexAssignment),
+ builder,
+ token.charOffset);
+ }
+
+ buildPropertyAccess(
+ IncompleteSend send, int operatorOffset, bool isNullAware) {
+ var propertyAccess =
+ accessor.buildPropertyAccess(send, operatorOffset, isNullAware);
+ if (propertyAccess is FastaAccessor) {
+ return new DeferredAccessGenerator(
+ helper, token, builder, propertyAccess);
+ } else {
+ kernel.Expression expression = propertyAccess;
+ return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
+ }
+ }
+
+ @override
+ DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+ {bool nonInstanceAccessIsError: false}) {
+ helper.addProblem(
+ templateDeferredTypeAnnotation.withArguments(
+ accessor.buildTypeWithBuiltArguments(arguments,
+ nonInstanceAccessIsError: nonInstanceAccessIsError),
+ builder.name),
+ offsetForToken(token),
+ lengthForToken(token));
+ return const InvalidType();
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.wrapInDeferredCheck(
+ accessor.doInvocation(offset, arguments), builder, token.charOffset);
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", builder: ");
+ sink.write(builder);
+ sink.write(", accessor: ");
+ sink.write(accessor);
+ }
+}
+
+class ReadOnlyAccessGenerator<Arguments> extends Generator<Arguments> {
+ final String plainNameForRead;
+
+ kernel.Expression expression;
+
+ VariableDeclaration value;
+
+ ReadOnlyAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.expression, this.plainNameForRead)
+ : super(helper, token);
+
+ String get debugName => "ReadOnlyAccessGenerator";
+
+ kernel.Expression _makeSimpleRead() => expression;
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ value ??= new VariableDeclaration.forValue(expression);
+ return new VariableGet(value);
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ var write = makeInvalidWrite(value);
+ complexAssignment?.write = write;
+ return write;
+ }
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) =>
+ super._finish(makeLet(value, body), complexAssignment);
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
+ adjustForImplicitCall(plainNameForRead, offset),
+ isImplicitCall: true);
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ NameSystem syntheticNames = new NameSystem();
+ sink.write(", expression: ");
+ printNodeOn(expression, sink, syntheticNames: syntheticNames);
+ sink.write(", plainNameForRead: ");
+ sink.write(plainNameForRead);
+ sink.write(", value: ");
+ printNodeOn(value, sink, syntheticNames: syntheticNames);
+ }
+}
+
+class LargeIntAccessGenerator<Arguments> extends Generator<Arguments> {
+ LargeIntAccessGenerator(
+ BuilderHelper<dynamic, dynamic, Arguments> helper, Token token)
+ : super(helper, token);
+
+ // TODO(ahe): This should probably be calling unhandled.
+ String get plainNameForRead => null;
+
+ String get debugName => "LargeIntAccessGenerator";
+
+ @override
+ kernel.Expression _makeSimpleRead() => buildError();
+
+ @override
+ kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return buildError();
+ }
+
+ @override
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ return buildError();
+ }
+
+ @override
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return buildError();
+ }
+
+ kernel.Expression buildError() {
+ return helper.buildCompileTimeError(
+ templateIntegerLiteralIsOutOfRange.withArguments(token),
+ offsetForToken(token),
+ lengthForToken(token));
+ }
+
+ @override
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return buildError();
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", lexeme: ");
+ sink.write(token.lexeme);
+ }
+}
+
+abstract class ErroneousExpressionGenerator<Arguments>
+ implements Generator<Arguments> {
+ /// Pass [arguments] that must be evaluated before throwing an error. At
+ /// most one of [isGetter] and [isSetter] should be true and they're passed
+ /// to [BuilderHelper.buildThrowNoSuchMethodError] if it is used.
+ kernel.Expression buildError(Arguments arguments,
+ {bool isGetter: false, bool isSetter: false, int offset});
+
+ DartType buildErroneousTypeNotAPrefix(Identifier suffix);
+
+ Name get name => unsupported("name", offsetForToken(token), uri);
+
+ @override
+ String get plainNameForRead => name.name;
+
+ withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
+
+ @override
+ Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+ return helper.buildInvalidInitializer(
+ buildError(forest.argumentsEmpty(noLocation), isSetter: true));
+ }
+
+ @override
+ doInvocation(int offset, Arguments arguments) {
+ return buildError(arguments, offset: offset);
+ }
+
+ @override
+ buildPropertyAccess(
+ IncompleteSend send, int operatorOffset, bool isNullAware) {
+ return this;
+ }
+
+ @override
+ buildThrowNoSuchMethodError(kernel.Expression receiver, Arguments arguments,
+ {bool isSuper: false,
+ bool isGetter: false,
+ bool isSetter: false,
+ bool isStatic: false,
+ String name,
+ int offset,
+ LocatedMessage argMessage}) {
+ return this;
+ }
+
+ @override
+ kernel.Expression buildAssignment(kernel.Expression value,
+ {bool voidContext: false}) {
+ return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
+ isSetter: true);
+ }
+
+ @override
+ kernel.Expression buildCompoundAssignment(
+ Name binaryOperator, kernel.Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false}) {
+ return buildError(forest.arguments(<kernel.Expression>[value], token),
+ isGetter: true);
+ }
+
+ @override
+ kernel.Expression buildPrefixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ // TODO(ahe): For the Analyzer, we probably need to build a prefix
+ // increment node that wraps an error.
+ return buildError(
+ forest.arguments(<kernel.Expression>[
+ storeOffset(forest.literalInt(1, null), offset)
+ ], noLocation),
+ isGetter: true);
+ }
+
+ @override
+ kernel.Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ // TODO(ahe): For the Analyzer, we probably need to build a post increment
+ // node that wraps an error.
+ return buildError(
+ forest.arguments(<kernel.Expression>[
+ storeOffset(forest.literalInt(1, null), offset)
+ ], noLocation),
+ isGetter: true);
+ }
+
+ @override
+ kernel.Expression buildNullAwareAssignment(
+ kernel.Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
+ isSetter: true);
+ }
+
+ @override
+ kernel.Expression buildSimpleRead() =>
+ buildError(forest.argumentsEmpty(noLocation), isGetter: true);
+
+ @override
+ kernel.Expression makeInvalidRead() =>
+ buildError(forest.argumentsEmpty(noLocation), isGetter: true);
+
+ @override
+ kernel.Expression makeInvalidWrite(kernel.Expression value) {
+ return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
+ isSetter: true);
+ }
+}
+
+class ThisAccessGenerator<Arguments> extends Generator<Arguments> {
+ final bool isInitializer;
+
+ final bool isSuper;
+
+ ThisAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.isInitializer,
+ {this.isSuper: false})
+ : super(helper, token);
+
+ String get plainNameForRead {
+ return unsupported("${isSuper ? 'super' : 'this'}.plainNameForRead",
+ offsetForToken(token), uri);
+ }
+
+ String get debugName => "ThisAccessGenerator";
+
+ kernel.Expression buildSimpleRead() {
+ if (!isSuper) {
+ return forest.thisExpression(token);
+ } else {
+ return helper.buildCompileTimeError(messageSuperAsExpression,
+ offsetForToken(token), lengthForToken(token));
+ }
+ }
+
+ @override
+ Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+ String keyword = isSuper ? "super" : "this";
+ int offset = offsetForToken(token);
+ return helper.buildInvalidInitializer(
+ helper.deprecated_buildCompileTimeError(
+ "Can't use '$keyword' here, did you mean '$keyword()'?", offset),
+ offset);
+ }
+
+ buildPropertyAccess(
+ IncompleteSend send, int operatorOffset, bool isNullAware) {
+ Name name = send.name;
+ Arguments arguments = send.arguments;
+ int offset = offsetForToken(send.token);
+ if (isInitializer && send is SendAccessor) {
+ if (isNullAware) {
+ helper.deprecated_addCompileTimeError(
+ operatorOffset, "Expected '.'\nTry removing '?'.");
+ }
+ return buildConstructorInitializer(offset, name, arguments);
+ }
+ Member getter = helper.lookupInstanceMember(name, isSuper: isSuper);
+ if (send is SendAccessor) {
+ // Notice that 'this' or 'super' can't be null. So we can ignore the
+ // value of [isNullAware].
+ if (getter == null) {
+ helper.warnUnresolvedMethod(name, offsetForToken(send.token),
+ isSuper: isSuper);
+ }
+ return helper.buildMethodInvocation(forest.thisExpression(null), name,
+ send.arguments, offsetForToken(send.token),
+ isSuper: isSuper, interfaceTarget: getter);
+ } else {
+ Member setter =
+ helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
+ if (isSuper) {
+ return new SuperPropertyAccessGenerator(
+ helper, send.token, name, getter, setter);
+ } else {
+ return new ThisPropertyAccessGenerator(
+ helper, send.token, name, getter, setter);
+ }
+ }
+ }
+
+ doInvocation(int offset, Arguments arguments) {
+ if (isInitializer) {
+ return buildConstructorInitializer(offset, new Name(""), arguments);
+ } else if (isSuper) {
+ return helper.buildCompileTimeError(
+ messageSuperAsExpression, offset, noLength);
+ } else {
+ return helper.buildMethodInvocation(
+ forest.thisExpression(null), callName, arguments, offset,
+ isImplicitCall: true);
+ }
+ }
+
+ Initializer buildConstructorInitializer(
+ int offset, Name name, Arguments arguments) {
+ Constructor constructor = helper.lookupConstructor(name, isSuper: isSuper);
+ LocatedMessage argMessage;
+ if (constructor != null) {
+ argMessage = helper.checkArguments(
+ new FunctionTypeAccessor.fromNode(constructor.function),
+ arguments,
+ CalleeDesignation.Constructor,
+ offset, <TypeParameter>[]);
+ }
+ if (constructor == null || argMessage != null) {
+ return helper.buildInvalidInitializer(
+ buildThrowNoSuchMethodError(
+ storeOffset(forest.literalNull(null), offset), arguments,
+ isSuper: isSuper,
+ name: name.name,
+ offset: offset,
+ argMessage: argMessage),
+ offset);
+ } else if (isSuper) {
+ return helper.buildSuperInitializer(
+ false, constructor, arguments, offset);
+ } else {
+ return helper.buildRedirectingInitializer(constructor, arguments, offset);
+ }
+ }
+
+ kernel.Expression buildAssignment(kernel.Expression value,
+ {bool voidContext: false}) {
+ return buildAssignmentError();
+ }
+
+ kernel.Expression buildNullAwareAssignment(
+ kernel.Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return buildAssignmentError();
+ }
+
+ kernel.Expression buildCompoundAssignment(
+ Name binaryOperator, kernel.Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false}) {
+ return buildAssignmentError();
+ }
+
+ kernel.Expression buildPrefixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ return buildAssignmentError();
+ }
+
+ kernel.Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ return buildAssignmentError();
+ }
+
+ kernel.Expression buildAssignmentError() {
+ String message =
+ isSuper ? "Can't assign to 'super'." : "Can't assign to 'this'.";
+ return helper.deprecated_buildCompileTimeError(
+ message, offsetForToken(token));
+ }
+
+ @override
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ return unimplemented("_makeRead", offsetForToken(token), uri);
+ }
+
+ @override
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return unimplemented("_makeWrite", offsetForToken(token), uri);
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", isInitializer: ");
+ sink.write(isInitializer);
+ sink.write(", isSuper: ");
+ sink.write(isSuper);
+ }
+}
+
+kernel.Expression makeLet(
+ VariableDeclaration variable, kernel.Expression body) {
+ if (variable == null) return body;
+ return new Let(variable, body);
+}
+
+kernel.Expression makeBinary<Arguments>(
+ kernel.Expression left,
+ Name operator,
+ Procedure interfaceTarget,
+ kernel.Expression right,
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ {int offset: TreeNode.noOffset}) {
+ return new ShadowMethodInvocation(
+ left,
+ operator,
+ helper.storeOffset(
+ helper.forest.castArguments(
+ helper.forest.arguments(<kernel.Expression>[right], null)),
+ offset),
+ interfaceTarget: interfaceTarget)
+ ..fileOffset = offset;
+}
+
+kernel.Expression buildIsNull<Arguments>(kernel.Expression value, int offset,
+ BuilderHelper<dynamic, dynamic, Arguments> helper) {
+ return makeBinary(value, equalsName, null,
+ helper.storeOffset(helper.forest.literalNull(null), offset), helper,
+ offset: offset);
+}
+
+VariableDeclaration makeOrReuseVariable(kernel.Expression value) {
+ // TODO: Devise a way to remember if a variable declaration was reused
+ // or is fresh (hence needs a let binding).
+ return new VariableDeclaration.forValue(value);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_impl.dart
new file mode 100644
index 0000000..603841f
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_impl.dart
@@ -0,0 +1,730 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of 'expression_generator.dart';
+
+abstract class BuilderHelper<Expression, Statement, Arguments> {
+ LibraryBuilder get library;
+
+ Uri get uri;
+
+ TypePromoter get typePromoter;
+
+ int get functionNestingLevel;
+
+ ConstantContext get constantContext;
+
+ Forest<Expression, Statement, Token, Arguments> get forest;
+
+ Constructor lookupConstructor(Name name, {bool isSuper});
+
+ Expression toValue(node);
+
+ Member lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
+
+ scopeLookup(Scope scope, String name, Token token,
+ {bool isQualified: false, PrefixBuilder prefix});
+
+ finishSend(Object receiver, Arguments arguments, int offset);
+
+ Expression buildCompileTimeError(Message message, int charOffset, int length,
+ {List<LocatedMessage> context});
+
+ Expression wrapInCompileTimeError(Expression expression, Message message);
+
+ Expression deprecated_buildCompileTimeError(String error, [int offset]);
+
+ Initializer buildInvalidInitializer(Expression expression, [int offset]);
+
+ Initializer buildFieldInitializer(
+ bool isSynthetic, String name, int offset, Expression expression);
+
+ Initializer buildSuperInitializer(
+ bool isSynthetic, Constructor constructor, Arguments arguments,
+ [int offset]);
+
+ Initializer buildRedirectingInitializer(
+ Constructor constructor, Arguments arguments,
+ [int charOffset = -1]);
+
+ Expression buildStaticInvocation(Procedure target, Arguments arguments,
+ {Constness constness, int charOffset, Member initialTarget});
+
+ Expression buildProblemExpression(
+ ProblemBuilder builder, int offset, int length);
+
+ Expression throwNoSuchMethodError(
+ Expression receiver, String name, Arguments arguments, int offset,
+ {Member candidate,
+ bool isSuper,
+ bool isGetter,
+ bool isSetter,
+ bool isStatic,
+ LocatedMessage argMessage});
+
+ LocatedMessage checkArguments(FunctionTypeAccessor function,
+ Arguments arguments, CalleeDesignation calleeKind, int offset,
+ [List<TypeParameter> typeParameters]);
+
+ StaticGet makeStaticGet(Member readTarget, Token token);
+
+ Expression wrapInDeferredCheck(
+ Expression expression, KernelPrefixBuilder prefix, int charOffset);
+
+ dynamic deprecated_addCompileTimeError(int charOffset, String message);
+
+ bool isIdentical(Member member);
+
+ Expression buildMethodInvocation(
+ Expression receiver, Name name, Arguments arguments, int offset,
+ {bool isConstantExpression,
+ bool isNullAware,
+ bool isImplicitCall,
+ bool isSuper,
+ Member interfaceTarget});
+
+ Expression buildConstructorInvocation(
+ TypeDeclarationBuilder type,
+ Token nameToken,
+ Arguments arguments,
+ String name,
+ List<DartType> typeArguments,
+ int charOffset,
+ Constness constness);
+
+ DartType validatedTypeVariableUse(
+ TypeParameterType type, int offset, bool nonInstanceAccessIsError);
+
+ void addProblem(Message message, int charOffset, int length);
+
+ void addProblemErrorIfConst(Message message, int charOffset, int length);
+
+ Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
+
+ Message warnUnresolvedSet(Name name, int charOffset, {bool isSuper});
+
+ Message warnUnresolvedMethod(Name name, int charOffset, {bool isSuper});
+
+ void warnTypeArgumentsMismatch(String name, int expected, int charOffset);
+
+ T storeOffset<T>(T node, int offset);
+}
+
+// The name used to refer to a call target kind
+enum CalleeDesignation { Function, Method, Constructor }
+
+// Abstraction over FunctionNode and FunctionType to access the
+// number and names of parameters.
+class FunctionTypeAccessor {
+ int requiredParameterCount;
+ int positionalParameterCount;
+
+ List _namedParameters;
+
+ Set<String> get namedParameterNames {
+ return new Set.from(_namedParameters.map((a) => a.name));
+ }
+
+ factory FunctionTypeAccessor.fromNode(FunctionNode node) {
+ return new FunctionTypeAccessor._(node.requiredParameterCount,
+ node.positionalParameters.length, node.namedParameters);
+ }
+
+ factory FunctionTypeAccessor.fromType(FunctionType type) {
+ return new FunctionTypeAccessor._(type.requiredParameterCount,
+ type.positionalParameters.length, type.namedParameters);
+ }
+
+ FunctionTypeAccessor._(this.requiredParameterCount,
+ this.positionalParameterCount, this._namedParameters);
+}
+
+// TODO(ahe): Merge this into [Generator] when all uses have been updated.
+abstract class FastaAccessor<Arguments> implements Accessor<Arguments> {
+ BuilderHelper<dynamic, dynamic, Arguments> get helper;
+
+ // TODO(ahe): Change type arguments.
+ Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
+ helper.forest;
+
+ String get plainNameForRead;
+
+ String get debugName;
+
+ Uri get uri => helper.uri;
+
+ String get plainNameForWrite => plainNameForRead;
+
+ bool get isInitializer => false;
+
+ T storeOffset<T>(T node, int offset) {
+ return helper.storeOffset(node, offset);
+ }
+
+ kernel.Expression buildForEffect() => buildSimpleRead();
+
+ Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+ int offset = offsetForToken(token);
+ return helper.buildInvalidInitializer(
+ helper.buildCompileTimeError(
+ messageInvalidInitializer, offset, lengthForToken(token)),
+ offset);
+ }
+
+ kernel.Expression makeInvalidRead() {
+ return buildThrowNoSuchMethodError(
+ forest.literalNull(token), forest.argumentsEmpty(noLocation),
+ isGetter: true);
+ }
+
+ kernel.Expression makeInvalidWrite(kernel.Expression value) {
+ return buildThrowNoSuchMethodError(forest.literalNull(token),
+ forest.arguments(<kernel.Expression>[value], noLocation),
+ isSetter: true);
+ }
+
+ /* kernel.Expression | FastaAccessor | Initializer */ doInvocation(
+ int offset, Arguments arguments);
+
+ /* kernel.Expression | FastaAccessor */ buildPropertyAccess(
+ IncompleteSend send, int operatorOffset, bool isNullAware) {
+ if (send is SendAccessor) {
+ return helper.buildMethodInvocation(buildSimpleRead(), send.name,
+ send.arguments, offsetForToken(send.token),
+ isNullAware: isNullAware);
+ } else {
+ if (helper.constantContext != ConstantContext.none &&
+ send.name != lengthName) {
+ helper.deprecated_addCompileTimeError(
+ offsetForToken(token), "Not a constant expression.");
+ }
+ return PropertyAccessGenerator.make(helper, send.token, buildSimpleRead(),
+ send.name, null, null, isNullAware);
+ }
+ }
+
+ DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+ {bool nonInstanceAccessIsError: false}) {
+ helper.addProblem(templateNotAType.withArguments(token.lexeme),
+ offsetForToken(token), lengthForToken(token));
+ return const InvalidType();
+ }
+
+ /* kernel.Expression | FastaAccessor */ buildThrowNoSuchMethodError(
+ kernel.Expression receiver, Arguments arguments,
+ {bool isSuper: false,
+ bool isGetter: false,
+ bool isSetter: false,
+ bool isStatic: false,
+ String name,
+ int offset,
+ LocatedMessage argMessage}) {
+ return helper.throwNoSuchMethodError(receiver, name ?? plainNameForWrite,
+ arguments, offset ?? offsetForToken(this.token),
+ isGetter: isGetter,
+ isSetter: isSetter,
+ isSuper: isSuper,
+ isStatic: isStatic,
+ argMessage: argMessage);
+ }
+
+ bool get isThisPropertyAccess => false;
+
+ @override
+ ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+ new ShadowIllegalAssignment(rhs);
+
+ void printOn(StringSink sink);
+
+ String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write(debugName);
+ buffer.write("(offset: ");
+ buffer.write("${offsetForToken(token)}");
+ printOn(buffer);
+ buffer.write(")");
+ return "$buffer";
+ }
+}
+
+abstract class GeneratorImpl {
+ Token get token;
+
+ Uri get uri;
+
+ kernel.Expression _finish(
+ kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+ return unimplemented("_finish", offsetForToken(token), uri);
+ }
+
+ kernel.Expression _makeSimpleRead() {
+ return unimplemented("_makeSimpleRead", offsetForToken(token), uri);
+ }
+
+ kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return unimplemented("_makeSimpleWrite", offsetForToken(token), uri);
+ }
+
+ kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ return unimplemented("_makeRead", offsetForToken(token), uri);
+ }
+
+ kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return unimplemented("_makeWrite", offsetForToken(token), uri);
+ }
+}
+
+abstract class IncompleteSend<Arguments> extends FastaAccessor<Arguments>
+ with GeneratorImpl {
+ final BuilderHelper<dynamic, dynamic, Arguments> helper;
+
+ @override
+ final Token token;
+
+ final Name name;
+
+ IncompleteSend(this.helper, this.token, this.name);
+
+ withReceiver(Object receiver, int operatorOffset, {bool isNullAware});
+
+ Arguments get arguments => null;
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", name: ");
+ sink.write(name.name);
+ }
+}
+
+class IncompleteError<Arguments> extends IncompleteSend<Arguments>
+ with ErroneousExpressionGenerator<Arguments> {
+ final Message message;
+
+ IncompleteError(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, this.message)
+ : super(helper, token, null);
+
+ String get debugName => "IncompleteError";
+
+ @override
+ kernel.Expression buildError(Arguments arguments,
+ {bool isGetter: false, bool isSetter: false, int offset}) {
+ int length = noLength;
+ if (offset == null) {
+ offset = offsetForToken(token);
+ length = lengthForToken(token);
+ }
+ return helper.buildCompileTimeError(message, offset, length);
+ }
+
+ @override
+ DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
+ helper.addProblem(
+ templateNotAPrefixInTypeAnnotation.withArguments(
+ token.lexeme, suffix.name),
+ offsetForToken(token),
+ lengthOfSpan(token, suffix.token));
+ return const InvalidType();
+ }
+
+ @override
+ doInvocation(int offset, Arguments arguments) => this;
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", message: ");
+ sink.write(message.code.name);
+ }
+}
+
+class SendAccessor<Arguments> extends IncompleteSend<Arguments> {
+ @override
+ final Arguments arguments;
+
+ SendAccessor(BuilderHelper<dynamic, dynamic, Arguments> helper, Token token,
+ Name name, this.arguments)
+ : super(helper, token, name) {
+ assert(arguments != null);
+ }
+
+ String get plainNameForRead => name.name;
+
+ String get debugName => "SendAccessor";
+
+ kernel.Expression buildSimpleRead() {
+ return unsupported("buildSimpleRead", offsetForToken(token), uri);
+ }
+
+ kernel.Expression buildAssignment(kernel.Expression value,
+ {bool voidContext: false}) {
+ return unsupported("buildAssignment", offsetForToken(token), uri);
+ }
+
+ withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
+ if (receiver is FastaAccessor) {
+ return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
+ }
+ if (receiver is PrefixBuilder) {
+ PrefixBuilder prefix = receiver;
+ if (isNullAware) {
+ helper.deprecated_addCompileTimeError(
+ offsetForToken(token),
+ "Library prefix '${prefix.name}' can't be used with null-aware "
+ "operator.\nTry removing '?'.");
+ }
+ receiver = helper.scopeLookup(prefix.exportScope, name.name, token,
+ isQualified: true, prefix: prefix);
+ return helper.finishSend(receiver, arguments, offsetForToken(token));
+ }
+ return helper.buildMethodInvocation(
+ helper.toValue(receiver), name, arguments, offsetForToken(token),
+ isNullAware: isNullAware);
+ }
+
+ kernel.Expression buildNullAwareAssignment(
+ kernel.Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return unsupported("buildNullAwareAssignment", offset, uri);
+ }
+
+ kernel.Expression buildCompoundAssignment(
+ Name binaryOperator, kernel.Expression value,
+ {int offset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false}) {
+ return unsupported(
+ "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
+ }
+
+ kernel.Expression buildPrefixIncrement(Name binaryOperator,
+ {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+ return unsupported(
+ "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
+ }
+
+ kernel.Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+ return unsupported(
+ "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return unsupported("doInvocation", offset, uri);
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ super.printOn(sink);
+ sink.write(", arguments: ");
+ var node = arguments;
+ if (node is kernel.Node) {
+ printNodeOn(node, sink);
+ } else {
+ sink.write(node);
+ }
+ }
+}
+
+class IncompletePropertyAccessor<Arguments> extends IncompleteSend<Arguments> {
+ IncompletePropertyAccessor(
+ BuilderHelper<dynamic, dynamic, Arguments> helper, Token token, Name name)
+ : super(helper, token, name);
+
+ String get plainNameForRead => name.name;
+
+ String get debugName => "IncompletePropertyAccessor";
+
+ kernel.Expression buildSimpleRead() {
+ return unsupported("buildSimpleRead", offsetForToken(token), uri);
+ }
+
+ kernel.Expression buildAssignment(kernel.Expression value,
+ {bool voidContext: false}) {
+ return unsupported("buildAssignment", offsetForToken(token), uri);
+ }
+
+ withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
+ if (receiver is FastaAccessor) {
+ return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
+ }
+ if (receiver is PrefixBuilder) {
+ PrefixBuilder prefix = receiver;
+ if (isNullAware) {
+ helper.deprecated_addCompileTimeError(
+ offsetForToken(token),
+ "Library prefix '${prefix.name}' can't be used with null-aware "
+ "operator.\nTry removing '?'.");
+ }
+ return helper.scopeLookup(prefix.exportScope, name.name, token,
+ isQualified: true, prefix: prefix);
+ }
+
+ return PropertyAccessGenerator.make(
+ helper, token, helper.toValue(receiver), name, null, null, isNullAware);
+ }
+
+ kernel.Expression buildNullAwareAssignment(
+ kernel.Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return unsupported("buildNullAwareAssignment", offset, uri);
+ }
+
+ kernel.Expression buildCompoundAssignment(
+ Name binaryOperator, kernel.Expression value,
+ {int offset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false}) {
+ return unsupported(
+ "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
+ }
+
+ kernel.Expression buildPrefixIncrement(Name binaryOperator,
+ {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+ return unsupported(
+ "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
+ }
+
+ kernel.Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+ return unsupported(
+ "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
+ }
+
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return unsupported("doInvocation", offset, uri);
+ }
+}
+
+int adjustForImplicitCall(String name, int offset) {
+ // Normally the offset is at the start of the token, but in this case,
+ // because we insert a '.call', we want it at the end instead.
+ return offset + (name?.length ?? 0);
+}
+
+class ParenthesizedExpression<Arguments>
+ extends ReadOnlyAccessGenerator<Arguments> {
+ ParenthesizedExpression(BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token, kernel.Expression expression)
+ : super(helper, token, expression, null);
+
+ String get debugName => "ParenthesizedExpression";
+
+ kernel.Expression makeInvalidWrite(kernel.Expression value) {
+ return helper.deprecated_buildCompileTimeError(
+ "Can't assign to a parenthesized expression.", offsetForToken(token));
+ }
+}
+
+class TypeDeclarationAccessor<Arguments>
+ extends ReadOnlyAccessGenerator<Arguments> {
+ /// The import prefix preceding the [declaration] reference, or `null` if
+ /// the reference is not prefixed.
+ final PrefixBuilder prefix;
+
+ /// The offset at which the [declaration] is referenced by this accessor,
+ /// or `-1` if the reference is implicit.
+ final int declarationReferenceOffset;
+
+ final TypeDeclarationBuilder declaration;
+
+ TypeDeclarationAccessor(
+ BuilderHelper<dynamic, dynamic, Arguments> helper,
+ Token token,
+ this.prefix,
+ this.declarationReferenceOffset,
+ this.declaration,
+ String plainNameForRead)
+ : super(helper, token, null, plainNameForRead);
+
+ String get debugName => "TypeDeclarationAccessor";
+
+ kernel.Expression get expression {
+ if (super.expression == null) {
+ int offset = offsetForToken(token);
+ if (declaration is KernelInvalidTypeBuilder) {
+ KernelInvalidTypeBuilder declaration = this.declaration;
+ helper.addProblemErrorIfConst(
+ declaration.message.messageObject, offset, token.length);
+ super.expression =
+ new Throw(forest.literalString(declaration.message.message, token))
+ ..fileOffset = offset;
+ } else {
+ super.expression = forest.literalType(
+ buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
+ token);
+ }
+ }
+ return super.expression;
+ }
+
+ kernel.Expression makeInvalidWrite(kernel.Expression value) {
+ return buildThrowNoSuchMethodError(
+ forest.literalNull(token),
+ storeOffset(forest.arguments(<kernel.Expression>[value], null),
+ value.fileOffset),
+ isSetter: true);
+ }
+
+ @override
+ buildPropertyAccess(
+ IncompleteSend send, int operatorOffset, bool isNullAware) {
+ // `SomeType?.toString` is the same as `SomeType.toString`, not
+ // `(SomeType).toString`.
+ isNullAware = false;
+
+ Name name = send.name;
+ Arguments arguments = send.arguments;
+
+ if (declaration is KernelClassBuilder) {
+ KernelClassBuilder declaration = this.declaration;
+ Builder builder = declaration.findStaticBuilder(
+ name.name, offsetForToken(token), uri, helper.library);
+
+ FastaAccessor accessor;
+ if (builder == null) {
+ // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
+ if (send is IncompletePropertyAccessor) {
+ accessor = new UnresolvedAccessor(helper, send.token, name);
+ } else {
+ return helper.buildConstructorInvocation(declaration, send.token,
+ arguments, name.name, null, token.charOffset, Constness.implicit);
+ }
+ } else {
+ Builder setter;
+ if (builder.isSetter) {
+ setter = builder;
+ } else if (builder.isGetter) {
+ setter = declaration.findStaticBuilder(
+ name.name, offsetForToken(token), uri, helper.library,
+ isSetter: true);
+ } else if (builder.isField && !builder.isFinal) {
+ setter = builder;
+ }
+ accessor = new StaticAccessGenerator.fromBuilder(
+ helper, builder, send.token, setter);
+ }
+
+ return arguments == null
+ ? accessor
+ : accessor.doInvocation(offsetForToken(send.token), arguments);
+ } else {
+ return super.buildPropertyAccess(send, operatorOffset, isNullAware);
+ }
+ }
+
+ @override
+ DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+ {bool nonInstanceAccessIsError: false}) {
+ if (arguments != null) {
+ int expected = 0;
+ if (declaration is KernelClassBuilder) {
+ expected = declaration.target.typeParameters.length;
+ } else if (declaration is FunctionTypeAliasBuilder) {
+ expected = declaration.target.typeParameters.length;
+ } else if (declaration is KernelTypeVariableBuilder) {
+ // Type arguments on a type variable - error reported elsewhere.
+ } else if (declaration is BuiltinTypeBuilder) {
+ // Type arguments on a built-in type, for example, dynamic or void.
+ expected = 0;
+ } else {
+ return unhandled(
+ "${declaration.runtimeType}",
+ "TypeDeclarationAccessor.buildType",
+ offsetForToken(token),
+ helper.uri);
+ }
+ if (arguments.length != expected) {
+ helper.warnTypeArgumentsMismatch(
+ declaration.name, expected, offsetForToken(token));
+ // We ignore the provided arguments, which will in turn return the
+ // raw type below.
+ // TODO(sigmund): change to use an InvalidType and include the raw type
+ // as a recovery node once the IR can represent it (Issue #29840).
+ arguments = null;
+ }
+ }
+
+ DartType type;
+ if (arguments == null) {
+ TypeDeclarationBuilder typeDeclaration = declaration;
+ if (typeDeclaration is KernelClassBuilder) {
+ type = typeDeclaration.buildType(helper.library, null);
+ } else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
+ type = typeDeclaration.buildType(helper.library, null);
+ }
+ }
+ if (type == null) {
+ type =
+ declaration.buildTypesWithBuiltArguments(helper.library, arguments);
+ }
+ if (type is TypeParameterType) {
+ return helper.validatedTypeVariableUse(
+ type, offsetForToken(token), nonInstanceAccessIsError);
+ }
+ return type;
+ }
+
+ @override
+ kernel.Expression doInvocation(int offset, Arguments arguments) {
+ return helper.buildConstructorInvocation(declaration, token, arguments, "",
+ null, token.charOffset, Constness.implicit);
+ }
+}
+
+class UnresolvedAccessor<Arguments> extends FastaAccessor<Arguments>
+ with GeneratorImpl, ErroneousExpressionGenerator<Arguments> {
+ @override
+ final Token token;
+
+ @override
+ final BuilderHelper<dynamic, dynamic, Arguments> helper;
+
+ @override
+ final Name name;
+
+ UnresolvedAccessor(this.helper, this.token, this.name);
+
+ String get debugName => "UnresolvedAccessor";
+
+ kernel.Expression doInvocation(int charOffset, Arguments arguments) {
+ return buildError(arguments, offset: charOffset);
+ }
+
+ @override
+ DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
+ helper.addProblem(
+ templateUnresolvedPrefixInTypeAnnotation.withArguments(
+ name.name, suffix.name),
+ offsetForToken(token),
+ lengthOfSpan(token, suffix.token));
+ return const InvalidType();
+ }
+
+ @override
+ kernel.Expression buildError(Arguments arguments,
+ {bool isGetter: false, bool isSetter: false, int offset}) {
+ offset ??= offsetForToken(this.token);
+ return helper.throwNoSuchMethodError(
+ storeOffset(forest.literalNull(null), offset),
+ plainNameForRead,
+ arguments,
+ offset,
+ isGetter: isGetter,
+ isSetter: isSetter);
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", name: ");
+ sink.write(name.name);
+ }
+}
+
+bool isFieldOrGetter(Member member) {
+ return member is Field || (member is Procedure && member.isGetter);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 7dbebfe..8f539a0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -9,20 +9,31 @@
import 'package:kernel/ast.dart'
show
Arguments,
+ BreakStatement,
+ Block,
+ Catch,
+ ContinueSwitchStatement,
DartType,
+ EmptyStatement,
Expression,
ExpressionStatement,
InvalidExpression,
+ LabeledStatement,
Let,
LibraryDependency,
MapEntry,
NamedExpression,
Statement,
+ SwitchCase,
+ ThisExpression,
TreeNode,
- VariableDeclaration;
+ VariableDeclaration,
+ setParents;
import '../parser.dart' show offsetForToken;
+import '../problems.dart' show unsupported;
+
import '../scanner.dart' show Token;
import 'kernel_shadow_ast.dart'
@@ -30,24 +41,36 @@
ShadowArguments,
ShadowAsExpression,
ShadowAwaitExpression,
+ ShadowBlock,
ShadowBoolLiteral,
ShadowCheckLibraryIsLoaded,
ShadowConditionalExpression,
+ ShadowDoStatement,
ShadowDoubleLiteral,
+ ShadowExpressionStatement,
+ ShadowIfStatement,
ShadowIntLiteral,
ShadowIsExpression,
ShadowIsNotExpression,
+ ShadowLabeledStatement,
ShadowListLiteral,
ShadowLoadLibrary,
ShadowMapLiteral,
ShadowNot,
ShadowNullLiteral,
+ ShadowRethrow,
+ ShadowReturnStatement,
ShadowStringConcatenation,
ShadowStringLiteral,
ShadowSymbolLiteral,
ShadowSyntheticExpression,
ShadowThisExpression,
- ShadowTypeLiteral;
+ ShadowThrow,
+ ShadowTryCatch,
+ ShadowTryFinally,
+ ShadowTypeLiteral,
+ ShadowWhileStatement,
+ ShadowYieldStatement;
import 'forest.dart' show Forest;
@@ -149,8 +172,13 @@
}
@override
- ShadowSymbolLiteral literalSymbol(String value, Token token) {
- return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(token);
+ ShadowSymbolLiteral literalSymbolMultiple(String value, Token hash, _) {
+ return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(hash);
+ }
+
+ @override
+ ShadowSymbolLiteral literalSymbolSingluar(String value, Token hash, _) {
+ return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(hash);
}
@override
@@ -200,6 +228,23 @@
}
@override
+ Statement block(
+ Token openBrace, List<Statement> statements, Token closeBrace) {
+ List<Statement> copy;
+ for (int i = 0; i < statements.length; i++) {
+ Statement statement = statements[i];
+ if (statement is _VariablesDeclaration) {
+ copy ??= new List<Statement>.from(statements.getRange(0, i));
+ copy.addAll(statement.declarations);
+ } else if (copy != null) {
+ copy.add(statement);
+ }
+ }
+ return new ShadowBlock(copy ?? statements)
+ ..fileOffset = offsetForToken(openBrace);
+ }
+
+ @override
Expression conditionalExpression(Expression condition, Token question,
Expression thenExpression, Token colon, Expression elseExpression) {
return new ShadowConditionalExpression(
@@ -208,6 +253,29 @@
}
@override
+ Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
+ Expression condition, Token semicolon) {
+ return new ShadowDoStatement(body, condition)
+ ..fileOffset = doKeyword.charOffset;
+ }
+
+ Statement expressionStatement(Expression expression, Token semicolon) {
+ return new ShadowExpressionStatement(expression);
+ }
+
+ @override
+ Statement emptyStatement(Token semicolon) {
+ return new EmptyStatement();
+ }
+
+ @override
+ Statement ifStatement(Token ifKeyword, Expression condition,
+ Statement thenStatement, Token elseKeyword, Statement elseStatement) {
+ return new ShadowIfStatement(condition, thenStatement, elseStatement)
+ ..fileOffset = ifKeyword.charOffset;
+ }
+
+ @override
Expression isExpression(
Expression operand, isOperator, Token notOperator, covariant type) {
int offset = offsetForToken(isOperator);
@@ -223,6 +291,25 @@
}
@override
+ Object parenthesizedCondition(
+ Token leftParenthesis, Expression expression, Token rightParenthesis) {
+ return expression;
+ }
+
+ @override
+ Statement rethrowStatement(Token rethrowKeyword, Token semicolon) {
+ return new ShadowExpressionStatement(
+ new ShadowRethrow()..fileOffset = offsetForToken(rethrowKeyword));
+ }
+
+ @override
+ Statement returnStatement(
+ Token returnKeyword, Expression expression, Token semicolon) {
+ return new ShadowReturnStatement(expression)
+ ..fileOffset = returnKeyword.charOffset;
+ }
+
+ @override
Expression stringConcatenationExpression(
List<Expression> expressions, Token token) {
return new ShadowStringConcatenation(expressions)
@@ -230,12 +317,78 @@
}
@override
+ Statement syntheticLabeledStatement(Statement statement) {
+ return new ShadowLabeledStatement(statement);
+ }
+
+ @override
Expression thisExpression(Token token) {
return new ShadowThisExpression()..fileOffset = offsetForToken(token);
}
@override
- bool isErroneousNode(TreeNode node) {
+ Expression throwExpression(Token throwKeyword, Expression expression) {
+ return new ShadowThrow(expression)
+ ..fileOffset = offsetForToken(throwKeyword);
+ }
+
+ @override
+ Statement tryStatement(Token tryKeyword, Statement body,
+ List<Catch> catchClauses, Token finallyKeyword, Statement finallyBlock) {
+ Statement tryStatement = body;
+ if (catchClauses != null) {
+ tryStatement = new ShadowTryCatch(tryStatement, catchClauses);
+ }
+ if (finallyBlock != null) {
+ tryStatement = new ShadowTryFinally(tryStatement, finallyBlock);
+ }
+ return tryStatement;
+ }
+
+ @override
+ _VariablesDeclaration variablesDeclaration(
+ List<VariableDeclaration> declarations, Uri uri) {
+ return new _VariablesDeclaration(declarations, uri);
+ }
+
+ @override
+ List<VariableDeclaration> variablesDeclarationExtractDeclarations(
+ _VariablesDeclaration variablesDeclaration) {
+ return variablesDeclaration.declarations;
+ }
+
+ @override
+ Statement wrapVariables(Statement statement) {
+ if (statement is _VariablesDeclaration) {
+ return new ShadowBlock(statement.declarations)
+ ..fileOffset = statement.fileOffset;
+ } else if (statement is VariableDeclaration) {
+ return new ShadowBlock(<Statement>[statement])
+ ..fileOffset = statement.fileOffset;
+ } else {
+ return statement;
+ }
+ }
+
+ @override
+ Statement whileStatement(
+ Token whileKeyword, Expression condition, Statement body) {
+ return new ShadowWhileStatement(condition, body)
+ ..fileOffset = whileKeyword.charOffset;
+ }
+
+ @override
+ Statement yieldStatement(
+ Token yieldKeyword, Token star, Expression expression, Token semicolon) {
+ return new ShadowYieldStatement(expression, isYieldStar: star != null)
+ ..fileOffset = yieldKeyword.charOffset;
+ }
+
+ @override
+ bool isBlock(Object node) => node is Block;
+
+ @override
+ bool isErroneousNode(Object node) {
if (node is ExpressionStatement) {
ExpressionStatement statement = node;
node = statement.expression;
@@ -254,4 +407,55 @@
}
return node is InvalidExpression;
}
+
+ @override
+ bool isThisExpression(Object node) => node is ThisExpression;
+
+ @override
+ bool isVariablesDeclaration(Object node) => node is _VariablesDeclaration;
+
+ @override
+ void resolveBreak(LabeledStatement target, BreakStatement user) {
+ user.target = target;
+ }
+
+ @override
+ void resolveContinue(LabeledStatement target, BreakStatement user) {
+ user.target = target;
+ }
+
+ @override
+ void resolveContinueInSwitch(
+ SwitchCase target, ContinueSwitchStatement user) {
+ user.target = target;
+ }
+}
+
+class _VariablesDeclaration extends Statement {
+ final List<VariableDeclaration> declarations;
+ final Uri uri;
+
+ _VariablesDeclaration(this.declarations, this.uri) {
+ setParents(declarations, this);
+ }
+
+ @override
+ accept(v) {
+ unsupported("accept", fileOffset, uri);
+ }
+
+ @override
+ accept1(v, arg) {
+ unsupported("accept1", fileOffset, uri);
+ }
+
+ @override
+ visitChildren(v) {
+ unsupported("visitChildren", fileOffset, uri);
+ }
+
+ @override
+ transformChildren(v) {
+ unsupported("transformChildren", fileOffset, uri);
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
deleted file mode 100644
index 25ddc28..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ /dev/null
@@ -1,1391 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library fasta.fasta_accessors;
-
-import '../../scanner/token.dart' show Token;
-
-import '../constant_context.dart' show ConstantContext;
-
-import '../fasta_codes.dart'
- show
- LocatedMessage,
- messageInvalidInitializer,
- messageLoadLibraryTakesNoArguments,
- messageSuperAsExpression,
- templateDeferredTypeAnnotation,
- templateIntegerLiteralIsOutOfRange,
- templateNotAPrefixInTypeAnnotation,
- templateNotAType,
- templateUnresolvedPrefixInTypeAnnotation;
-
-import '../messages.dart' show Message, noLength;
-
-import '../names.dart' show callName, lengthName;
-
-import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
-
-import '../problems.dart' show unhandled, unimplemented, unsupported;
-
-import '../scope.dart' show AccessErrorBuilder, ProblemBuilder, Scope;
-
-import '../type_inference/type_promotion.dart' show TypePromoter;
-
-import 'body_builder.dart' show Identifier, noLocation;
-
-import 'constness.dart' show Constness;
-
-import 'forest.dart' show Forest;
-
-import 'frontend_accessors.dart' as kernel
- show
- IndexAccessor,
- NullAwarePropertyAccessor,
- LoadLibraryAccessor,
- PropertyAccessor,
- ReadOnlyAccessor,
- DeferredAccessor,
- DelayedErrorAccessor,
- StaticAccessor,
- SuperIndexAccessor,
- SuperPropertyAccessor,
- ThisIndexAccessor,
- ThisPropertyAccessor,
- VariableAccessor;
-
-import 'frontend_accessors.dart' show Accessor;
-
-import 'kernel_ast_api.dart' hide Expression, Statement;
-
-import 'kernel_ast_api.dart' as kernel show Expression, Statement;
-
-import 'kernel_builder.dart'
- show
- Builder,
- BuiltinTypeBuilder,
- FunctionTypeAliasBuilder,
- KernelClassBuilder,
- KernelFunctionTypeAliasBuilder,
- KernelInvalidTypeBuilder,
- KernelPrefixBuilder,
- KernelTypeVariableBuilder,
- LibraryBuilder,
- LoadLibraryBuilder,
- PrefixBuilder,
- TypeDeclarationBuilder;
-
-abstract class BuilderHelper<Expression, Statement, Arguments> {
- LibraryBuilder get library;
-
- Uri get uri;
-
- TypePromoter get typePromoter;
-
- int get functionNestingLevel;
-
- ConstantContext get constantContext;
-
- Forest<Expression, Statement, Token, Arguments> get forest;
-
- Constructor lookupConstructor(Name name, {bool isSuper});
-
- Expression toValue(node);
-
- Member lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
-
- scopeLookup(Scope scope, String name, Token token,
- {bool isQualified: false, PrefixBuilder prefix});
-
- finishSend(Object receiver, Arguments arguments, int offset);
-
- Expression buildCompileTimeError(Message message, int charOffset, int length,
- {List<LocatedMessage> context});
-
- Expression wrapInCompileTimeError(Expression expression, Message message);
-
- Expression deprecated_buildCompileTimeError(String error, [int offset]);
-
- Initializer buildInvalidInitializer(Expression expression, [int offset]);
-
- Initializer buildFieldInitializer(
- bool isSynthetic, String name, int offset, Expression expression);
-
- Initializer buildSuperInitializer(
- bool isSynthetic, Constructor constructor, Arguments arguments,
- [int offset]);
-
- Initializer buildRedirectingInitializer(
- Constructor constructor, Arguments arguments,
- [int charOffset = -1]);
-
- Expression buildStaticInvocation(Procedure target, Arguments arguments,
- {Constness constness, int charOffset, Member initialTarget});
-
- Expression buildProblemExpression(
- ProblemBuilder builder, int offset, int length);
-
- Expression throwNoSuchMethodError(
- Expression receiver, String name, Arguments arguments, int offset,
- {Member candidate,
- bool isSuper,
- bool isGetter,
- bool isSetter,
- bool isStatic,
- LocatedMessage argMessage});
-
- LocatedMessage checkArguments(FunctionTypeAccessor function,
- Arguments arguments, CalleeDesignation calleeKind, int offset,
- [List<TypeParameter> typeParameters]);
-
- StaticGet makeStaticGet(Member readTarget, Token token);
-
- Expression wrapInDeferredCheck(
- Expression expression, KernelPrefixBuilder prefix, int charOffset);
-
- dynamic deprecated_addCompileTimeError(int charOffset, String message);
-
- bool isIdentical(Member member);
-
- Expression buildMethodInvocation(
- Expression receiver, Name name, Arguments arguments, int offset,
- {bool isConstantExpression,
- bool isNullAware,
- bool isImplicitCall,
- bool isSuper,
- Member interfaceTarget});
-
- Expression buildConstructorInvocation(
- TypeDeclarationBuilder type,
- Token nameToken,
- Arguments arguments,
- String name,
- List<DartType> typeArguments,
- int charOffset,
- Constness constness);
-
- DartType validatedTypeVariableUse(
- TypeParameterType type, int offset, bool nonInstanceAccessIsError);
-
- void addProblem(Message message, int charOffset, int length);
-
- void addProblemErrorIfConst(Message message, int charOffset, int length);
-
- Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
-
- Message warnUnresolvedSet(Name name, int charOffset, {bool isSuper});
-
- Message warnUnresolvedMethod(Name name, int charOffset, {bool isSuper});
-
- void warnTypeArgumentsMismatch(String name, int expected, int charOffset);
-
- T storeOffset<T>(T node, int offset);
-}
-
-// The name used to refer to a call target kind
-enum CalleeDesignation { Function, Method, Constructor }
-
-// Abstraction over FunctionNode and FunctionType to access the
-// number and names of parameters.
-class FunctionTypeAccessor {
- int requiredParameterCount;
- int positionalParameterCount;
-
- List _namedParameters;
-
- Set<String> get namedParameterNames {
- return new Set.from(_namedParameters.map((a) => a.name));
- }
-
- factory FunctionTypeAccessor.fromNode(FunctionNode node) {
- return new FunctionTypeAccessor._(node.requiredParameterCount,
- node.positionalParameters.length, node.namedParameters);
- }
-
- factory FunctionTypeAccessor.fromType(FunctionType type) {
- return new FunctionTypeAccessor._(type.requiredParameterCount,
- type.positionalParameters.length, type.namedParameters);
- }
-
- FunctionTypeAccessor._(this.requiredParameterCount,
- this.positionalParameterCount, this._namedParameters);
-}
-
-abstract class FastaAccessor<Arguments> implements Accessor<Arguments> {
- BuilderHelper get helper;
-
- // TODO(ahe): Change type arguments.
- Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
- helper.forest;
-
- String get plainNameForRead;
-
- Uri get uri => helper.uri;
-
- String get plainNameForWrite => plainNameForRead;
-
- bool get isInitializer => false;
-
- T storeOffset<T>(T node, int offset) {
- return helper.storeOffset(node, offset);
- }
-
- kernel.Expression buildForEffect() => buildSimpleRead();
-
- Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- int offset = offsetForToken(token);
- return helper.buildInvalidInitializer(
- helper.buildCompileTimeError(
- messageInvalidInitializer, offset, lengthForToken(token)),
- offset);
- }
-
- kernel.Expression makeInvalidRead() {
- return buildThrowNoSuchMethodError(
- forest.literalNull(token), forest.argumentsEmpty(noLocation),
- isGetter: true);
- }
-
- kernel.Expression makeInvalidWrite(kernel.Expression value) {
- return buildThrowNoSuchMethodError(forest.literalNull(token),
- forest.arguments(<kernel.Expression>[value], noLocation),
- isSetter: true);
- }
-
- /* kernel.Expression | FastaAccessor | Initializer */ doInvocation(
- int offset, Arguments arguments);
-
- /* kernel.Expression | FastaAccessor */ buildPropertyAccess(
- IncompleteSend send, int operatorOffset, bool isNullAware) {
- if (send is SendAccessor) {
- return helper.buildMethodInvocation(buildSimpleRead(), send.name,
- send.arguments, offsetForToken(send.token),
- isNullAware: isNullAware);
- } else {
- if (helper.constantContext != ConstantContext.none &&
- send.name != lengthName) {
- helper.deprecated_addCompileTimeError(
- offsetForToken(token), "Not a constant expression.");
- }
- return PropertyAccessor.make(helper, send.token, buildSimpleRead(),
- send.name, null, null, isNullAware);
- }
- }
-
- DartType buildTypeWithBuiltArguments(List<DartType> arguments,
- {bool nonInstanceAccessIsError: false}) {
- helper.addProblem(templateNotAType.withArguments(token.lexeme),
- offsetForToken(token), lengthForToken(token));
- return const InvalidType();
- }
-
- /* kernel.Expression | FastaAccessor */ buildThrowNoSuchMethodError(
- kernel.Expression receiver, Arguments arguments,
- {bool isSuper: false,
- bool isGetter: false,
- bool isSetter: false,
- bool isStatic: false,
- String name,
- int offset,
- LocatedMessage argMessage}) {
- return helper.throwNoSuchMethodError(receiver, name ?? plainNameForWrite,
- arguments, offset ?? offsetForToken(this.token),
- isGetter: isGetter,
- isSetter: isSetter,
- isSuper: isSuper,
- isStatic: isStatic,
- argMessage: argMessage);
- }
-
- bool get isThisPropertyAccessor => false;
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowIllegalAssignment(rhs);
-}
-
-abstract class ErrorAccessor<Arguments> implements FastaAccessor<Arguments> {
- /// Pass [arguments] that must be evaluated before throwing an error. At
- /// most one of [isGetter] and [isSetter] should be true and they're passed
- /// to [BuilderHelper.buildThrowNoSuchMethodError] if it is used.
- kernel.Expression buildError(Arguments arguments,
- {bool isGetter: false, bool isSetter: false, int offset});
-
- DartType buildErroneousTypeNotAPrefix(Identifier suffix);
-
- Name get name => unsupported("name", offsetForToken(token), uri);
-
- @override
- String get plainNameForRead => name.name;
-
- withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
-
- @override
- Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- return helper.buildInvalidInitializer(
- buildError(forest.argumentsEmpty(noLocation), isSetter: true));
- }
-
- @override
- doInvocation(int offset, Arguments arguments) {
- return buildError(arguments, offset: offset);
- }
-
- @override
- buildPropertyAccess(
- IncompleteSend send, int operatorOffset, bool isNullAware) {
- return this;
- }
-
- @override
- buildThrowNoSuchMethodError(kernel.Expression receiver, Arguments arguments,
- {bool isSuper: false,
- bool isGetter: false,
- bool isSetter: false,
- bool isStatic: false,
- String name,
- int offset,
- LocatedMessage argMessage}) {
- return this;
- }
-
- @override
- kernel.Expression buildAssignment(kernel.Expression value,
- {bool voidContext: false}) {
- return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
- isSetter: true);
- }
-
- @override
- kernel.Expression buildCompoundAssignment(
- Name binaryOperator, kernel.Expression value,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget,
- bool isPreIncDec: false}) {
- return buildError(forest.arguments(<kernel.Expression>[value], token),
- isGetter: true);
- }
-
- @override
- kernel.Expression buildPrefixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- // TODO(ahe): For the Analyzer, we probably need to build a prefix
- // increment node that wraps an error.
- return buildError(
- forest.arguments(<kernel.Expression>[
- storeOffset(forest.literalInt(1, null), offset)
- ], noLocation),
- isGetter: true);
- }
-
- @override
- kernel.Expression buildPostfixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- // TODO(ahe): For the Analyzer, we probably need to build a post increment
- // node that wraps an error.
- return buildError(
- forest.arguments(<kernel.Expression>[
- storeOffset(forest.literalInt(1, null), offset)
- ], noLocation),
- isGetter: true);
- }
-
- @override
- kernel.Expression buildNullAwareAssignment(
- kernel.Expression value, DartType type, int offset,
- {bool voidContext: false}) {
- return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
- isSetter: true);
- }
-
- @override
- kernel.Expression buildSimpleRead() =>
- buildError(forest.argumentsEmpty(noLocation), isGetter: true);
-
- @override
- kernel.Expression makeInvalidRead() =>
- buildError(forest.argumentsEmpty(noLocation), isGetter: true);
-
- @override
- kernel.Expression makeInvalidWrite(kernel.Expression value) {
- return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
- isSetter: true);
- }
-}
-
-class ThisAccessor<Arguments> extends FastaAccessor<Arguments> {
- final BuilderHelper helper;
-
- final Token token;
-
- final bool isInitializer;
-
- final bool isSuper;
-
- ThisAccessor(this.helper, this.token, this.isInitializer,
- {this.isSuper: false});
-
- String get plainNameForRead {
- return unsupported("${isSuper ? 'super' : 'this'}.plainNameForRead",
- offsetForToken(token), uri);
- }
-
- kernel.Expression buildSimpleRead() {
- if (!isSuper) {
- return forest.thisExpression(token);
- } else {
- return helper.buildCompileTimeError(messageSuperAsExpression,
- offsetForToken(token), lengthForToken(token));
- }
- }
-
- @override
- Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- String keyword = isSuper ? "super" : "this";
- int offset = offsetForToken(token);
- return helper.buildInvalidInitializer(
- helper.deprecated_buildCompileTimeError(
- "Can't use '$keyword' here, did you mean '$keyword()'?", offset),
- offset);
- }
-
- buildPropertyAccess(
- IncompleteSend send, int operatorOffset, bool isNullAware) {
- Name name = send.name;
- Arguments arguments = send.arguments;
- int offset = offsetForToken(send.token);
- if (isInitializer && send is SendAccessor) {
- if (isNullAware) {
- helper.deprecated_addCompileTimeError(
- operatorOffset, "Expected '.'\nTry removing '?'.");
- }
- return buildConstructorInitializer(offset, name, arguments);
- }
- Member getter = helper.lookupInstanceMember(name, isSuper: isSuper);
- if (send is SendAccessor) {
- // Notice that 'this' or 'super' can't be null. So we can ignore the
- // value of [isNullAware].
- if (getter == null) {
- helper.warnUnresolvedMethod(name, offsetForToken(send.token),
- isSuper: isSuper);
- }
- return helper.buildMethodInvocation(forest.thisExpression(null), name,
- send.arguments, offsetForToken(send.token),
- isSuper: isSuper, interfaceTarget: getter);
- } else {
- Member setter =
- helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
- if (isSuper) {
- return new SuperPropertyAccessor(
- helper, send.token, name, getter, setter);
- } else {
- return new ThisPropertyAccessor(
- helper, send.token, name, getter, setter);
- }
- }
- }
-
- doInvocation(int offset, Arguments arguments) {
- if (isInitializer) {
- return buildConstructorInitializer(offset, new Name(""), arguments);
- } else if (isSuper) {
- return helper.buildCompileTimeError(
- messageSuperAsExpression, offset, noLength);
- } else {
- return helper.buildMethodInvocation(
- forest.thisExpression(null), callName, arguments, offset,
- isImplicitCall: true);
- }
- }
-
- Initializer buildConstructorInitializer(
- int offset, Name name, Arguments arguments) {
- Constructor constructor = helper.lookupConstructor(name, isSuper: isSuper);
- LocatedMessage argMessage;
- if (constructor != null) {
- argMessage = helper.checkArguments(
- new FunctionTypeAccessor.fromNode(constructor.function),
- arguments,
- CalleeDesignation.Constructor,
- offset, <TypeParameter>[]);
- }
- if (constructor == null || argMessage != null) {
- return helper.buildInvalidInitializer(
- buildThrowNoSuchMethodError(
- storeOffset(forest.literalNull(null), offset), arguments,
- isSuper: isSuper,
- name: name.name,
- offset: offset,
- argMessage: argMessage),
- offset);
- } else if (isSuper) {
- return helper.buildSuperInitializer(
- false, constructor, arguments, offset);
- } else {
- return helper.buildRedirectingInitializer(constructor, arguments, offset);
- }
- }
-
- kernel.Expression buildAssignment(kernel.Expression value,
- {bool voidContext: false}) {
- return buildAssignmentError();
- }
-
- kernel.Expression buildNullAwareAssignment(
- kernel.Expression value, DartType type, int offset,
- {bool voidContext: false}) {
- return buildAssignmentError();
- }
-
- kernel.Expression buildCompoundAssignment(
- Name binaryOperator, kernel.Expression value,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget,
- bool isPreIncDec: false}) {
- return buildAssignmentError();
- }
-
- kernel.Expression buildPrefixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- return buildAssignmentError();
- }
-
- kernel.Expression buildPostfixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- return buildAssignmentError();
- }
-
- kernel.Expression buildAssignmentError() {
- String message =
- isSuper ? "Can't assign to 'super'." : "Can't assign to 'this'.";
- return helper.deprecated_buildCompileTimeError(
- message, offsetForToken(token));
- }
-
- toString() {
- int offset = offsetForToken(token);
- return "ThisAccessor($offset${isSuper ? ', super' : ''})";
- }
-}
-
-abstract class IncompleteSend<Arguments> extends FastaAccessor<Arguments> {
- final BuilderHelper helper;
-
- @override
- final Token token;
-
- final Name name;
-
- IncompleteSend(this.helper, this.token, this.name);
-
- withReceiver(Object receiver, int operatorOffset, {bool isNullAware});
-
- Arguments get arguments => null;
-}
-
-class IncompleteError<Arguments> extends IncompleteSend<Arguments>
- with ErrorAccessor<Arguments> {
- final Message message;
-
- IncompleteError(BuilderHelper helper, Token token, this.message)
- : super(helper, token, null);
-
- @override
- kernel.Expression buildError(Arguments arguments,
- {bool isGetter: false, bool isSetter: false, int offset}) {
- int length = noLength;
- if (offset == null) {
- offset = offsetForToken(token);
- length = lengthForToken(token);
- }
- return helper.buildCompileTimeError(message, offset, length);
- }
-
- @override
- DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
- helper.addProblem(
- templateNotAPrefixInTypeAnnotation.withArguments(
- token.lexeme, suffix.name),
- offsetForToken(token),
- lengthOfSpan(token, suffix.token));
- return const InvalidType();
- }
-
- @override
- doInvocation(int offset, Arguments arguments) => this;
-}
-
-class SendAccessor<Arguments> extends IncompleteSend<Arguments> {
- @override
- final Arguments arguments;
-
- SendAccessor(BuilderHelper helper, Token token, Name name, this.arguments)
- : super(helper, token, name) {
- assert(arguments != null);
- }
-
- String get plainNameForRead => name.name;
-
- kernel.Expression buildSimpleRead() {
- return unsupported("buildSimpleRead", offsetForToken(token), uri);
- }
-
- kernel.Expression buildAssignment(kernel.Expression value,
- {bool voidContext: false}) {
- return unsupported("buildAssignment", offsetForToken(token), uri);
- }
-
- withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
- if (receiver is FastaAccessor) {
- return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
- }
- if (receiver is PrefixBuilder) {
- PrefixBuilder prefix = receiver;
- if (isNullAware) {
- helper.deprecated_addCompileTimeError(
- offsetForToken(token),
- "Library prefix '${prefix.name}' can't be used with null-aware "
- "operator.\nTry removing '?'.");
- }
- receiver = helper.scopeLookup(prefix.exportScope, name.name, token,
- isQualified: true, prefix: prefix);
- return helper.finishSend(receiver, arguments, offsetForToken(token));
- }
- return helper.buildMethodInvocation(
- helper.toValue(receiver), name, arguments, offsetForToken(token),
- isNullAware: isNullAware);
- }
-
- kernel.Expression buildNullAwareAssignment(
- kernel.Expression value, DartType type, int offset,
- {bool voidContext: false}) {
- return unsupported("buildNullAwareAssignment", offset, uri);
- }
-
- kernel.Expression buildCompoundAssignment(
- Name binaryOperator, kernel.Expression value,
- {int offset,
- bool voidContext: false,
- Procedure interfaceTarget,
- bool isPreIncDec: false}) {
- return unsupported(
- "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
- }
-
- kernel.Expression buildPrefixIncrement(Name binaryOperator,
- {int offset, bool voidContext: false, Procedure interfaceTarget}) {
- return unsupported(
- "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
- }
-
- kernel.Expression buildPostfixIncrement(Name binaryOperator,
- {int offset, bool voidContext: false, Procedure interfaceTarget}) {
- return unsupported(
- "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
- }
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return unsupported("doInvocation", offset, uri);
- }
-
- toString() {
- int offset = offsetForToken(token);
- return "SendAccessor($offset, $name, $arguments)";
- }
-}
-
-class IncompletePropertyAccessor<Arguments> extends IncompleteSend<Arguments> {
- IncompletePropertyAccessor(BuilderHelper helper, Token token, Name name)
- : super(helper, token, name);
-
- String get plainNameForRead => name.name;
-
- kernel.Expression buildSimpleRead() {
- return unsupported("buildSimpleRead", offsetForToken(token), uri);
- }
-
- kernel.Expression buildAssignment(kernel.Expression value,
- {bool voidContext: false}) {
- return unsupported("buildAssignment", offsetForToken(token), uri);
- }
-
- withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
- if (receiver is FastaAccessor) {
- return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
- }
- if (receiver is PrefixBuilder) {
- PrefixBuilder prefix = receiver;
- if (isNullAware) {
- helper.deprecated_addCompileTimeError(
- offsetForToken(token),
- "Library prefix '${prefix.name}' can't be used with null-aware "
- "operator.\nTry removing '?'.");
- }
- return helper.scopeLookup(prefix.exportScope, name.name, token,
- isQualified: true, prefix: prefix);
- }
-
- return PropertyAccessor.make(
- helper, token, helper.toValue(receiver), name, null, null, isNullAware);
- }
-
- kernel.Expression buildNullAwareAssignment(
- kernel.Expression value, DartType type, int offset,
- {bool voidContext: false}) {
- return unsupported("buildNullAwareAssignment", offset, uri);
- }
-
- kernel.Expression buildCompoundAssignment(
- Name binaryOperator, kernel.Expression value,
- {int offset,
- bool voidContext: false,
- Procedure interfaceTarget,
- bool isPreIncDec: false}) {
- return unsupported(
- "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
- }
-
- kernel.Expression buildPrefixIncrement(Name binaryOperator,
- {int offset, bool voidContext: false, Procedure interfaceTarget}) {
- return unsupported(
- "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
- }
-
- kernel.Expression buildPostfixIncrement(Name binaryOperator,
- {int offset, bool voidContext: false, Procedure interfaceTarget}) {
- return unsupported(
- "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
- }
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return unsupported("doInvocation", offset, uri);
- }
-
- toString() {
- int offset = offsetForToken(token);
- return "IncompletePropertyAccessor($offset, $name)";
- }
-}
-
-class IndexAccessor<Arguments> extends kernel.IndexAccessor<Arguments>
- with FastaAccessor<Arguments> {
- final BuilderHelper helper;
-
- IndexAccessor.internal(this.helper, Token token, kernel.Expression receiver,
- kernel.Expression index, Procedure getter, Procedure setter)
- : super.internal(helper, receiver, index, getter, setter, token);
-
- String get plainNameForRead => "[]";
-
- String get plainNameForWrite => "[]=";
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildMethodInvocation(
- buildSimpleRead(), callName, arguments, forest.readOffset(arguments),
- isImplicitCall: true);
- }
-
- toString() => "IndexAccessor()";
-
- static FastaAccessor make(
- BuilderHelper helper,
- Token token,
- kernel.Expression receiver,
- kernel.Expression index,
- Procedure getter,
- Procedure setter) {
- if (receiver is ThisExpression) {
- return new ThisIndexAccessor(helper, token, index, getter, setter);
- } else {
- return new IndexAccessor.internal(
- helper, token, receiver, index, getter, setter);
- }
- }
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowIndexAssign(receiver, index, rhs);
-}
-
-class PropertyAccessor<Arguments> extends kernel.PropertyAccessor<Arguments>
- with FastaAccessor<Arguments> {
- final BuilderHelper helper;
-
- PropertyAccessor.internal(this.helper, Token token,
- kernel.Expression receiver, Name name, Member getter, Member setter)
- : super.internal(helper, receiver, name, getter, setter, token);
-
- String get plainNameForRead => name.name;
-
- bool get isThisPropertyAccessor => receiver is ThisExpression;
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildMethodInvocation(receiver, name, arguments, offset);
- }
-
- toString() => "PropertyAccessor()";
-
- static FastaAccessor make(
- BuilderHelper helper,
- Token token,
- kernel.Expression receiver,
- Name name,
- Member getter,
- Member setter,
- bool isNullAware) {
- if (receiver is ThisExpression) {
- return unsupported("ThisExpression", offsetForToken(token), helper.uri);
- } else {
- return isNullAware
- ? new NullAwarePropertyAccessor(
- helper, token, receiver, name, getter, setter, null)
- : new PropertyAccessor.internal(
- helper, token, receiver, name, getter, setter);
- }
- }
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowPropertyAssign(receiver, rhs);
-}
-
-class StaticAccessor<Arguments> extends kernel.StaticAccessor<Arguments>
- with FastaAccessor<Arguments> {
- StaticAccessor(
- BuilderHelper helper, Token token, Member readTarget, Member writeTarget)
- : super(helper, readTarget, writeTarget, token) {
- assert(readTarget != null || writeTarget != null);
- }
-
- factory StaticAccessor.fromBuilder(BuilderHelper helper, Builder builder,
- Token token, Builder builderSetter) {
- if (builder is AccessErrorBuilder) {
- AccessErrorBuilder error = builder;
- builder = error.builder;
- // We should only see an access error here if we've looked up a setter
- // when not explicitly looking for a setter.
- assert(builder.isSetter);
- } else if (builder.target == null) {
- return unhandled("${builder.runtimeType}", "StaticAccessor.fromBuilder",
- offsetForToken(token), helper.uri);
- }
- Member getter = builder.target.hasGetter ? builder.target : null;
- Member setter = builder.target.hasSetter ? builder.target : null;
- if (setter == null) {
- if (builderSetter?.target?.hasSetter ?? false) {
- setter = builderSetter.target;
- }
- }
- return new StaticAccessor(helper, token, getter, setter);
- }
-
- String get plainNameForRead => (readTarget ?? writeTarget).name.name;
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- if (helper.constantContext != ConstantContext.none &&
- !helper.isIdentical(readTarget)) {
- helper.deprecated_addCompileTimeError(
- offset, "Not a constant expression.");
- }
- if (readTarget == null || isFieldOrGetter(readTarget)) {
- return helper.buildMethodInvocation(buildSimpleRead(), callName,
- arguments, offset + (readTarget?.name?.name?.length ?? 0),
- // This isn't a constant expression, but we have checked if a
- // constant expression error should be emitted already.
- isConstantExpression: true,
- isImplicitCall: true);
- } else {
- return helper.buildStaticInvocation(readTarget, arguments,
- charOffset: offset);
- }
- }
-
- toString() => "StaticAccessor()";
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowStaticAssignment(rhs);
-}
-
-class LoadLibraryAccessor<Arguments> extends kernel
- .LoadLibraryAccessor<Arguments> with FastaAccessor<Arguments> {
- LoadLibraryAccessor(
- BuilderHelper helper, Token token, LoadLibraryBuilder builder)
- : super(helper, token, builder);
-
- String get plainNameForRead => 'loadLibrary';
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- if (forest.argumentsPositional(arguments).length > 0 ||
- forest.argumentsNamed(arguments).length > 0) {
- helper.addProblemErrorIfConst(
- messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
- }
- return builder.createLoadLibrary(offset, forest);
- }
-}
-
-class DeferredAccessor<Arguments> extends kernel.DeferredAccessor<Arguments>
- with FastaAccessor<Arguments> {
- DeferredAccessor(BuilderHelper helper, Token token, PrefixBuilder builder,
- FastaAccessor expression)
- : super(helper, token, builder, expression);
-
- String get plainNameForRead {
- return unsupported(
- "deferredAccessor.plainNameForRead", offsetForToken(token), uri);
- }
-
- FastaAccessor get accessor => super.accessor;
-
- buildPropertyAccess(
- IncompleteSend send, int operatorOffset, bool isNullAware) {
- var propertyAccess =
- accessor.buildPropertyAccess(send, operatorOffset, isNullAware);
- if (propertyAccess is FastaAccessor) {
- return new DeferredAccessor(helper, token, builder, propertyAccess);
- } else {
- kernel.Expression expression = propertyAccess;
- return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
- }
- }
-
- @override
- DartType buildTypeWithBuiltArguments(List<DartType> arguments,
- {bool nonInstanceAccessIsError: false}) {
- helper.addProblem(
- templateDeferredTypeAnnotation.withArguments(
- accessor.buildTypeWithBuiltArguments(arguments,
- nonInstanceAccessIsError: nonInstanceAccessIsError),
- builder.name),
- offsetForToken(token),
- lengthForToken(token));
- return const InvalidType();
- }
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.wrapInDeferredCheck(
- accessor.doInvocation(offset, arguments), builder, token.charOffset);
- }
-}
-
-class SuperPropertyAccessor<Arguments> extends kernel
- .SuperPropertyAccessor<Arguments> with FastaAccessor<Arguments> {
- SuperPropertyAccessor(BuilderHelper helper, Token token, Name name,
- Member getter, Member setter)
- : super(helper, name, getter, setter, token);
-
- String get plainNameForRead => name.name;
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- if (helper.constantContext != ConstantContext.none) {
- helper.deprecated_addCompileTimeError(
- offset, "Not a constant expression.");
- }
- if (getter == null || isFieldOrGetter(getter)) {
- return helper.buildMethodInvocation(
- buildSimpleRead(), callName, arguments, offset,
- // This isn't a constant expression, but we have checked if a
- // constant expression error should be emitted already.
- isConstantExpression: true,
- isImplicitCall: true);
- } else {
- // TODO(ahe): This could be something like "super.property(...)" where
- // property is a setter.
- return unhandled("${getter.runtimeType}", "doInvocation", offset, uri);
- }
- }
-
- toString() => "SuperPropertyAccessor()";
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowPropertyAssign(null, rhs, isSuper: true);
-}
-
-class ThisIndexAccessor<Arguments> extends kernel.ThisIndexAccessor<Arguments>
- with FastaAccessor<Arguments> {
- ThisIndexAccessor(BuilderHelper helper, Token token, kernel.Expression index,
- Procedure getter, Procedure setter)
- : super(helper, index, getter, setter, token);
-
- String get plainNameForRead => "[]";
-
- String get plainNameForWrite => "[]=";
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildMethodInvocation(
- buildSimpleRead(), callName, arguments, offset,
- isImplicitCall: true);
- }
-
- toString() => "ThisIndexAccessor()";
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowIndexAssign(null, index, rhs);
-}
-
-class SuperIndexAccessor<Arguments> extends kernel.SuperIndexAccessor<Arguments>
- with FastaAccessor<Arguments> {
- SuperIndexAccessor(BuilderHelper helper, Token token, kernel.Expression index,
- Member getter, Member setter)
- : super(helper, index, getter, setter, token);
-
- String get plainNameForRead => "[]";
-
- String get plainNameForWrite => "[]=";
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildMethodInvocation(
- buildSimpleRead(), callName, arguments, offset,
- isImplicitCall: true);
- }
-
- toString() => "SuperIndexAccessor()";
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowIndexAssign(null, index, rhs, isSuper: true);
-}
-
-class ThisPropertyAccessor<Arguments> extends kernel
- .ThisPropertyAccessor<Arguments> with FastaAccessor<Arguments> {
- final BuilderHelper helper;
-
- ThisPropertyAccessor(
- this.helper, Token token, Name name, Member getter, Member setter)
- : super(helper, name, getter, setter, token);
-
- String get plainNameForRead => name.name;
-
- bool get isThisPropertyAccessor => true;
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- Member interfaceTarget = getter;
- if (interfaceTarget == null) {
- helper.warnUnresolvedMethod(name, offset);
- }
- if (interfaceTarget is Field) {
- // TODO(ahe): In strong mode we should probably rewrite this to
- // `this.name.call(arguments)`.
- interfaceTarget = null;
- }
- return helper.buildMethodInvocation(
- forest.thisExpression(null), name, arguments, offset,
- interfaceTarget: interfaceTarget);
- }
-
- toString() => "ThisPropertyAccessor()";
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowPropertyAssign(null, rhs);
-}
-
-class NullAwarePropertyAccessor<Arguments> extends kernel
- .NullAwarePropertyAccessor<Arguments> with FastaAccessor<Arguments> {
- final BuilderHelper helper;
-
- NullAwarePropertyAccessor(
- this.helper,
- Token token,
- kernel.Expression receiver,
- Name name,
- Member getter,
- Member setter,
- DartType type)
- : super(helper, receiver, name, getter, setter, type, token);
-
- String get plainNameForRead => name.name;
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return unimplemented("doInvocation", offset, uri);
- }
-
- toString() => "NullAwarePropertyAccessor()";
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowPropertyAssign(receiverExpression, rhs);
-}
-
-int adjustForImplicitCall(String name, int offset) {
- // Normally the offset is at the start of the token, but in this case,
- // because we insert a '.call', we want it at the end instead.
- return offset + (name?.length ?? 0);
-}
-
-class VariableAccessor<Arguments> extends kernel.VariableAccessor<Arguments>
- with FastaAccessor<Arguments> {
- VariableAccessor(
- BuilderHelper helper, Token token, VariableDeclaration variable,
- [DartType promotedType])
- : super(helper, variable, promotedType, token);
-
- String get plainNameForRead => variable.name;
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
- adjustForImplicitCall(plainNameForRead, offset),
- isImplicitCall: true);
- }
-
- toString() => "VariableAccessor()";
-
- @override
- ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
- new ShadowVariableAssignment(rhs);
-}
-
-class ReadOnlyAccessor<Arguments> extends kernel.ReadOnlyAccessor<Arguments>
- with FastaAccessor<Arguments> {
- final String plainNameForRead;
-
- ReadOnlyAccessor(BuilderHelper helper, kernel.Expression expression,
- this.plainNameForRead, Token token)
- : super(helper, expression, token);
-
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
- adjustForImplicitCall(plainNameForRead, offset),
- isImplicitCall: true);
- }
-}
-
-class LargeIntAccessor<Arguments> extends kernel.DelayedErrorAccessor<Arguments>
- with FastaAccessor<Arguments> {
- final String plainNameForRead = null;
-
- LargeIntAccessor(BuilderHelper helper, Token token) : super(helper, token);
-
- @override
- kernel.Expression buildError() {
- return helper.buildCompileTimeError(
- templateIntegerLiteralIsOutOfRange.withArguments(token),
- offsetForToken(token),
- lengthForToken(token));
- }
-
- kernel.Expression doInvocation(int offset, Arguments arguments) =>
- buildError();
-}
-
-class ParenthesizedExpression<Arguments> extends ReadOnlyAccessor<Arguments> {
- ParenthesizedExpression(
- BuilderHelper helper, kernel.Expression expression, Token token)
- : super(helper, expression, null, token);
-
- kernel.Expression makeInvalidWrite(kernel.Expression value) {
- return helper.deprecated_buildCompileTimeError(
- "Can't assign to a parenthesized expression.", offsetForToken(token));
- }
-}
-
-class TypeDeclarationAccessor<Arguments> extends ReadOnlyAccessor<Arguments> {
- /// The import prefix preceding the [declaration] reference, or `null` if
- /// the reference is not prefixed.
- final PrefixBuilder prefix;
-
- /// The offset at which the [declaration] is referenced by this accessor,
- /// or `-1` if the reference is implicit.
- final int declarationReferenceOffset;
-
- final TypeDeclarationBuilder declaration;
-
- TypeDeclarationAccessor(
- BuilderHelper helper,
- this.prefix,
- this.declarationReferenceOffset,
- this.declaration,
- String plainNameForRead,
- Token token)
- : super(helper, null, plainNameForRead, token);
-
- kernel.Expression get expression {
- if (super.expression == null) {
- int offset = offsetForToken(token);
- if (declaration is KernelInvalidTypeBuilder) {
- KernelInvalidTypeBuilder declaration = this.declaration;
- helper.addProblemErrorIfConst(
- declaration.message.messageObject, offset, token.length);
- super.expression =
- new Throw(forest.literalString(declaration.message.message, token))
- ..fileOffset = offset;
- } else {
- super.expression = forest.literalType(
- buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
- token);
- }
- }
- return super.expression;
- }
-
- kernel.Expression makeInvalidWrite(kernel.Expression value) {
- return buildThrowNoSuchMethodError(
- forest.literalNull(token),
- storeOffset(forest.arguments(<kernel.Expression>[value], null),
- value.fileOffset),
- isSetter: true);
- }
-
- @override
- buildPropertyAccess(
- IncompleteSend send, int operatorOffset, bool isNullAware) {
- // `SomeType?.toString` is the same as `SomeType.toString`, not
- // `(SomeType).toString`.
- isNullAware = false;
-
- Name name = send.name;
- Arguments arguments = send.arguments;
-
- if (declaration is KernelClassBuilder) {
- KernelClassBuilder declaration = this.declaration;
- Builder builder = declaration.findStaticBuilder(
- name.name, offsetForToken(token), uri, helper.library);
-
- FastaAccessor accessor;
- if (builder == null) {
- // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
- if (send is IncompletePropertyAccessor) {
- accessor = new UnresolvedAccessor(helper, name, send.token);
- } else {
- return helper.buildConstructorInvocation(declaration, send.token,
- arguments, name.name, null, token.charOffset, Constness.implicit);
- }
- } else {
- Builder setter;
- if (builder.isSetter) {
- setter = builder;
- } else if (builder.isGetter) {
- setter = declaration.findStaticBuilder(
- name.name, offsetForToken(token), uri, helper.library,
- isSetter: true);
- } else if (builder.isField && !builder.isFinal) {
- setter = builder;
- }
- accessor =
- new StaticAccessor.fromBuilder(helper, builder, send.token, setter);
- }
-
- return arguments == null
- ? accessor
- : accessor.doInvocation(offsetForToken(send.token), arguments);
- } else {
- return super.buildPropertyAccess(send, operatorOffset, isNullAware);
- }
- }
-
- @override
- DartType buildTypeWithBuiltArguments(List<DartType> arguments,
- {bool nonInstanceAccessIsError: false}) {
- if (arguments != null) {
- int expected = 0;
- if (declaration is KernelClassBuilder) {
- expected = declaration.target.typeParameters.length;
- } else if (declaration is FunctionTypeAliasBuilder) {
- expected = declaration.target.typeParameters.length;
- } else if (declaration is KernelTypeVariableBuilder) {
- // Type arguments on a type variable - error reported elsewhere.
- } else if (declaration is BuiltinTypeBuilder) {
- // Type arguments on a built-in type, for example, dynamic or void.
- expected = 0;
- } else {
- return unhandled(
- "${declaration.runtimeType}",
- "TypeDeclarationAccessor.buildType",
- offsetForToken(token),
- helper.uri);
- }
- if (arguments.length != expected) {
- helper.warnTypeArgumentsMismatch(
- declaration.name, expected, offsetForToken(token));
- // We ignore the provided arguments, which will in turn return the
- // raw type below.
- // TODO(sigmund): change to use an InvalidType and include the raw type
- // as a recovery node once the IR can represent it (Issue #29840).
- arguments = null;
- }
- }
-
- DartType type;
- if (arguments == null) {
- TypeDeclarationBuilder typeDeclaration = declaration;
- if (typeDeclaration is KernelClassBuilder) {
- type = typeDeclaration.buildType(helper.library, null);
- } else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
- type = typeDeclaration.buildType(helper.library, null);
- }
- }
- if (type == null) {
- type =
- declaration.buildTypesWithBuiltArguments(helper.library, arguments);
- }
- if (type is TypeParameterType) {
- return helper.validatedTypeVariableUse(
- type, offsetForToken(token), nonInstanceAccessIsError);
- }
- return type;
- }
-
- @override
- kernel.Expression doInvocation(int offset, Arguments arguments) {
- return helper.buildConstructorInvocation(declaration, token, arguments, "",
- null, token.charOffset, Constness.implicit);
- }
-}
-
-class UnresolvedAccessor<Arguments> extends FastaAccessor<Arguments>
- with ErrorAccessor<Arguments> {
- @override
- final Token token;
-
- @override
- final BuilderHelper helper;
-
- @override
- final Name name;
-
- UnresolvedAccessor(this.helper, this.name, this.token);
-
- kernel.Expression doInvocation(int charOffset, Arguments arguments) {
- return buildError(arguments, offset: charOffset);
- }
-
- @override
- DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
- helper.addProblem(
- templateUnresolvedPrefixInTypeAnnotation.withArguments(
- name.name, suffix.name),
- offsetForToken(token),
- lengthOfSpan(token, suffix.token));
- return const InvalidType();
- }
-
- @override
- kernel.Expression buildError(Arguments arguments,
- {bool isGetter: false, bool isSetter: false, int offset}) {
- offset ??= offsetForToken(this.token);
- return helper.throwNoSuchMethodError(
- storeOffset(forest.literalNull(null), offset),
- plainNameForRead,
- arguments,
- offset,
- isGetter: isGetter,
- isSetter: isSetter);
- }
-}
-
-bool isFieldOrGetter(Member member) {
- return member is Field || (member is Procedure && member.isGetter);
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index c194492..99375a3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -7,6 +7,8 @@
// TODO(ahe): Remove this import.
import 'package:kernel/ast.dart' as kernel show Arguments, DartType;
+import 'body_builder.dart' show Identifier;
+
/// A tree factory.
///
/// For now, the [Location] is always a token.
@@ -91,7 +93,16 @@
/// either adjacent strings or interpolated strings.
Expression literalString(String value, Location location);
- Expression literalSymbol(String value, Location location);
+ /// Return a representation of a symbol literal defined by the [hash] and the
+ /// list of [components]. The [value] is the string value of the symbol.
+ Expression literalSymbolMultiple(
+ String value, Location hash, List<Identifier> components);
+
+ /// Return a representation of a symbol literal defined by the [hash] and the
+ /// single [component]. The component can be either an [Identifier] or an
+ /// [Operator]. The [value] is the string value of the symbol.
+ Expression literalSymbolSingluar(
+ String value, Location hash, Object component);
Expression literalType(covariant type, Location location);
@@ -124,6 +135,11 @@
Expression awaitExpression(Expression operand, Location location);
+ /// Return a representation of a block of [statements] enclosed between the
+ /// [openBracket] and [closeBracket].
+ Statement block(
+ Location openBrace, List<Statement> statements, Location closeBrace);
+
/// Return a representation of a conditional expression. The [condition] is
/// the expression preceding the question mark. The [question] is the `?`. The
/// [thenExpression] is the expression following the question mark. The
@@ -132,6 +148,26 @@
Expression conditionalExpression(Expression condition, Location question,
Expression thenExpression, Location colon, Expression elseExpression);
+ /// Return a representation of a do statement.
+ Statement doStatement(
+ Location doKeyword,
+ Statement body,
+ Location whileKeyword,
+ covariant Expression condition,
+ Location semicolon);
+
+ /// Return a representation of an expression statement composed from the
+ /// [expression] and [semicolon].
+ Statement expressionStatement(Expression expression, Location semicolon);
+
+ /// Return a representation of an empty statement consisting of the given
+ /// [semicolon].
+ Statement emptyStatement(Location semicolon);
+
+ /// Return a representation of an `if` statement.
+ Statement ifStatement(Location ifKeyword, covariant Expression condition,
+ Statement thenStatement, Location elseKeyword, Statement elseStatement);
+
/// Return a representation of an `is` expression. The [operand] is the
/// representation of the left operand. The [isOperator] is the `is` operator.
/// The [notOperator] is either the `!` or `null` if the test is not negated.
@@ -141,12 +177,82 @@
Expression notExpression(Expression operand, Location location);
+ /// Return a representation of a parenthesized condition consisting of the
+ /// given [expression] between the [leftParenthesis] and [rightParenthesis].
+ Object parenthesizedCondition(Location leftParenthesis, Expression expression,
+ Location rightParenthesis);
+
+ /// Return a representation of a rethrow statement consisting of the
+ /// [rethrowKeyword] followed by the [semicolon].
+ Statement rethrowStatement(Location rethrowKeyword, Location semicolon);
+
+ /// Return a representation of a return statement.
+ Statement returnStatement(
+ Location returnKeyword, Expression expression, Location semicolon);
+
Expression stringConcatenationExpression(
List<Expression> expressions, Location location);
+ /// The given [statement] is being used as the target of either a break or
+ /// continue statement. Return the statement that should be used as the actual
+ /// target.
+ Statement syntheticLabeledStatement(Statement statement);
+
Expression thisExpression(Location location);
- bool isErroneousNode(covariant node);
+ /// Return a representation of a throw expression consisting of the
+ /// [throwKeyword].
+ Expression throwExpression(Location throwKeyword, Expression expression);
+
+ /// Return a representation of a try statement. The statement is introduced by
+ /// the [tryKeyword] and the given [body]. If catch clauses were included,
+ /// then the [catchClauses] will represent them, otherwise it will be `null`.
+ /// Similarly, if a finally block was included, then the [finallyKeyword] and
+ /// [finallyBlock] will be non-`null`, otherwise both will be `null`. If there
+ /// was an error in some part of the try statement, then an [errorReplacement]
+ /// might be provided, in which case it could be returned instead of the
+ /// representation of the try statement.
+ Statement tryStatement(Location tryKeyword, Statement body,
+ covariant catchClauses, Location finallyKeyword, Statement finallyBlock);
+
+ Statement variablesDeclaration(covariant List declarations, Uri uri);
+
+ Object variablesDeclarationExtractDeclarations(
+ covariant Statement variablesDeclaration);
+
+ Statement wrapVariables(Statement statement);
+
+ /// Return a representation of a while statement introduced by the
+ /// [whileKeyword] and consisting of the given [condition] and [body].
+ Statement whileStatement(
+ Location whileKeyword, covariant Expression condition, Statement body);
+
+ /// Return a representation of a yield statement consisting of the
+ /// [yieldKeyword], [star], [expression], and [semicolon]. The [star] is null
+ /// when no star was included in the source code.
+ Statement yieldStatement(Location yieldKeyword, Location star,
+ Expression expression, Location semicolon);
+
+ bool isBlock(Object node);
+
+ bool isErroneousNode(Object node);
+
+ bool isThisExpression(Object node);
+
+ bool isVariablesDeclaration(Object node);
+
+ /// Record that the [user] (a break statement) is associated with the [target]
+ /// statement.
+ void resolveBreak(covariant Statement target, covariant Statement user);
+
+ /// Record that the [user] (a continue statement) is associated with the
+ /// [target] statement.
+ void resolveContinue(covariant Statement target, covariant Statement user);
+
+ /// Record that the [user] (a continue statement inside a switch case) is
+ /// associated with the [target] statement.
+ void resolveContinueInSwitch(
+ covariant Object target, covariant Statement user);
// TODO(ahe): Remove this method when all users are moved here.
kernel.Arguments castArguments(Arguments arguments) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
deleted file mode 100644
index e44e72d..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
+++ /dev/null
@@ -1,816 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// A library to help transform compounds and null-aware accessors into
-/// let expressions.
-
-import 'package:kernel/ast.dart' hide MethodInvocation, InvalidExpression;
-
-import '../../scanner/token.dart' show Token;
-
-import '../names.dart' show equalsName, indexGetName, indexSetName;
-
-import '../parser.dart' show offsetForToken;
-
-import '../problems.dart' show unhandled;
-
-import 'fasta_accessors.dart' show BuilderHelper;
-
-import 'kernel_builder.dart' show LoadLibraryBuilder, PrefixBuilder;
-
-import 'kernel_shadow_ast.dart'
- show
- ShadowArguments,
- ShadowComplexAssignment,
- ShadowConditionalExpression,
- ShadowIllegalAssignment,
- ShadowMethodInvocation,
- ShadowNullAwarePropertyGet,
- ShadowPropertyAssign,
- ShadowPropertyGet,
- ShadowSuperMethodInvocation,
- ShadowSuperPropertyGet,
- ShadowThisExpression,
- ShadowVariableDeclaration,
- ShadowVariableGet;
-
-/// An [Accessor] represents a subexpression for which we can't yet build a
-/// kernel [Expression] because we don't yet know the context in which it is
-/// used.
-///
-/// Once the context is known, an [Accessor] can be converted into an
-/// [Expression] by calling a "build" method.
-///
-/// For example, when building a kernel representation for `a[x] = b`, after
-/// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
-/// generate an invocation of `operator[]` or `operator[]=`, so we generate an
-/// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be
-/// called.
-abstract class Accessor<Arguments> {
- final BuilderHelper helper;
- final Token token;
-
- Accessor(this.helper, this.token);
-
- /// Builds an [Expression] representing a read from the accessor.
- Expression buildSimpleRead() {
- return _finish(_makeSimpleRead(), null);
- }
-
- /// Builds an [Expression] representing an assignment with the accessor on
- /// the LHS and [value] on the RHS.
- ///
- /// The returned expression evaluates to the assigned value, unless
- /// [voidContext] is true, in which case it may evaluate to anything.
- Expression buildAssignment(Expression value, {bool voidContext: false}) {
- var complexAssignment = startComplexAssignment(value);
- return _finish(_makeSimpleWrite(value, voidContext, complexAssignment),
- complexAssignment);
- }
-
- /// Returns an [Expression] representing a null-aware assignment (`??=`) with
- /// the accessor on the LHS and [value] on the RHS.
- ///
- /// The returned expression evaluates to the assigned value, unless
- /// [voidContext] is true, in which case it may evaluate to anything.
- ///
- /// [type] is the static type of the RHS.
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
- {bool voidContext: false}) {
- var complexAssignment = startComplexAssignment(value);
- if (voidContext) {
- var nullAwareCombiner = new ShadowConditionalExpression(
- buildIsNull(_makeRead(complexAssignment), offset),
- _makeWrite(value, false, complexAssignment),
- new NullLiteral());
- complexAssignment?.nullAwareCombiner = nullAwareCombiner;
- return _finish(nullAwareCombiner, complexAssignment);
- }
- var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment));
- var nullAwareCombiner = new ShadowConditionalExpression(
- buildIsNull(new VariableGet(tmp), offset),
- _makeWrite(value, false, complexAssignment),
- new VariableGet(tmp));
- complexAssignment?.nullAwareCombiner = nullAwareCombiner;
- return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
- }
-
- /// Returns an [Expression] representing a compound assignment (e.g. `+=`)
- /// with the accessor on the LHS and [value] on the RHS.
- Expression buildCompoundAssignment(Name binaryOperator, Expression value,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget,
- bool isPreIncDec: false}) {
- var complexAssignment = startComplexAssignment(value);
- complexAssignment?.isPreIncDec = isPreIncDec;
- var combiner = makeBinary(
- _makeRead(complexAssignment), binaryOperator, interfaceTarget, value,
- offset: offset);
- complexAssignment?.combiner = combiner;
- return _finish(_makeWrite(combiner, voidContext, complexAssignment),
- complexAssignment);
- }
-
- /// Returns an [Expression] representing a pre-increment or pre-decrement
- /// of the accessor.
- Expression buildPrefixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- return buildCompoundAssignment(binaryOperator, new IntLiteral(1),
- offset: offset,
- voidContext: voidContext,
- interfaceTarget: interfaceTarget,
- isPreIncDec: true);
- }
-
- /// Returns an [Expression] representing a post-increment or post-decrement
- /// of the accessor.
- Expression buildPostfixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- if (voidContext) {
- return buildPrefixIncrement(binaryOperator,
- offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
- }
- var rhs = new IntLiteral(1);
- var complexAssignment = startComplexAssignment(rhs);
- var value = new VariableDeclaration.forValue(_makeRead(complexAssignment));
- valueAccess() => new VariableGet(value);
- var combiner = makeBinary(
- valueAccess(), binaryOperator, interfaceTarget, rhs,
- offset: offset);
- complexAssignment?.combiner = combiner;
- complexAssignment?.isPostIncDec = true;
- var dummy = new ShadowVariableDeclaration.forValue(
- _makeWrite(combiner, true, complexAssignment),
- helper.functionNestingLevel);
- return _finish(
- makeLet(value, makeLet(dummy, valueAccess())), complexAssignment);
- }
-
- Expression _makeSimpleRead() => _makeRead(null);
-
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- return _makeWrite(value, voidContext, complexAssignment);
- }
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment);
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment);
-
- Expression _finish(
- Expression body, ShadowComplexAssignment complexAssignment) {
- if (complexAssignment != null) {
- complexAssignment.desugared = body;
- return complexAssignment;
- } else {
- return body;
- }
- }
-
- /// Returns an [Expression] representing a compile-time error.
- ///
- /// At runtime, an exception will be thrown.
- makeInvalidRead() {
- return unhandled("compile-time error", "$runtimeType",
- offsetForToken(token), helper.uri);
- }
-
- /// Returns an [Expression] representing a compile-time error wrapping
- /// [value].
- ///
- /// At runtime, [value] will be evaluated before throwing an exception.
- makeInvalidWrite(Expression value) {
- return unhandled("compile-time error", "$runtimeType",
- offsetForToken(token), helper.uri);
- }
-
- /// Creates a data structure for tracking the desugaring of a complex
- /// assignment expression whose right hand side is [rhs].
- ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
- new ShadowIllegalAssignment(rhs);
-}
-
-abstract class VariableAccessor<Arguments> extends Accessor<Arguments> {
- VariableDeclaration variable;
- DartType promotedType;
-
- VariableAccessor(
- BuilderHelper helper, this.variable, this.promotedType, Token token)
- : super(helper, token);
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- var fact = helper.typePromoter
- .getFactForAccess(variable, helper.functionNestingLevel);
- var scope = helper.typePromoter.currentScope;
- var read = new ShadowVariableGet(variable, fact, scope)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- helper.typePromoter.mutateVariable(variable, helper.functionNestingLevel);
- var write = variable.isFinal || variable.isConst
- ? makeInvalidWrite(value)
- : new VariableSet(variable, value)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-}
-
-class PropertyAccessor<Arguments> extends Accessor<Arguments> {
- VariableDeclaration _receiverVariable;
- Expression receiver;
- Name name;
- Member getter, setter;
-
- static Accessor make(BuilderHelper helper, Expression receiver, Name name,
- Member getter, Member setter,
- {Token token}) {
- if (receiver is ThisExpression) {
- return new ThisPropertyAccessor(helper, name, getter, setter, token);
- } else {
- return new PropertyAccessor.internal(
- helper, receiver, name, getter, setter, token);
- }
- }
-
- PropertyAccessor.internal(BuilderHelper helper, this.receiver, this.name,
- this.getter, this.setter, Token token)
- : super(helper, token);
-
- Expression _makeSimpleRead() => new ShadowPropertyGet(receiver, name, getter)
- ..fileOffset = offsetForToken(token);
-
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- var write = new PropertySet(receiver, name, value, setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- receiverAccess() {
- _receiverVariable ??= new VariableDeclaration.forValue(receiver);
- return new VariableGet(_receiverVariable)
- ..fileOffset = offsetForToken(token);
- }
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- var read = new ShadowPropertyGet(receiverAccess(), name, getter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- var write = new PropertySet(receiverAccess(), name, value, setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- Expression _finish(
- Expression body, ShadowComplexAssignment complexAssignment) {
- return super._finish(makeLet(_receiverVariable, body), complexAssignment);
- }
-}
-
-/// Special case of [PropertyAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisPropertyAccessor<Arguments> extends Accessor<Arguments> {
- Name name;
- Member getter, setter;
-
- ThisPropertyAccessor(
- BuilderHelper helper, this.name, this.getter, this.setter, Token token)
- : super(helper, token);
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- if (getter == null) {
- helper.warnUnresolvedGet(name, offsetForToken(token));
- }
- var read = new ShadowPropertyGet(new ShadowThisExpression(), name, getter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (setter == null) {
- helper.warnUnresolvedSet(name, offsetForToken(token));
- }
- var write = new PropertySet(new ShadowThisExpression(), name, value, setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-}
-
-class NullAwarePropertyAccessor<Arguments> extends Accessor<Arguments> {
- VariableDeclaration receiver;
- Expression receiverExpression;
- Name name;
- Member getter, setter;
- DartType type;
-
- NullAwarePropertyAccessor(BuilderHelper helper, this.receiverExpression,
- this.name, this.getter, this.setter, this.type, Token token)
- : this.receiver = makeOrReuseVariable(receiverExpression),
- super(helper, token);
-
- receiverAccess() => new VariableGet(receiver);
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- var read = new ShadowPropertyGet(receiverAccess(), name, getter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- var write = new PropertySet(receiverAccess(), name, value, setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- Expression _finish(
- Expression body, ShadowComplexAssignment complexAssignment) {
- var offset = offsetForToken(token);
- var nullAwareGuard = new ConditionalExpression(
- buildIsNull(receiverAccess(), offset), new NullLiteral(), body, null)
- ..fileOffset = offset;
- if (complexAssignment != null) {
- body = makeLet(receiver, nullAwareGuard);
- ShadowPropertyAssign kernelPropertyAssign = complexAssignment;
- kernelPropertyAssign.nullAwareGuard = nullAwareGuard;
- kernelPropertyAssign.desugared = body;
- return kernelPropertyAssign;
- } else {
- return new ShadowNullAwarePropertyGet(receiver, nullAwareGuard)
- ..fileOffset = offset;
- }
- }
-}
-
-class SuperPropertyAccessor<Arguments> extends Accessor<Arguments> {
- Name name;
- Member getter, setter;
-
- SuperPropertyAccessor(
- BuilderHelper helper, this.name, this.getter, this.setter, Token token)
- : super(helper, token);
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- if (getter == null) {
- helper.warnUnresolvedGet(name, offsetForToken(token), isSuper: true);
- }
- // TODO(ahe): Use [DirectPropertyGet] when possible.
- var read = new ShadowSuperPropertyGet(name, getter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (setter == null) {
- helper.warnUnresolvedSet(name, offsetForToken(token), isSuper: true);
- }
- // TODO(ahe): Use [DirectPropertySet] when possible.
- var write = new SuperPropertySet(name, value, setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-}
-
-class IndexAccessor<Arguments> extends Accessor<Arguments> {
- Expression receiver;
- Expression index;
- VariableDeclaration receiverVariable;
- VariableDeclaration indexVariable;
- Procedure getter, setter;
-
- static Accessor make(BuilderHelper helper, Expression receiver,
- Expression index, Procedure getter, Procedure setter,
- {Token token}) {
- if (receiver is ThisExpression) {
- return new ThisIndexAccessor(helper, index, getter, setter, token);
- } else {
- return new IndexAccessor.internal(
- helper, receiver, index, getter, setter, token);
- }
- }
-
- IndexAccessor.internal(BuilderHelper helper, this.receiver, this.index,
- this.getter, this.setter, Token token)
- : super(helper, token);
-
- Expression _makeSimpleRead() {
- var read = new ShadowMethodInvocation(
- receiver, indexGetName, new ShadowArguments(<Expression>[index]),
- interfaceTarget: getter)
- ..fileOffset = offsetForToken(token);
- return read;
- }
-
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- var write = new ShadowMethodInvocation(
- receiver, indexSetName, new ShadowArguments(<Expression>[index, value]),
- interfaceTarget: setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- receiverAccess() {
- // We cannot reuse the receiver if it is a variable since it might be
- // reassigned in the index expression.
- receiverVariable ??= new VariableDeclaration.forValue(receiver);
- return new VariableGet(receiverVariable)
- ..fileOffset = offsetForToken(token);
- }
-
- indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable)..fileOffset = offsetForToken(token);
- }
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- var read = new ShadowMethodInvocation(receiverAccess(), indexGetName,
- new ShadowArguments(<Expression>[indexAccess()]),
- interfaceTarget: getter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- var write = new ShadowMethodInvocation(receiverAccess(), indexSetName,
- new ShadowArguments(<Expression>[indexAccess(), value]),
- interfaceTarget: setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- // TODO(dmitryas): remove this method after the "[]=" operator of the Context
- // class is made to return a value.
- _makeWriteAndReturn(
- Expression value, ShadowComplexAssignment complexAssignment) {
- // The call to []= does not return the value like direct-style assignments
- // do. We need to bind the value in a let.
- var valueVariable = new VariableDeclaration.forValue(value);
- var write = new ShadowMethodInvocation(
- receiverAccess(),
- indexSetName,
- new ShadowArguments(
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- interfaceTarget: setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- var dummy = new ShadowVariableDeclaration.forValue(
- write, helper.functionNestingLevel);
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
- Expression _finish(
- Expression body, ShadowComplexAssignment complexAssignment) {
- return super._finish(
- makeLet(receiverVariable, makeLet(indexVariable, body)),
- complexAssignment);
- }
-}
-
-/// Special case of [IndexAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisIndexAccessor<Arguments> extends Accessor<Arguments> {
- Expression index;
- VariableDeclaration indexVariable;
- Procedure getter, setter;
-
- ThisIndexAccessor(
- BuilderHelper helper, this.index, this.getter, this.setter, Token token)
- : super(helper, token);
-
- Expression _makeSimpleRead() {
- return new ShadowMethodInvocation(new ShadowThisExpression(), indexGetName,
- new ShadowArguments(<Expression>[index]),
- interfaceTarget: getter)
- ..fileOffset = offsetForToken(token);
- }
-
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- var write = new ShadowMethodInvocation(new ShadowThisExpression(),
- indexSetName, new ShadowArguments(<Expression>[index, value]),
- interfaceTarget: setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable);
- }
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- var read = new ShadowMethodInvocation(new ShadowThisExpression(),
- indexGetName, new ShadowArguments(<Expression>[indexAccess()]),
- interfaceTarget: getter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- var write = new ShadowMethodInvocation(new ShadowThisExpression(),
- indexSetName, new ShadowArguments(<Expression>[indexAccess(), value]),
- interfaceTarget: setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- _makeWriteAndReturn(
- Expression value, ShadowComplexAssignment complexAssignment) {
- var valueVariable = new VariableDeclaration.forValue(value);
- var write = new ShadowMethodInvocation(
- new ShadowThisExpression(),
- indexSetName,
- new ShadowArguments(
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- interfaceTarget: setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- var dummy = new VariableDeclaration.forValue(write);
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
- Expression _finish(
- Expression body, ShadowComplexAssignment complexAssignment) {
- return super._finish(makeLet(indexVariable, body), complexAssignment);
- }
-}
-
-class SuperIndexAccessor<Arguments> extends Accessor<Arguments> {
- Expression index;
- VariableDeclaration indexVariable;
- Member getter, setter;
-
- SuperIndexAccessor(
- BuilderHelper helper, this.index, this.getter, this.setter, Token token)
- : super(helper, token);
-
- indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable);
- }
-
- Expression _makeSimpleRead() {
- if (getter == null) {
- helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
- isSuper: true);
- }
- // TODO(ahe): Use [DirectMethodInvocation] when possible.
- return new ShadowSuperMethodInvocation(
- indexGetName, new ShadowArguments(<Expression>[index]), getter)
- ..fileOffset = offsetForToken(token);
- }
-
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- if (setter == null) {
- helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
- isSuper: true);
- }
- var write = new SuperMethodInvocation(
- indexSetName, new ShadowArguments(<Expression>[index, value]), setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- if (getter == null) {
- helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
- isSuper: true);
- }
- var read = new SuperMethodInvocation(
- indexGetName, new ShadowArguments(<Expression>[indexAccess()]), getter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- if (setter == null) {
- helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
- isSuper: true);
- }
- var write = new SuperMethodInvocation(indexSetName,
- new ShadowArguments(<Expression>[indexAccess(), value]), setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- return write;
- }
-
- _makeWriteAndReturn(
- Expression value, ShadowComplexAssignment complexAssignment) {
- var valueVariable = new VariableDeclaration.forValue(value);
- if (setter == null) {
- helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
- isSuper: true);
- }
- var write = new SuperMethodInvocation(
- indexSetName,
- new ShadowArguments(
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- setter)
- ..fileOffset = offsetForToken(token);
- complexAssignment?.write = write;
- var dummy = new VariableDeclaration.forValue(write);
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
- Expression _finish(
- Expression body, ShadowComplexAssignment complexAssignment) {
- return super._finish(makeLet(indexVariable, body), complexAssignment);
- }
-}
-
-class StaticAccessor<Arguments> extends Accessor<Arguments> {
- Member readTarget;
- Member writeTarget;
-
- StaticAccessor(
- BuilderHelper helper, this.readTarget, this.writeTarget, Token token)
- : super(helper, token);
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- if (readTarget == null) {
- return makeInvalidRead();
- } else {
- var read = helper.makeStaticGet(readTarget, token);
- complexAssignment?.read = read;
- return read;
- }
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- Expression write;
- if (writeTarget == null) {
- write = makeInvalidWrite(value);
- } else {
- write = new StaticSet(writeTarget, value);
- complexAssignment?.write = write;
- }
- write.fileOffset = offsetForToken(token);
- return write;
- }
-}
-
-abstract class LoadLibraryAccessor<Arguments> extends Accessor<Arguments> {
- final LoadLibraryBuilder builder;
-
- LoadLibraryAccessor(BuilderHelper helper, Token token, this.builder)
- : super(helper, token);
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- var read =
- helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
- complexAssignment?.read = read;
- return read;
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- Expression write = makeInvalidWrite(value);
- write.fileOffset = offsetForToken(token);
- return write;
- }
-}
-
-abstract class DeferredAccessor<Arguments> extends Accessor<Arguments> {
- final PrefixBuilder builder;
- final Accessor accessor;
-
- DeferredAccessor(
- BuilderHelper helper, Token token, this.builder, this.accessor)
- : super(helper, token);
-
- Expression _makeSimpleRead() {
- return helper.wrapInDeferredCheck(
- accessor._makeSimpleRead(), builder, token.charOffset);
- }
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- return helper.wrapInDeferredCheck(
- accessor._makeRead(complexAssignment), builder, token.charOffset);
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- return helper.wrapInDeferredCheck(
- accessor._makeWrite(value, voidContext, complexAssignment),
- builder,
- token.charOffset);
- }
-}
-
-class ReadOnlyAccessor<Arguments> extends Accessor<Arguments> {
- Expression expression;
- VariableDeclaration value;
-
- ReadOnlyAccessor(BuilderHelper helper, this.expression, Token token)
- : super(helper, token);
-
- Expression _makeSimpleRead() => expression;
-
- Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- value ??= new VariableDeclaration.forValue(expression);
- return new VariableGet(value);
- }
-
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) {
- var write = makeInvalidWrite(value);
- complexAssignment?.write = write;
- return write;
- }
-
- Expression _finish(
- Expression body, ShadowComplexAssignment complexAssignment) =>
- super._finish(makeLet(value, body), complexAssignment);
-}
-
-abstract class DelayedErrorAccessor<Arguments> extends Accessor<Arguments> {
- DelayedErrorAccessor(BuilderHelper helper, Token token)
- : super(helper, token);
-
- Expression buildError();
-
- Expression _makeSimpleRead() => buildError();
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) =>
- buildError();
- Expression _makeRead(ShadowComplexAssignment complexAssignment) =>
- buildError();
- Expression _makeWrite(Expression value, bool voidContext,
- ShadowComplexAssignment complexAssignment) =>
- buildError();
-}
-
-Expression makeLet(VariableDeclaration variable, Expression body) {
- if (variable == null) return body;
- return new Let(variable, body);
-}
-
-Expression makeBinary(
- Expression left, Name operator, Procedure interfaceTarget, Expression right,
- {int offset: TreeNode.noOffset}) {
- return new ShadowMethodInvocation(
- left, operator, new ShadowArguments(<Expression>[right]),
- interfaceTarget: interfaceTarget)
- ..fileOffset = offset;
-}
-
-Expression buildIsNull(Expression value, int offset) {
- return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset);
-}
-
-VariableDeclaration makeOrReuseVariable(Expression value) {
- // TODO: Devise a way to remember if a variable declaration was reused
- // or is fresh (hence needs a let binding).
- return new VariableDeclaration.forValue(value);
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart
index 7d5877f..e48156c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart
@@ -14,3 +14,35 @@
export 'package:kernel/core_types.dart' show CoreTypes;
export 'package:kernel/transformations/flags.dart' show TransformerFlag;
+
+export 'package:kernel/text/ast_to_text.dart' show NameSystem;
+
+import 'package:kernel/text/ast_to_text.dart' show NameSystem, Printer;
+
+import 'package:kernel/ast.dart' show Class, Member, Node;
+
+void printNodeOn(Node node, StringSink sink, {NameSystem syntheticNames}) {
+ if (node == null) {
+ sink.write("null");
+ } else {
+ syntheticNames ??= new NameSystem();
+ new Printer(sink, syntheticNames: syntheticNames).writeNode(node);
+ }
+}
+
+void printQualifiedNameOn(Member member, StringSink sink,
+ {NameSystem syntheticNames}) {
+ if (member == null) {
+ sink.write("null");
+ } else {
+ syntheticNames ??= new NameSystem();
+ sink.write(member.enclosingLibrary.importUri);
+ sink.write("::");
+ Class cls = member.enclosingClass;
+ if (cls != null) {
+ sink.write(cls.name ?? syntheticNames.nameClass(cls));
+ sink.write("::");
+ }
+ sink.write(member.name?.name ?? syntheticNames.nameMember(member));
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index b2cad0c..6817deb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -15,7 +15,6 @@
Catch,
CheckLibraryIsLoaded,
Class,
- ConditionalExpression,
Constructor,
ConstructorInvocation,
ContinueSwitchStatement,
@@ -39,23 +38,27 @@
Name,
NamedExpression,
NamedType,
+ Node,
Procedure,
ProcedureKind,
+ PropertySet,
Rethrow,
ReturnStatement,
Statement,
StaticGet,
- StaticInvocation,
+ StaticSet,
StringConcatenation,
SuperInitializer,
+ SuperMethodInvocation,
+ SuperPropertySet,
SwitchCase,
- ThisExpression,
Throw,
TreeNode,
TypeParameter,
TypeParameterType,
VariableDeclaration,
VariableGet,
+ VariableSet,
VoidType,
setParents;
@@ -63,14 +66,12 @@
show
ShadowAssertInitializer,
ShadowAssertStatement,
- ShadowBlock,
ShadowBreakStatement,
ShadowCascadeExpression,
ShadowComplexAssignment,
ShadowConstructorInvocation,
ShadowContinueSwitchStatement,
ShadowDeferredCheck,
- ShadowDoStatement,
ShadowExpressionStatement,
ShadowFactoryConstructorInvocation,
ShadowFieldInitializer,
@@ -89,9 +90,10 @@
ShadowMethodInvocation,
ShadowNamedFunctionExpression,
ShadowNullAwareMethodInvocation,
+ ShadowNullAwarePropertyGet,
ShadowPropertyAssign,
+ ShadowPropertyGet,
ShadowRedirectingInitializer,
- ShadowRethrow,
ShadowReturnStatement,
ShadowStaticAssignment,
ShadowStaticGet,
@@ -101,11 +103,7 @@
ShadowSuperPropertyGet,
ShadowSwitchStatement,
ShadowSyntheticExpression,
- ShadowThrow,
- ShadowTryCatch,
- ShadowTryFinally,
ShadowVariableAssignment,
ShadowVariableDeclaration,
ShadowVariableGet,
- ShadowWhileStatement,
ShadowYieldStatement;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
index e825cf4..f2ff3b6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
@@ -39,4 +39,9 @@
TypeInferrer typeInferrer)
: super(library, member, scope, formalParameterScope, hierarchy,
coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
+
+ @override
+ void enterThenForTypePromotion(Expression condition) {
+ typePromoter.enterThen(condition);
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 884971a..7272014 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -8,21 +8,27 @@
show
Class,
Constructor,
+ ThisExpression,
DartType,
DynamicType,
Expression,
Field,
FunctionNode,
InterfaceType,
+ AsExpression,
ListLiteral,
Member,
Name,
Procedure,
+ ReturnStatement,
+ VoidType,
+ MethodInvocation,
ProcedureKind,
StaticGet,
Supertype,
TypeParameter,
TypeParameterType,
+ Arguments,
VariableDeclaration;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -84,6 +90,8 @@
import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
+import 'kernel_target.dart' show KernelTarget;
+
abstract class KernelClassBuilder
extends ClassBuilder<KernelTypeBuilder, InterfaceType> {
KernelClassBuilder actualOrigin;
@@ -382,20 +390,48 @@
noSuchMethod.enclosingClass.superclass != null;
}
- void addNoSuchMethodForwarderForProcedure(
- Procedure procedure, ClassHierarchy hierarchy) {
+ void transformProcedureToNoSuchMethodForwarder(
+ Member noSuchMethodInterface, KernelTarget target, Procedure procedure) {
+ String prefix =
+ procedure.isGetter ? 'get:' : procedure.isSetter ? 'set:' : '';
+ Expression invocation = target.backendTarget.instantiateInvocation(
+ target.loader.coreTypes,
+ new ThisExpression(),
+ prefix + procedure.name.name,
+ new Arguments.forwarded(procedure.function),
+ procedure.fileOffset,
+ /*isSuper=*/ false);
+ Expression result = new MethodInvocation(new ThisExpression(),
+ noSuchMethodName, new Arguments([invocation]), noSuchMethodInterface)
+ ..fileOffset = procedure.fileOffset;
+ if (procedure.function.returnType is! VoidType) {
+ result = new AsExpression(result, procedure.function.returnType)
+ ..isTypeError = true
+ ..fileOffset = procedure.fileOffset;
+ }
+ procedure.function.body = new ReturnStatement(result)
+ ..fileOffset = procedure.fileOffset;
+ procedure.function.body.parent = procedure.function;
+
+ procedure.isAbstract = false;
+ procedure.isNoSuchMethodForwarder = true;
+ procedure.isForwardingStub = false;
+ procedure.isForwardingSemiStub = false;
+ }
+
+ void addNoSuchMethodForwarderForProcedure(Member noSuchMethod,
+ KernelTarget target, Procedure procedure, ClassHierarchy hierarchy) {
CloneWithoutBody cloner = new CloneWithoutBody(
typeSubstitution: getSubstitutionMap(
hierarchy.getClassAsInstanceOf(cls, procedure.enclosingClass)));
Procedure cloned = cloner.clone(procedure);
- cloned.isAbstract = true;
- cloned.isNoSuchMethodForwarder = true;
-
+ transformProcedureToNoSuchMethodForwarder(noSuchMethod, target, cloned);
cls.procedures.add(cloned);
cloned.parent = cls;
}
- void addNoSuchMethodForwarders(ClassHierarchy hierarchy) {
+ void addNoSuchMethodForwarders(
+ KernelTarget target, ClassHierarchy hierarchy) {
if (!hasUserDefinedNoSuchMethod(cls, hierarchy)) {
return;
}
@@ -443,14 +479,20 @@
List<Member> concrete = hierarchy.getDispatchTargets(cls);
List<Member> declared = hierarchy.getDeclaredMembers(cls);
+
+ Member noSuchMethod = ClassHierarchy.findMemberByName(
+ hierarchy.getInterfaceMembers(cls), noSuchMethodName);
+
for (Member member in hierarchy.getInterfaceMembers(cls)) {
if (member is Procedure &&
ClassHierarchy.findMemberByName(concrete, member.name) == null &&
!existingForwardersNames.contains(member.name)) {
if (ClassHierarchy.findMemberByName(declared, member.name) != null) {
- member.isNoSuchMethodForwarder = true;
+ transformProcedureToNoSuchMethodForwarder(
+ noSuchMethod, target, member);
} else {
- addNoSuchMethodForwarderForProcedure(member, hierarchy);
+ addNoSuchMethodForwarderForProcedure(
+ noSuchMethod, target, member, hierarchy);
}
existingForwardersNames.add(member.name);
}
@@ -467,9 +509,11 @@
!existingSetterForwardersNames.contains(member.name)) {
if (ClassHierarchy.findMemberByName(declaredSetters, member.name) !=
null) {
- member.isNoSuchMethodForwarder = true;
+ transformProcedureToNoSuchMethodForwarder(
+ noSuchMethod, target, member);
} else {
- addNoSuchMethodForwarderForProcedure(member, hierarchy);
+ addNoSuchMethodForwarderForProcedure(
+ noSuchMethod, target, member, hierarchy);
}
existingSetterForwardersNames.add(member.name);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 463f5b4..b5f6854 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -990,47 +990,35 @@
return count;
}
- int instantiateToBound(TypeBuilder dynamicType, TypeBuilder bottomType,
+ int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder bottomType,
ClassBuilder objectClass) {
int count = 0;
+ bool strongMode = loader.target.strongMode;
+
+ int computeDefaultTypesForVariables(List<TypeVariableBuilder> variables) {
+ if (variables == null) return 0;
+ List<KernelTypeBuilder> calculatedBounds = strongMode
+ ? calculateBounds(variables, dynamicType, bottomType, objectClass)
+ : null;
+ for (int i = 0; i < variables.length; ++i) {
+ variables[i].defaultType =
+ strongMode ? calculatedBounds[i] : dynamicType;
+ }
+ return variables.length;
+ }
for (var declaration in libraryDeclaration.members.values) {
if (declaration is KernelClassBuilder) {
- if (declaration.typeVariables != null) {
- List<KernelTypeBuilder> calculatedBounds;
- if (loader.target.strongMode) {
- calculatedBounds = calculateBounds(declaration.typeVariables,
- dynamicType, bottomType, objectClass);
- } else {
- calculatedBounds =
- new List<KernelTypeBuilder>(declaration.typeVariables.length);
- for (int i = 0; i < calculatedBounds.length; ++i) {
- calculatedBounds[i] = dynamicType;
- }
+ count += computeDefaultTypesForVariables(declaration.typeVariables);
+ declaration.forEach((String name, Builder member) {
+ if (member is KernelProcedureBuilder) {
+ count += computeDefaultTypesForVariables(member.typeVariables);
}
- for (int i = 0; i < calculatedBounds.length; ++i) {
- declaration.typeVariables[i].defaultType = calculatedBounds[i];
- }
- count += calculatedBounds.length;
- }
+ });
} else if (declaration is KernelFunctionTypeAliasBuilder) {
- if (declaration.typeVariables != null) {
- List<KernelTypeBuilder> calculatedBounds;
- if (loader.target.strongMode) {
- calculatedBounds = calculateBounds(declaration.typeVariables,
- dynamicType, bottomType, objectClass);
- } else {
- calculatedBounds =
- new List<KernelTypeBuilder>(declaration.typeVariables.length);
- for (int i = 0; i < calculatedBounds.length; ++i) {
- calculatedBounds[i] = dynamicType;
- }
- }
- for (int i = 0; i < calculatedBounds.length; ++i) {
- declaration.typeVariables[i].defaultType = calculatedBounds[i];
- }
- count += calculatedBounds.length;
- }
+ count += computeDefaultTypesForVariables(declaration.typeVariables);
+ } else if (declaration is KernelFunctionBuilder) {
+ count += computeDefaultTypesForVariables(declaration.typeVariables);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 71372b9..fac004f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -20,26 +20,55 @@
import 'dart:core' hide MapEntry;
-import 'package:front_end/src/base/instrumentation.dart';
-import 'package:front_end/src/fasta/fasta_codes.dart';
-import 'package:front_end/src/fasta/kernel/body_builder.dart';
-import 'package:front_end/src/fasta/kernel/fasta_accessors.dart';
-import 'package:front_end/src/fasta/source/source_class_builder.dart';
-import 'package:front_end/src/fasta/source/source_library_builder.dart';
-import 'package:front_end/src/fasta/type_inference/interface_resolver.dart';
-import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
-import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
-import 'package:front_end/src/fasta/type_inference/type_promotion.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
import 'package:kernel/ast.dart' hide InvalidExpression, InvalidInitializer;
+
import 'package:kernel/clone.dart' show CloneVisitor;
-import 'package:kernel/frontend/accessors.dart';
-import 'package:kernel/type_algebra.dart';
+
+import 'package:kernel/type_algebra.dart' show Substitution;
+
+import '../../base/instrumentation.dart'
+ show
+ Instrumentation,
+ InstrumentationValueForMember,
+ InstrumentationValueForType,
+ InstrumentationValueForTypeArgs;
+
+import '../fasta_codes.dart'
+ show templateCantUseSuperBoundedTypeForInstanceCreation;
import '../problems.dart' show unhandled, unsupported;
+import '../source/source_class_builder.dart' show SourceClassBuilder;
+
+import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+
+import '../type_inference/interface_resolver.dart' show InterfaceResolver;
+
+import '../type_inference/type_inference_engine.dart'
+ show
+ FieldInitializerInferenceNode,
+ IncludesTypeParametersCovariantly,
+ InferenceNode,
+ TypeInferenceEngine,
+ TypeInferenceEngineImpl;
+
+import '../type_inference/type_inferrer.dart'
+ show TypeInferrer, TypeInferrerDisabled, TypeInferrerImpl;
+
+import '../type_inference/type_promotion.dart'
+ show TypePromoter, TypePromoterImpl, TypePromotionFact, TypePromotionScope;
+
+import '../type_inference/type_schema.dart' show UnknownType;
+
+import '../type_inference/type_schema_elimination.dart' show greatestClosure;
+
+import '../type_inference/type_schema_environment.dart'
+ show TypeSchemaEnvironment, getPositionalParameterType;
+
+import 'body_builder.dart' show combineStatements;
+
+import 'expression_generator.dart' show BuilderHelper, makeLet;
+
/// Indicates whether type inference involving conditional expressions should
/// always use least upper bound.
///
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 96b6930..f76f827 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -242,7 +242,7 @@
objectType.bind(loader.coreLibrary["Object"]);
bottomType.bind(loader.coreLibrary["Null"]);
loader.resolveTypes();
- loader.instantiateToBound(dynamicType, bottomType, objectClassBuilder);
+ loader.computeDefaultTypes(dynamicType, bottomType, objectClassBuilder);
List<SourceClassBuilder> myClasses = collectMyClasses();
loader.checkSemantics(myClasses);
loader.finishTypeVariables(objectClassBuilder, dynamicType);
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index fa6795b..1ba0f1e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -137,15 +137,7 @@
new List<KernelTypeBuilder>(variables.length);
for (int i = 0; i < variables.length; i++) {
- KernelTypeBuilder type = variables[i].bound;
- if (type == null ||
- type is KernelNamedTypeBuilder &&
- type.builder is KernelClassBuilder &&
- (type.builder as KernelClassBuilder).cls == objectClass?.cls) {
- type = dynamicType;
- }
-
- bounds[i] = type;
+ bounds[i] = variables[i].bound ?? dynamicType;
}
TypeVariablesGraph graph = new TypeVariablesGraph(variables, bounds);
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index 8bcda60..d95f852 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -6,7 +6,10 @@
import 'dart:io' show BytesBuilder, File, IOSink;
-import 'package:kernel/ast.dart' show Library, Component;
+import 'package:kernel/clone.dart' show CloneVisitor;
+
+import 'package:kernel/ast.dart'
+ show Library, Component, Procedure, Class, TypeParameter, Supertype;
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
@@ -58,6 +61,39 @@
return byteSink.builder.takeBytes();
}
+List<int> serializeProcedure(Procedure procedure) {
+ Library fakeLibrary =
+ new Library(new Uri(scheme: 'evaluate', path: 'source'));
+
+ if (procedure.parent is Class) {
+ Class realClass = procedure.parent;
+
+ CloneVisitor cloner = new CloneVisitor();
+
+ Class fakeClass = new Class(name: realClass.name);
+ for (TypeParameter typeParam in realClass.typeParameters) {
+ fakeClass.typeParameters.add(typeParam.accept(cloner));
+ }
+
+ fakeClass.parent = fakeLibrary;
+ fakeClass.supertype = new Supertype.byReference(
+ realClass.supertype.className,
+ realClass.supertype.typeArguments.map(cloner.visitType).toList());
+
+ // Rebind the type parameters in the procedure.
+ procedure = procedure.accept(cloner);
+ procedure.parent = fakeClass;
+ fakeClass.procedures.add(procedure);
+ fakeLibrary.classes.add(fakeClass);
+ } else {
+ fakeLibrary.procedures.add(procedure);
+ procedure.parent = fakeLibrary;
+ }
+
+ Component program = new Component(libraries: [fakeLibrary]);
+ return serializeComponent(program);
+}
+
/// A [Sink] that directly writes data into a byte builder.
class ByteSink implements Sink<List<int>> {
final BytesBuilder builder = new BytesBuilder();
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 4cb980b..65b8b20 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -1196,6 +1196,11 @@
}
@override
+ void handleParenthesizedCondition(Token token) {
+ listener?.handleParenthesizedCondition(token);
+ }
+
+ @override
void handleParenthesizedExpression(Token token) {
listener?.handleParenthesizedExpression(token);
}
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index b9bbf76..962bded 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -102,10 +102,8 @@
/// Identifier is the name of a type variable being declared (e.g. `Foo` in
/// `class C<Foo extends num> {}`).
- static const typeVariableDeclaration = const IdentifierContext(
- 'typeVariableDeclaration',
- inDeclaration: true,
- isBuiltInIdentifierAllowed: false);
+ static const typeVariableDeclaration =
+ const TypeVariableDeclarationIdentifierContext();
/// Identifier is the start of a reference to a type that starts with prefix.
static const prefixedTypeReference =
@@ -121,15 +119,16 @@
/// Identifier is a name being declared by a top level variable declaration.
static const topLevelVariableDeclaration =
- const TopLevelVariableIdentifierContext();
+ const TopLevelDeclarationIdentifierContext(
+ 'topLevelVariableDeclaration', const [';', '=', ',']);
/// Identifier is a name being declared by a field declaration.
static const fieldDeclaration = const FieldDeclarationIdentifierContext();
/// Identifier is the name being declared by a top level function declaration.
- static const topLevelFunctionDeclaration = const IdentifierContext(
- 'topLevelFunctionDeclaration',
- inDeclaration: true);
+ static const topLevelFunctionDeclaration =
+ const TopLevelDeclarationIdentifierContext(
+ 'topLevelFunctionDeclaration', const ['<', '(', '{', '=>']);
/// Identifier is the start of the name being declared by a method
/// declaration.
@@ -149,7 +148,8 @@
/// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
/// occur as part of error recovery? If it's only as part of error recovery,
/// perhaps we should just re-use methodDeclaration.
- static const operatorName = const IdentifierContext('operatorName');
+ static const operatorName =
+ const MethodDeclarationIdentifierContext.continuation();
/// Identifier is the name being declared by a local function declaration that
/// uses a "get" or "set" keyword.
@@ -163,17 +163,15 @@
/// Identifier is the start of the name being declared by a local function
/// declaration.
static const localFunctionDeclaration =
- const IdentifierContext('localFunctionDeclaration', inDeclaration: true);
+ const LocalFunctionDeclarationIdentifierContext();
/// Identifier is part of the name being declared by a local function
/// declaration, but it's not the first identifier of the name.
///
/// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
/// occur as part of error recovery?
- static const localFunctionDeclarationContinuation = const IdentifierContext(
- 'localFunctionDeclarationContinuation',
- inDeclaration: true,
- isContinuation: true);
+ static const localFunctionDeclarationContinuation =
+ const LocalFunctionDeclarationIdentifierContext.continuation();
/// Identifier is the name appearing in a function expression.
///
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index f18b2ac..a5d808f 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -12,10 +12,9 @@
import 'parser.dart' show Parser;
-import 'type_info.dart'
- show insertSyntheticIdentifierAfter, isValidTypeReference;
+import 'type_info.dart' show isValidTypeReference;
-import 'util.dart' show optional;
+import 'util.dart' show isOneOfOrEof, optional;
/// See [IdentifierContext.classOrNamedMixinDeclaration].
class ClassOrNamedMixinIdentifierContext extends IdentifierContext {
@@ -46,7 +45,7 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
@@ -88,7 +87,7 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
@@ -123,7 +122,7 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
@@ -148,11 +147,11 @@
identifier, fasta.templateExpectedIdentifier);
if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
isOneOfOrEof(identifier, const [',', '}'])) {
- return insertSyntheticIdentifierAfter(token, parser);
+ return parser.rewriter.insertSyntheticIdentifier(token);
} else if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- return insertSyntheticIdentifierAfter(identifier, parser);
+ return parser.rewriter.insertSyntheticIdentifier(identifier);
}
return identifier;
}
@@ -204,7 +203,7 @@
identifier = token.next;
}
// Insert a synthetic identifier to satisfy listeners.
- return insertSyntheticIdentifierAfter(token, parser);
+ return parser.rewriter.insertSyntheticIdentifier(token);
}
}
@@ -257,11 +256,11 @@
parser.reportRecoverableErrorWithToken(
identifier, fasta.templateExpectedIdentifier);
// Insert a synthetic identifier to satisfy listeners.
- return insertSyntheticIdentifierAfter(token, parser);
+ return parser.rewriter.insertSyntheticIdentifier(token);
}
}
-/// See [IdentifierContext].importPrefixDeclaration
+/// See [IdentifierContext.importPrefixDeclaration].
class ImportPrefixIdentifierContext extends IdentifierContext {
const ImportPrefixIdentifierContext()
: super('importPrefixDeclaration',
@@ -291,7 +290,44 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
+ }
+ }
+ return identifier;
+ }
+}
+
+/// See [IdentifierContext.localFunctionDeclaration]
+/// and [IdentifierContext.localFunctionDeclarationContinuation].
+class LocalFunctionDeclarationIdentifierContext extends IdentifierContext {
+ const LocalFunctionDeclarationIdentifierContext()
+ : super('localFunctionDeclaration', inDeclaration: true);
+
+ const LocalFunctionDeclarationIdentifierContext.continuation()
+ : super('localFunctionDeclarationContinuation',
+ inDeclaration: true, isContinuation: true);
+
+ @override
+ Token ensureIdentifier(Token token, Parser parser) {
+ Token identifier = token.next;
+ assert(identifier.kind != IDENTIFIER_TOKEN);
+ if (identifier.isIdentifier) {
+ checkAsyncAwaitYieldAsIdentifier(identifier, parser);
+ return identifier;
+ }
+
+ // Recovery
+ if (isOneOfOrEof(identifier, const ['.', '(', '{', '=>']) ||
+ looksLikeStartOfNextStatement(identifier)) {
+ identifier = parser.insertSyntheticIdentifier(token, this,
+ message: fasta.templateExpectedIdentifier.withArguments(identifier));
+ } else {
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateExpectedIdentifier);
+ if (!identifier.isKeywordOrIdentifier) {
+ // When in doubt, consume the token to ensure we make progress
+ // but insert a synthetic identifier to satisfy listeners.
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
@@ -335,7 +371,7 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
@@ -367,14 +403,16 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
}
}
-/// See [IdentifierContext.methodDeclaration].
+/// See [IdentifierContext.methodDeclaration],
+/// and [IdentifierContext.methodDeclarationContinuation],
+/// and [IdentifierContext.operatorName].
class MethodDeclarationIdentifierContext extends IdentifierContext {
const MethodDeclarationIdentifierContext()
: super('methodDeclaration', inDeclaration: true);
@@ -383,6 +421,9 @@
: super('methodDeclarationContinuation',
inDeclaration: true, isContinuation: true);
+ const MethodDeclarationIdentifierContext.operatorName()
+ : super('operatorName', inDeclaration: true);
+
@override
Token ensureIdentifier(Token token, Parser parser) {
Token identifier = token.next;
@@ -413,16 +454,18 @@
}
}
-/// See [IdentifierContext.topLevelVariableDeclaration].
-class TopLevelVariableIdentifierContext extends IdentifierContext {
- const TopLevelVariableIdentifierContext()
- : super('topLevelVariableDeclaration', inDeclaration: true);
+/// See [IdentifierContext.topLevelFunctionDeclaration]
+/// and [IdentifierContext.topLevelVariableDeclaration].
+class TopLevelDeclarationIdentifierContext extends IdentifierContext {
+ final List<String> followingValues;
+
+ const TopLevelDeclarationIdentifierContext(String name, this.followingValues)
+ : super(name, inDeclaration: true);
@override
Token ensureIdentifier(Token token, Parser parser) {
Token identifier = token.next;
assert(identifier.kind != IDENTIFIER_TOKEN);
- const followingValues = const [';', '=', ','];
if (identifier.isIdentifier) {
Token next = identifier.next;
@@ -430,9 +473,9 @@
isOneOfOrEof(next, followingValues)) {
return identifier;
}
- // Although this is a valid top level var name, the var declaration
+ // Although this is a valid top level name, the declaration
// is invalid and this looks like the start of the next declaration.
- // In this situation, fall through to insert a synthetic var name.
+ // In this situation, fall through to insert a synthetic name.
}
// Recovery
@@ -449,14 +492,14 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
}
}
-/// See [IdentifierContext].typedefDeclaration
+/// See [IdentifierContext.typedefDeclaration].
class TypedefDeclarationIdentifierContext extends IdentifierContext {
const TypedefDeclarationIdentifierContext()
: super('typedefDeclaration',
@@ -467,11 +510,15 @@
Token identifier = token.next;
assert(identifier.kind != IDENTIFIER_TOKEN);
if (identifier.type.isPseudo) {
+ if (optional('Function', identifier)) {
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateExpectedIdentifier);
+ }
return identifier;
}
// Recovery
- const followingValues = const ['(', '<', '=', ';', 'var'];
+ const followingValues = const ['(', '<', '=', ';'];
if (identifier.type.isBuiltIn &&
isOneOfOrEof(identifier.next, followingValues)) {
parser.reportRecoverableErrorWithToken(
@@ -486,7 +533,7 @@
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
- identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
@@ -538,7 +585,39 @@
next = token.next;
}
// Insert a synthetic identifier to satisfy listeners.
- return insertSyntheticIdentifierAfter(token, parser);
+ return parser.rewriter.insertSyntheticIdentifier(token);
+ }
+}
+
+// See [IdentifierContext.typeVariableDeclaration].
+class TypeVariableDeclarationIdentifierContext extends IdentifierContext {
+ const TypeVariableDeclarationIdentifierContext()
+ : super('typeVariableDeclaration',
+ inDeclaration: true, isBuiltInIdentifierAllowed: false);
+
+ @override
+ Token ensureIdentifier(Token token, Parser parser) {
+ Token identifier = token.next;
+ assert(identifier.kind != IDENTIFIER_TOKEN);
+ if (identifier.type.isPseudo) {
+ return identifier;
+ }
+
+ // Recovery
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateExpectedIdentifier);
+ const followingValues = const ['<', '>', ';', '}', 'extends', 'super'];
+ if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
+ looksLikeStartOfNextClassMember(identifier) ||
+ looksLikeStartOfNextStatement(identifier) ||
+ isOneOfOrEof(identifier, followingValues)) {
+ identifier = parser.rewriter.insertSyntheticIdentifier(token);
+ } else {
+ // When in doubt, consume the token to ensure we make progress
+ // but insert a synthetic identifier to satisfy listeners.
+ identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
+ }
+ return identifier;
}
}
@@ -554,15 +633,6 @@
}
}
-bool isOneOfOrEof(Token token, Iterable<String> followingValues) {
- for (String tokenValue in followingValues) {
- if (optional(tokenValue, token)) {
- return true;
- }
- }
- return token.isEof;
-}
-
bool looksLikeStartOfNextClassMember(Token token) =>
token.isModifier || isOneOfOrEof(token, const ['get', 'set', 'void']);
@@ -585,4 +655,5 @@
bool looksLikeStartOfNextTopLevelDeclaration(Token token) =>
token.isTopLevelKeyword ||
- isOneOfOrEof(token, const ['const', 'get', 'final', 'set', 'var', 'void']);
+ isOneOfOrEof(
+ token, const ['class', 'const', 'get', 'final', 'set', 'var', 'void']);
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 5c3e99c..e7bcb52 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1113,6 +1113,18 @@
logEvent("InvalidOperatorName");
}
+ /// Handle the condition in a control structure:
+ /// - if statement
+ /// - do while loop
+ /// - switch statement
+ /// - while loop
+ void handleParenthesizedCondition(Token token) {
+ logEvent("ParenthesizedCondition");
+ }
+
+ /// Handle a parenthesized expression.
+ /// These may be within the condition expression of a control structure
+ /// but will not be the condition of a control structure.
void handleParenthesizedExpression(Token token) {
logEvent("ParenthesizedExpression");
}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 53154e7..d0777a2 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -89,6 +89,7 @@
TypeParamOrArgInfo,
computeMethodTypeArguments,
computeType,
+ computeTypeParam,
computeTypeParamOrArg,
isGeneralizedFunctionType,
isValidTypeReference,
@@ -501,8 +502,11 @@
// and continue parsing as a top level function.
rewriter.insertTokenAfter(
next,
- new SyntheticStringToken(TokenType.IDENTIFIER,
- '#synthetic_function_${next.charOffset}', token.charOffset, 0));
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER,
+ '#synthetic_function_${next.charOffset}',
+ next.next.charOffset,
+ 0));
return parseTopLevelMemberImpl(next);
}
// Ignore any preceding modifiers and just report the unexpected token
@@ -546,18 +550,14 @@
directiveState?.checkDeclaration();
return parseEnum(previous);
} else if (identical(value, 'typedef')) {
- Token next = token.next;
+ String nextValue = token.next.stringValue;
directiveState?.checkDeclaration();
- if (next.isIdentifier || optional("void", next)) {
- return parseTypedef(previous);
- } else if (next.isTopLevelKeyword ||
- optional('var', next) ||
- optional('=', next) ||
- next.isEof) {
- // Recovery
- return parseTypedef(previous);
- } else {
+ if (identical('(', nextValue) ||
+ identical('<', nextValue) ||
+ identical('.', nextValue)) {
return parseTopLevelMemberImpl(previous);
+ } else {
+ return parseTypedef(previous);
}
} else {
// The remaining top level keywords are built-in keywords
@@ -1045,9 +1045,13 @@
/// ```
/// typeAlias:
- /// metadata 'typedef' typeAliasBody
+ /// metadata 'typedef' typeAliasBody |
+ /// metadata 'typedef' identifier typeParameters? '=' functionType ';'
/// ;
///
+ /// functionType:
+ /// returnType? 'Function' typeParameters? parameterTypeList
+ ///
/// typeAliasBody:
/// functionTypeAlias
/// ;
@@ -1064,18 +1068,21 @@
Token typedefKeyword = token.next;
assert(optional('typedef', typedefKeyword));
listener.beginFunctionTypeAlias(typedefKeyword);
+ TypeInfo typeInfo = computeType(typedefKeyword, false);
+ token = typeInfo.skipType(typedefKeyword).next;
Token equals;
- Token afterType = parseType(typedefKeyword, TypeContinuation.Typedef);
- if (afterType == null) {
- token = ensureIdentifier(
- typedefKeyword, IdentifierContext.typedefDeclaration);
- token = parseTypeVariablesOpt(token).next;
- equals = token;
- expect('=', token);
- token = parseType(token);
+ TypeParamOrArgInfo typeParam = computeTypeParamOrArg(token);
+ if (typeInfo == noType &&
+ (token.kind == IDENTIFIER_TOKEN || token.type.isPseudo) &&
+ optional('=', typeParam.skip(token).next)) {
+ listener.handleIdentifier(token, IdentifierContext.typedefDeclaration);
+ equals = typeParam.parseVariables(token, this).next;
+ assert(optional('=', equals));
+ token = computeType(equals, true).ensureTypeOrVoid(equals, this);
} else {
- token = ensureIdentifier(afterType, IdentifierContext.typedefDeclaration);
- token = parseTypeVariablesOpt(token);
+ token = typeInfo.parseType(typedefKeyword, this);
+ token = ensureIdentifier(token, IdentifierContext.typedefDeclaration);
+ token = typeParam.parseVariables(token, this);
token =
parseFormalParametersRequiredOpt(token, MemberKind.FunctionTypeAlias);
}
@@ -1351,7 +1358,8 @@
Token endInlineFunctionType;
if (beforeInlineFunctionType != null) {
- endInlineFunctionType = parseTypeVariablesOpt(beforeInlineFunctionType);
+ endInlineFunctionType = computeTypeParamOrArg(beforeInlineFunctionType)
+ .parseVariables(beforeInlineFunctionType, this);
listener.beginFunctionTypedFormalParameter(beforeInlineFunctionType.next);
token = typeInfo.parseType(beforeType, this);
endInlineFunctionType = parseFormalParametersRequiredOpt(
@@ -1648,10 +1656,10 @@
Token abstractToken = beforeAbstractToken?.next;
Token begin = abstractToken ?? token;
Token classKeyword = token;
- expect("class", token);
+ assert(optional('class', token));
Token name =
ensureIdentifier(token, IdentifierContext.classOrNamedMixinDeclaration);
- token = parseTypeVariablesOpt(name);
+ token = computeTypeParam(name).parseVariables(name, this);
if (optional('=', token.next)) {
listener.beginNamedMixinApplication(begin, abstractToken, name);
return parseNamedMixinApplication(token, begin, classKeyword);
@@ -1665,7 +1673,7 @@
Token token, Token begin, Token classKeyword) {
Token equals = token = token.next;
assert(optional('=', equals));
- token = parseType(token);
+ token = computeType(token, true).ensureTypeNotVoid(token, this);
token = parseMixinApplicationRest(token);
Token implementsKeyword = null;
if (optional('implements', token.next)) {
@@ -1753,7 +1761,8 @@
TokenType.IDENTIFIER, 'Object', next.offset, 0);
rewriter.insertTokenAfter(token, extendsKeyword);
rewriter.insertTokenAfter(extendsKeyword, superclassToken);
- token = parseType(extendsKeyword);
+ token = computeType(extendsKeyword, true)
+ .ensureTypeNotVoid(extendsKeyword, this);
token = parseMixinApplicationRest(token);
listener.handleClassExtends(extendsKeyword);
} else {
@@ -1817,7 +1826,7 @@
Token next = token.next;
if (optional('extends', next)) {
Token extendsKeyword = next;
- token = parseType(next);
+ token = computeType(next, true).ensureTypeNotVoid(next, this);
if (optional('with', token.next)) {
token = parseMixinApplicationRest(token);
} else {
@@ -1842,7 +1851,8 @@
if (optional('implements', token.next)) {
implementsKeyword = token.next;
do {
- token = parseType(token.next);
+ token =
+ computeType(token.next, true).ensureTypeNotVoid(token.next, this);
++interfacesCount;
} while (optional(',', token.next));
}
@@ -2012,13 +2022,6 @@
followingValues = ['.', ';'];
} else if (context == IdentifierContext.localAccessorDeclaration) {
followingValues = ['(', '{', '=>'];
- } else if (context == IdentifierContext.localFunctionDeclaration ||
- context == IdentifierContext.localFunctionDeclarationContinuation) {
- followingValues = ['.', '(', '{', '=>'];
- } else if (context == IdentifierContext.topLevelFunctionDeclaration) {
- followingValues = ['(', '{', '=>'];
- } else if (context == IdentifierContext.typeVariableDeclaration) {
- followingValues = ['<', '>', ';', '}'];
} else {
return false;
}
@@ -2080,17 +2083,9 @@
initialKeywords = statementKeywords();
} else if (context == IdentifierContext.localAccessorDeclaration) {
initialKeywords = statementKeywords();
- } else if (context == IdentifierContext.localFunctionDeclaration) {
- initialKeywords = statementKeywords();
} else if (context ==
IdentifierContext.localFunctionDeclarationContinuation) {
initialKeywords = statementKeywords();
- } else if (context == IdentifierContext.topLevelFunctionDeclaration) {
- initialKeywords = topLevelKeywords();
- } else if (context == IdentifierContext.typeVariableDeclaration) {
- initialKeywords = topLevelKeywords()
- ..addAll(classMemberKeywords())
- ..addAll(statementKeywords());
} else {
return false;
}
@@ -2370,12 +2365,6 @@
hasVar = true;
continue optional;
- case TypeContinuation.Typedef:
- if (optional('=', token)) {
- return null; // This isn't a type, it's a new-style typedef.
- }
- continue optional;
-
case TypeContinuation.SendOrFunctionLiteral:
Token beforeName;
Token name;
@@ -2693,7 +2682,7 @@
Token token;
bool isGetter = false;
if (getOrSet == null) {
- token = parseTypeVariablesOpt(name);
+ token = computeTypeParam(name).parseVariables(name, this);
} else {
isGetter = optional("get", getOrSet);
token = name;
@@ -4444,20 +4433,36 @@
return token;
}
- Token parseParenthesizedExpression(Token token) {
- Token previousToken = token;
- token = token.next;
- if (!optional('(', token)) {
+ Token parseParenthesizedCondition(Token token) {
+ if (!optional('(', token.next)) {
// Recover
+ Token next = token.next;
reportRecoverableError(
- token, fasta.templateExpectedToken.withArguments('('));
+ next, fasta.templateExpectedToken.withArguments('('));
+ // TODO(danrubel): Consider removing the 2nd error message.
reportRecoverableError(
- token, fasta.templateExpectedToken.withArguments(')'));
+ next, fasta.templateExpectedToken.withArguments(')'));
BeginToken replacement = link(
- new SyntheticBeginToken(TokenType.OPEN_PAREN, token.charOffset),
- new SyntheticToken(TokenType.CLOSE_PAREN, token.charOffset));
- token = rewriter.insertTokenAfter(previousToken, replacement).next;
+ new SyntheticBeginToken(TokenType.OPEN_PAREN, next.charOffset),
+ new SyntheticToken(TokenType.CLOSE_PAREN, next.charOffset));
+ rewriter.insertTokenAfter(token, replacement).next;
}
+ Token begin = token.next;
+ token = parseExpressionInParenthesis(token);
+ listener.handleParenthesizedCondition(begin);
+ return token;
+ }
+
+ Token parseParenthesizedExpression(Token token) {
+ Token begin = token.next;
+ token = parseExpressionInParenthesis(token);
+ listener.handleParenthesizedExpression(begin);
+ return token;
+ }
+
+ Token parseExpressionInParenthesis(Token token) {
+ token = token.next;
+ assert(optional('(', token));
BeginToken begin = token;
token = parseExpression(token).next;
if (!identical(begin.endGroup, token)) {
@@ -4465,8 +4470,7 @@
token, fasta.templateExpectedButGot.withArguments(')'));
token = begin.endGroup;
}
- listener.handleParenthesizedExpression(begin);
- expect(')', token);
+ assert(optional(')', token));
return token;
}
@@ -5274,7 +5278,7 @@
Token ifToken = token.next;
assert(optional('if', ifToken));
listener.beginIfStatement(ifToken);
- token = parseParenthesizedExpression(ifToken);
+ token = parseParenthesizedCondition(ifToken);
listener.beginThenStatement(token.next);
token = parseStatement(token);
listener.endThenStatement(token);
@@ -5494,7 +5498,7 @@
Token whileToken = token.next;
assert(optional('while', whileToken));
listener.beginWhileStatement(whileToken);
- token = parseParenthesizedExpression(whileToken);
+ token = parseParenthesizedCondition(whileToken);
listener.beginWhileStatementBody(token.next);
LoopState savedLoopState = loopState;
loopState = LoopState.InsideLoop;
@@ -5529,7 +5533,7 @@
new SyntheticKeywordToken(Keyword.WHILE, whileToken.charOffset))
.next;
}
- token = parseParenthesizedExpression(whileToken);
+ token = parseParenthesizedCondition(whileToken);
token = ensureSemicolon(token);
listener.endDoWhileStatement(doToken, whileToken, token);
return token;
@@ -5757,7 +5761,7 @@
Token switchKeyword = token.next;
assert(optional('switch', switchKeyword));
listener.beginSwitchStatement(switchKeyword);
- token = parseParenthesizedExpression(switchKeyword);
+ token = parseParenthesizedCondition(switchKeyword);
LoopState savedLoopState = loopState;
if (loopState == LoopState.OutsideLoop) {
loopState = LoopState.InsideSwitch;
diff --git a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
index d5b8eae..b8ab28e 100644
--- a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
+++ b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
@@ -2,8 +2,16 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:front_end/src/fasta/util/link.dart';
+
import '../../scanner/token.dart'
- show BeginToken, SimpleToken, Token, TokenType;
+ show
+ BeginToken,
+ SimpleToken,
+ SyntheticStringToken,
+ SyntheticToken,
+ Token,
+ TokenType;
import 'util.dart' show optional;
@@ -33,6 +41,61 @@
/// Initialize a newly created re-writer.
TokenStreamRewriter();
+ /// For every `<` in [unbalancedLt] append a synthetic `>`.
+ /// Return the first `<`.
+ ///
+ /// [unbalancedLt] is a collection of `<` without closing `>` in the reverse
+ /// order from which they were encountered in the token stream.
+ Token balanceLt(final Token beforeLt, Token end, Link<Token> unbalancedLt) {
+ assert(optional('<', beforeLt.next));
+ assert(unbalancedLt.isNotEmpty);
+
+ BeginToken lt;
+ while (unbalancedLt.isNotEmpty) {
+ lt = unbalancedLt.head;
+ unbalancedLt = unbalancedLt.tail;
+ Token next = end.next;
+ Token gt;
+
+ if (optional('>', next)) {
+ gt = next;
+ } else if (optional('>>', next)) {
+ gt = new SimpleToken(TokenType.GT, next.charOffset)
+ ..setNext(new SimpleToken(TokenType.GT, next.charOffset + 1)
+ ..setNext(next.next));
+ } else if (optional('>=', next)) {
+ gt = new SimpleToken(TokenType.GT, next.charOffset)
+ ..setNext(new SimpleToken(TokenType.EQ, next.charOffset + 1)
+ ..setNext(next.next));
+ } else if (optional('>>=', next)) {
+ gt = new SimpleToken(TokenType.GT, next.charOffset)
+ ..setNext(new SimpleToken(TokenType.GT, next.charOffset + 1)
+ ..setNext(new SimpleToken(TokenType.EQ, next.charOffset + 2)
+ ..setNext(next.next)));
+ } else {
+ gt = new SyntheticToken(TokenType.GT, next.charOffset)..setNext(next);
+ }
+
+ lt.endGroup = gt;
+ end.setNext(gt);
+ end = gt;
+ }
+ assert(beforeLt.next == lt);
+ return lt;
+ }
+
+ /// Insert a synthetic identifier after [token] and return the new identifier.
+ Token insertSyntheticIdentifier(Token token) {
+ Token identifier = new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', token.next.charOffset, 0)
+ ..setNext(token.next);
+
+ // A no-op rewriter could simply return the synthetic identifier here.
+
+ token.setNext(identifier);
+ return identifier;
+ }
+
/// Insert the chain of tokens starting at the [insertedToken] immediately
/// after the [previousToken]. Return the [previousToken].
Token insertTokenAfter(Token previousToken, Token insertedToken) {
diff --git a/pkg/front_end/lib/src/fasta/parser/type_continuation.dart b/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
index a8aafd2..1f317ab 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
@@ -25,10 +25,6 @@
/// Same as [Optional], but we have seen `var`.
OptionalAfterVar,
- /// Indicates that the keyword `typedef` has just been seen, and the parser
- /// should parse the following as a type unless it is followed by `=`.
- Typedef,
-
/// Indicates that the parser is parsing an expression and has just seen an
/// identifier.
SendOrFunctionLiteral,
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index b70a1e2..47f587f 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -4,7 +4,7 @@
library fasta.parser.type_info;
-import '../../scanner/token.dart' show SyntheticStringToken, Token, TokenType;
+import '../../scanner/token.dart' show Token, TokenType;
import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN, KEYWORD_TOKEN;
@@ -65,6 +65,13 @@
/// when parsing `>>` in valid code or during recovery.
Token parseArguments(Token token, Parser parser);
+ /// Call this function to parse optional type parameters
+ /// (also known as type variables) after [token].
+ /// This function will call the appropriate event methods on the [Parser]'s
+ /// listener to handle the parameters. This may modify the token stream
+ /// when parsing `>>` in valid code or during recovery.
+ Token parseVariables(Token token, Parser parser);
+
/// Call this function with the [token] before the type var to obtain
/// the last token in the type var. If there is no type var, then this method
/// will return [token]. This does not modify the token stream.
@@ -101,13 +108,6 @@
/// `<` identifier `>`.
const TypeParamOrArgInfo simpleTypeArgument1 = const SimpleTypeArgument1();
-Token insertSyntheticIdentifierAfter(Token token, Parser parser) {
- Token identifier = new SyntheticStringToken(
- TokenType.IDENTIFIER, '', token.next.charOffset, 0);
- parser.rewriter.insertTokenAfter(token, identifier);
- return identifier;
-}
-
bool isGeneralizedFunctionType(Token token) {
return optional('Function', token) &&
(optional('<', token.next) || optional('(', token.next));
@@ -255,6 +255,29 @@
}
/// Called by the parser to obtain information about a possible group of type
+/// parameters that follow [token] in a top level or class member declaration.
+/// It assumes that a leading `<` cannot be part of an expression, and thus
+/// tries to more aggressively recover given an unmatched '<'
+TypeParamOrArgInfo computeTypeParam(Token token) {
+ if (!optional('<', token.next)) {
+ return noTypeParamOrArg;
+ }
+ TypeParamOrArgInfo typeParam = computeTypeParamOrArgImpl(token);
+ if (typeParam != noTypeParamOrArg) {
+ return typeParam;
+ }
+
+ // Recovery
+ if (token.next.endGroup == null) {
+ // Attempt to find where the missing `>` should be inserted.
+ return new ComplexTypeParamOrArgInfo(token).computeRecovery();
+ } else {
+ // The `<` `>` are balanced but there's still a problem.
+ return noTypeParamOrArg;
+ }
+}
+
+/// Called by the parser to obtain information about a possible group of type
/// parameters or type arguments that follow [token].
/// This does not modify the token stream.
///
@@ -262,18 +285,23 @@
/// with `>>`, then then [innerEndGroup] is set to either `>>` if the token
/// has not been split or the first `>` if the `>>` token has been split.
TypeParamOrArgInfo computeTypeParamOrArg(Token token, [Token innerEndGroup]) {
+ return optional('<', token.next)
+ ? computeTypeParamOrArgImpl(token, innerEndGroup)
+ : noTypeParamOrArg;
+}
+
+TypeParamOrArgInfo computeTypeParamOrArgImpl(Token token,
+ [Token innerEndGroup]) {
Token next = token.next;
- if (!optional('<', next)) {
- return noTypeParamOrArg;
- }
+ assert(optional('<', next));
Token endGroup = next.endGroup ?? innerEndGroup;
if (endGroup == null) {
return noTypeParamOrArg;
}
Token identifier = next.next;
- // identifier `<` `void` `>` is handled by ComplexTypeInfo.
- if (isValidTypeReference(identifier) &&
- !optional('void', identifier) &&
+ // identifier `<` `void` `>` and `<` `dynamic` `>`
+ // are handled by ComplexTypeInfo.
+ if ((identifier.kind == IDENTIFIER_TOKEN || identifier.type.isPseudo) &&
identifier.next == endGroup) {
return simpleTypeArgument1;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 376d485..a18b898 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -22,7 +22,7 @@
import 'type_info.dart';
-import 'util.dart' show optional, skipMetadata;
+import 'util.dart' show isOneOf, optional, skipMetadata;
/// See documentation on the [noType] const.
class NoType implements TypeInfo {
@@ -35,7 +35,7 @@
Token ensureTypeNotVoid(Token token, Parser parser) {
parser.reportRecoverableErrorWithToken(
token.next, fasta.templateExpectedType);
- insertSyntheticIdentifierAfter(token, parser);
+ parser.rewriter.insertSyntheticIdentifier(token);
return simpleType.parseType(token, parser);
}
@@ -502,6 +502,12 @@
}
@override
+ Token parseVariables(Token token, Parser parser) {
+ parser.listener.handleNoTypeVariables(token.next);
+ return token;
+ }
+
+ @override
Token skip(Token token) => token;
}
@@ -515,23 +521,27 @@
Listener listener = parser.listener;
listener.beginTypeArguments(token);
token = simpleType.parseType(token, parser);
- Token next = token.next;
+ token = processEndGroup(token, start, parser);
+ parser.listener.endTypeArguments(1, start, token);
+ return token;
+ }
- if (next == start.endGroup) {
- parser.listener.endTypeArguments(1, start, next);
- return next;
- } else if (optional('>', next)) {
- // When `>>` is split, the inner group's endGroup updated here.
- start.endGroup = next;
- parser.listener.endTypeArguments(1, start, next);
- return next;
- } else if (optional('>>', next)) {
- parser.listener.endTypeArguments(1, start, next);
- // In this case, the last consumed token is the token before `>>`.
- return token;
- } else {
- throw "Internal error: Expected '>' or '>>' but found '$next'.";
- }
+ @override
+ Token parseVariables(Token token, Parser parser) {
+ BeginToken start = token = token.next;
+ assert(optional('<', token));
+ Listener listener = parser.listener;
+ listener.beginTypeVariables(token);
+ token = token.next;
+ listener.beginTypeVariable(token);
+ listener.beginMetadataStar(token);
+ listener.endMetadataStar(0);
+ listener.handleIdentifier(token, IdentifierContext.typeVariableDeclaration);
+ listener.handleNoType(token);
+ token = processEndGroup(token, start, parser);
+ listener.endTypeVariable(token, null);
+ listener.endTypeVariables(1, start, token);
+ return token;
}
@override
@@ -553,6 +563,10 @@
/// `>>` for the outer group and the token before `>>` for the inner group.
Token end;
+ /// A collection of `<` without closing `>` in the reverse order from which
+ /// they were encountered in the token stream.
+ Link<Token> unbalancedLt = const Link<Token>();
+
ComplexTypeParamOrArgInfo(Token token)
: assert(optional('<', token.next)),
start = token.next;
@@ -575,7 +589,6 @@
do {
TypeInfo typeInfo = computeType(next, true, innerEndGroup);
if (typeInfo == noType) {
- // Recovery
while (typeInfo == noType && optional('@', next.next)) {
next = skipMetadata(next);
typeInfo = computeType(next, true, innerEndGroup);
@@ -590,6 +603,10 @@
}
token = typeInfo.skipType(next);
next = token.next;
+ if (optional('extends', next) || optional('super', next)) {
+ token = computeType(next, true, innerEndGroup).skipType(next);
+ next = token.next;
+ }
} while (optional(',', next));
if (next == start.endGroup) {
@@ -605,17 +622,60 @@
return this;
}
- @override
- Token parseArguments(Token token, Parser parser) {
- assert(identical(start, token.next));
-
- Token innerEndGroup;
- if (start.endGroup != null && optional('>>', start.endGroup)) {
- innerEndGroup = parser.rewriter.splitGtGt(start);
+ /// Parse the tokens and return the receiver or [noTypeParamOrArg] if there
+ /// are no type parameters or arguments. This does not modify the token
+ /// stream.
+ ///
+ /// This is called when parsing type parameters in a top level
+ /// or class member declaration. It assumes that a leading `<` cannot be part
+ /// of an expression, and thus tries to more aggressively recover
+ /// given an unmatched '<'.
+ ///
+ TypeParamOrArgInfo computeRecovery() {
+ assert(start.endGroup == null);
+ unbalancedLt = unbalancedLt.prepend(start);
+ Token token = start;
+ Token next = token.next;
+ while (!next.isEof) {
+ if (optional('Function', next)) {
+ next = next.next;
+ if (optional('<', next)) {
+ next = skipTypeVariables(next);
+ if (next == null) {
+ break;
+ }
+ next = next.next;
+ }
+ if (optional('(', next)) {
+ next = next.endGroup;
+ } else {
+ break;
+ }
+ } else if (optional('<', next)) {
+ Token endGroup = skipTypeVariables(next);
+ if (endGroup != null) {
+ next = endGroup;
+ } else {
+ unbalancedLt = unbalancedLt.prepend(next);
+ }
+ } else if (!isValidTypeReference(next) &&
+ !isOneOf(next, const ['.', ',', 'extends', 'super'])) {
+ break;
+ }
+ token = next;
+ next = token.next;
}
- Token next = start;
- parser.listener.beginTypeArguments(start);
+ end = token;
+ return this;
+ }
+
+ @override
+ Token parseArguments(Token token, Parser parser) {
+ Token begin = balanceLt(token, parser);
+ Token next = begin;
+ Token innerEndGroup = processBeginGroup(begin, parser);
+ parser.listener.beginTypeArguments(begin);
int count = 0;
do {
TypeInfo typeInfo = computeType(next, true, innerEndGroup);
@@ -633,28 +693,101 @@
next = token.next;
++count;
} while (optional(',', next));
+ end = processEndGroup(token, begin, parser);
+ parser.listener.endTypeArguments(count, begin, end);
+ return end;
+ }
- if (next == start.endGroup) {
- end = next;
- parser.listener.endTypeArguments(count, start, end);
- return end;
- } else if (optional('>', next)) {
- // When `>>` is split, this method is recursively called
- // and the inner group's endGroup updated here.
- assert(start.endGroup == null);
- end = start.endGroup = next;
- parser.listener.endTypeArguments(count, start, end);
- return end;
- } else if (optional('>>', next)) {
- // In this case, the end or last consumed token is the token before `>>`.
- end = token;
- parser.listener.endTypeArguments(count, start, next);
- return end;
- } else {
- throw "Internal error: Expected '>' or '>>' but found '$next'.";
- }
+ @override
+ Token parseVariables(Token token, Parser parser) {
+ Token begin = balanceLt(token, parser);
+ Token next = begin;
+ Token innerEndGroup = processBeginGroup(begin, parser);
+ parser.listener.beginTypeVariables(begin);
+ int count = 0;
+ do {
+ parser.listener.beginTypeVariable(next.next);
+ token = parser.parseMetadataStar(next);
+ token = parser.ensureIdentifier(
+ token, IdentifierContext.typeVariableDeclaration);
+ Token extendsOrSuper = null;
+ next = token.next;
+ if (optional('extends', next) || optional('super', next)) {
+ extendsOrSuper = next;
+ token = computeType(next, true, innerEndGroup)
+ .ensureTypeOrVoid(next, parser);
+ next = token.next;
+ } else {
+ parser.listener.handleNoType(token);
+ }
+ parser.listener.endTypeVariable(next, extendsOrSuper);
+ ++count;
+ } while (optional(',', next));
+ end = processEndGroup(token, begin, parser);
+ parser.listener.endTypeVariables(count, begin, end);
+ return end;
}
@override
Token skip(Token token) => end;
+
+ /// For every unbalanced `<` append a synthetic `>`. Return the first `<`
+ Token balanceLt(Token token, Parser parser) {
+ assert(identical(start, token.next));
+ if (unbalancedLt.isEmpty) {
+ return start;
+ }
+ Token begin = parser.rewriter.balanceLt(token, end, unbalancedLt);
+ assert(begin.endGroup != null);
+ if (begin.endGroup.isSynthetic) {
+ parser.reportRecoverableError(
+ begin.endGroup.next, fasta.templateExpectedButGot.withArguments('>'));
+ }
+ return begin;
+ }
+}
+
+Token processBeginGroup(BeginToken start, Parser parser) {
+ Token innerEndGroup;
+ if (start.endGroup != null && optional('>>', start.endGroup)) {
+ innerEndGroup = parser.rewriter.splitGtGt(start);
+ }
+ return innerEndGroup;
+}
+
+Token processEndGroup(Token token, BeginToken start, Parser parser) {
+ Token next = token.next;
+ if (next == start.endGroup) {
+ return next;
+ } else if (optional('>', next)) {
+ // When `>>` is split, the inner group's endGroup updated here.
+ assert(start.endGroup == null);
+ start.endGroup = next;
+ return next;
+ } else if (optional('>>', next)) {
+ // In this case, the last consumed token is the token before `>>`.
+ return token;
+ } else {
+ // Recovery
+ parser.reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
+ if (start.endGroup != null) {
+ return start.endGroup;
+ }
+ while (true) {
+ if (optional('>', next)) {
+ start.endGroup = next;
+ return next;
+ }
+ if (optional('>>', next)) {
+ // In this case, the last consumed token is the token before `>>`.
+ return token;
+ }
+ if (next.isEof) {
+ // Sanity check.
+ return next;
+ }
+ token = next;
+ next = token.next;
+ }
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/parser/util.dart b/pkg/front_end/lib/src/fasta/parser/util.dart
index 7eb1f46..bbbd361 100644
--- a/pkg/front_end/lib/src/fasta/parser/util.dart
+++ b/pkg/front_end/lib/src/fasta/parser/util.dart
@@ -39,6 +39,26 @@
return token == null ? TreeNode.noOffset : token.offset;
}
+/// Return true if the given token matches one of the given values.
+bool isOneOf(Token token, Iterable<String> values) {
+ for (String tokenValue in values) {
+ if (optional(tokenValue, token)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/// Return true if the given token matches one of the given values or is EOF.
+bool isOneOfOrEof(Token token, Iterable<String> values) {
+ for (String tokenValue in values) {
+ if (optional(tokenValue, token)) {
+ return true;
+ }
+ }
+ return token.isEof;
+}
+
/// A null-aware alternative to `token.length`. If [token] is `null`, returns
/// [noLength].
int lengthForToken(Token token) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 5419f26..5b02dc9 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -20,7 +20,8 @@
ProcedureKind,
Supertype;
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/class_hierarchy.dart'
+ show ClassHierarchy, HandleAmbiguousSupertypes;
import 'package:kernel/core_types.dart' show CoreTypes;
@@ -395,16 +396,16 @@
ticker.logMs("Resolved $count type-variable bounds");
}
- void instantiateToBound(TypeBuilder dynamicType, TypeBuilder bottomType,
+ void computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder bottomType,
ClassBuilder objectClass) {
int count = 0;
builders.forEach((Uri uri, LibraryBuilder library) {
if (library.loader == this) {
count +=
- library.instantiateToBound(dynamicType, bottomType, objectClass);
+ library.computeDefaultTypes(dynamicType, bottomType, objectClass);
}
});
- ticker.logMs("Instantiated $count type variables to their bounds");
+ ticker.logMs("Computed default types for $count type variables");
}
void finishNativeMethods() {
@@ -619,17 +620,38 @@
return new Component()..libraries.addAll(libraries);
}
+ List<Class> computeListOfLoaderClasses() {
+ List<Class> result = <Class>[];
+ builders.forEach((Uri uri, LibraryBuilder libraryBuilder) {
+ if (!libraryBuilder.isPart &&
+ !libraryBuilder.isPatch &&
+ (libraryBuilder.loader == this)) {
+ Library library = libraryBuilder.target;
+ result.addAll(library.classes);
+ }
+ });
+ return result;
+ }
+
void computeHierarchy() {
List<List> ambiguousTypesRecords = [];
- hierarchy = new ClassHierarchy(computeFullComponent(),
- onAmbiguousSupertypes: (Class cls, Supertype a, Supertype b) {
+ HandleAmbiguousSupertypes onAmbiguousSupertypes =
+ (Class cls, Supertype a, Supertype b) {
if (ambiguousTypesRecords != null) {
ambiguousTypesRecords.add([cls, a, b]);
}
- },
- mixinInferrer: target.strongMode
- ? new StrongModeMixinInferrer(this)
- : new LegacyModeMixinInferrer());
+ };
+ if (hierarchy == null) {
+ hierarchy = new ClassHierarchy(computeFullComponent(),
+ onAmbiguousSupertypes: onAmbiguousSupertypes,
+ mixinInferrer: target.strongMode
+ ? new StrongModeMixinInferrer(this)
+ : new LegacyModeMixinInferrer());
+ } else {
+ hierarchy.onAmbiguousSupertypes = onAmbiguousSupertypes;
+ hierarchy.applyTreeChanges(const [], computeListOfLoaderClasses(),
+ reissueAmbiguousSupertypesFor: computeFullComponent());
+ }
for (List record in ambiguousTypesRecords) {
handleAmbiguousSupertypes(record[0], record[1], record[2]);
}
@@ -687,7 +709,7 @@
for (SourceClassBuilder builder in sourceClasses) {
if (builder.library.loader == this) {
- builder.addNoSuchMethodForwarders(hierarchy);
+ builder.addNoSuchMethodForwarders(target, hierarchy);
}
}
ticker.logMs("Added noSuchMethod forwarders");
@@ -736,11 +758,27 @@
/// assign their types.
void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
typeInferenceEngine.finishTopLevelFields();
+ List<Class> changedClasses = new List<Class>();
for (var builder in orderedClasses) {
ShadowClass class_ = builder.target;
+ int memberCount = class_.fields.length +
+ class_.constructors.length +
+ class_.procedures.length +
+ class_.redirectingFactoryConstructors.length;
class_.finalizeCovariance(interfaceResolver);
ShadowClass.clearClassInferenceInfo(class_);
+ int newMemberCount = class_.fields.length +
+ class_.constructors.length +
+ class_.procedures.length +
+ class_.redirectingFactoryConstructors.length;
+ if (newMemberCount != memberCount) {
+ // The inference potentially adds new members (but doesn't otherwise
+ // change the classes), so if the member count has changed we need to
+ // update the class in the class hierarchy.
+ changedClasses.add(class_);
+ }
}
+
orderedClasses = null;
typeInferenceEngine.finishTopLevelInitializingFormals();
if (instrumentation != null) {
@@ -754,11 +792,8 @@
// Since finalization of covariance may have added forwarding stubs, we need
// to recompute the class hierarchy so that method compilation will properly
// target those forwarding stubs.
- // TODO(paulberry): could we make this unnecessary by not clearing class
- // inference info?
- typeInferenceEngine.classHierarchy = hierarchy = new ClassHierarchy(
- computeFullComponent(),
- onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
+ hierarchy.onAmbiguousSupertypes = ignoreAmbiguousSupertypes;
+ hierarchy.applyMemberChanges(changedClasses, findDescendants: true);
ticker.logMs("Performed top level inference");
}
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener.dart b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
index 938ad81..f312680 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -277,6 +277,11 @@
}
@override
+ void handleParenthesizedCondition(Token token) {
+ debugEvent("handleParenthesizedCondition");
+ }
+
+ @override
void handleParenthesizedExpression(Token token) {
debugEvent("ParenthesizedExpression");
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index 06f8279..0333163 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -13,22 +13,10 @@
import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/text/ast_to_text.dart';
import 'package:kernel/transformations/flags.dart' show TransformerFlag;
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
-/// Set this flag to `true` to cause debugging information about covariance
-/// checks to be printed to standard output.
-const bool debugCovariance = false;
-
-/// Type of a closure which applies a covariance annotation to a class member.
-///
-/// This is necessary since we need to determine which covariance annotations
-/// need to be added before creating a forwarding stub, but the covariance
-/// annotations themselves need to be applied to the forwarding stub.
-typedef void _CovarianceFix(FunctionNode function);
-
/// Concrete class derived from [InferenceNode] to represent type inference of
/// getters, setters, and fields based on inheritance.
class AccessorInferenceNode extends InferenceNode {
@@ -192,41 +180,59 @@
/// Does not create forwarding stubs.
Procedure resolve() => _resolution ??= _resolve();
- /// Determines which covariance fixes need to be applied to the given
- /// [interfaceMember].
+ /// Tag the parameters of [interfaceMember] that need type checks
///
- /// [substitution] indicates the necessary substitutions to convert types
- /// named in [interfaceMember] to types in the target class.
+ /// Parameters can need type checks for calls coming from statically typed
+ /// call sites, due to covariant generics and overrides with explicit
+ /// `covariant` parameters.
///
- /// The fixes are not applied immediately (since [interfaceMember] might be
- /// a member of another class, and a forwarding stub may need to be
- /// generated).
- void _computeCovarianceFixes(Substitution substitution,
- Procedure interfaceMember, List<_CovarianceFix> fixes) {
- if (debugCovariance) {
- print('Considering covariance fixes for '
- '${_printProcedure(interfaceMember, enclosingClass)}');
- for (int i = _start; i < _end; i++) {
- print(' Candidate: ${_printProcedure(_candidates[i])}');
- }
- }
- var class_ = enclosingClass;
+ /// Tag parameters of [interfaceMember] that need such checks when the member
+ /// occurs in [enclosingClass]'s interface. If parameters need checks but
+ /// they would not be checked in an inherited implementation, a forwarding
+ /// stub is introduced as a place to put the checks.
+ Procedure _computeCovarianceFixes(Procedure interfaceMember) {
+ assert(_interfaceResolver.strongMode);
+ var substitution =
+ _interfaceResolver._substitutionFor(interfaceMember, enclosingClass);
+ // We always create a forwarding stub when we've inherited a member from an
+ // interface other than the first override candidate. This is to work
+ // around a bug in the Kernel type checker where it chooses the first
+ // override candidate.
+ //
+ // TODO(kmillikin): Fix the Kernel type checker and stop creating these
+ // extra stubs.
+ var stub = interfaceMember.enclosingClass == enclosingClass ||
+ interfaceMember == _resolvedCandidate(_start)
+ ? interfaceMember
+ : _createForwardingStub(substitution, interfaceMember);
+
var interfaceFunction = interfaceMember.function;
var interfacePositionalParameters = interfaceFunction.positionalParameters;
var interfaceNamedParameters = interfaceFunction.namedParameters;
var interfaceTypeParameters = interfaceFunction.typeParameters;
+
+ void createStubIfNeeded() {
+ if (stub != interfaceMember) return;
+ if (interfaceMember.enclosingClass == enclosingClass) return;
+ stub = _createForwardingStub(substitution, interfaceMember);
+ }
+
bool isImplCreated = false;
void createImplIfNeeded() {
if (isImplCreated) return;
- fixes.add(_createForwardingImplIfNeeded);
+ createStubIfNeeded();
+ _createForwardingImplIfNeeded(stub.function);
isImplCreated = true;
}
IncludesTypeParametersCovariantly needsCheckVisitor =
- class_.typeParameters.isEmpty
+ enclosingClass.typeParameters.isEmpty
? null
- : ShadowClass.getClassInferenceInfo(class_).needsCheckVisitor ??=
- new IncludesTypeParametersCovariantly(class_.typeParameters);
+ : ShadowClass
+ .getClassInferenceInfo(enclosingClass)
+ .needsCheckVisitor ??=
+ new IncludesTypeParametersCovariantly(
+ enclosingClass.typeParameters);
bool needsCheck(DartType type) => needsCheckVisitor == null
? false
: substitution.substituteType(type).accept(needsCheckVisitor);
@@ -252,19 +258,23 @@
isCovariant = true;
}
}
- if (isGenericCovariantImpl != superParameter.isGenericCovariantImpl) {
- createImplIfNeeded();
+ if (isGenericCovariantImpl) {
+ if (!superParameter.isGenericCovariantImpl) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isGenericCovariantImpl) {
+ createStubIfNeeded();
+ stub.function.positionalParameters[i].isGenericCovariantImpl = true;
+ }
}
- if (isGenericCovariantImpl != parameter.isGenericCovariantImpl) {
- fixes.add((FunctionNode function) => function.positionalParameters[i]
- .isGenericCovariantImpl = isGenericCovariantImpl);
- }
- if (isCovariant != superParameter.isCovariant) {
- createImplIfNeeded();
- }
- if (isCovariant != parameter.isCovariant) {
- fixes.add((FunctionNode function) =>
- function.positionalParameters[i].isCovariant = isCovariant);
+ if (isCovariant) {
+ if (!superParameter.isCovariant) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isCovariant) {
+ createStubIfNeeded();
+ stub.function.positionalParameters[i].isCovariant = true;
+ }
}
}
for (int i = 0; i < interfaceNamedParameters.length; i++) {
@@ -288,19 +298,23 @@
isCovariant = true;
}
}
- if (isGenericCovariantImpl != superParameter.isGenericCovariantImpl) {
- createImplIfNeeded();
+ if (isGenericCovariantImpl) {
+ if (!superParameter.isGenericCovariantImpl) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isGenericCovariantImpl) {
+ createStubIfNeeded();
+ stub.function.namedParameters[i].isGenericCovariantImpl = true;
+ }
}
- if (isGenericCovariantImpl != parameter.isGenericCovariantImpl) {
- fixes.add((FunctionNode function) => function.namedParameters[i]
- .isGenericCovariantImpl = isGenericCovariantImpl);
- }
- if (isCovariant != superParameter.isCovariant) {
- createImplIfNeeded();
- }
- if (isCovariant != parameter.isCovariant) {
- fixes.add((FunctionNode function) =>
- function.namedParameters[i].isCovariant = isCovariant);
+ if (isCovariant) {
+ if (!superParameter.isCovariant) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isCovariant) {
+ createStubIfNeeded();
+ stub.function.namedParameters[i].isCovariant = true;
+ }
}
}
for (int i = 0; i < interfaceTypeParameters.length; i++) {
@@ -320,18 +334,17 @@
isGenericCovariantImpl = true;
}
}
- if (isGenericCovariantImpl != superTypeParameter.isGenericCovariantImpl) {
- createImplIfNeeded();
- }
- if (isGenericCovariantImpl != typeParameter.isGenericCovariantImpl) {
- fixes.add((FunctionNode function) => function
- .typeParameters[i].isGenericCovariantImpl = isGenericCovariantImpl);
+ if (isGenericCovariantImpl) {
+ if (!superTypeParameter.isGenericCovariantImpl) {
+ createImplIfNeeded();
+ }
+ if (!typeParameter.isGenericCovariantImpl) {
+ createStubIfNeeded();
+ stub.function.typeParameters[i].isGenericCovariantImpl = true;
+ }
}
}
-
- if (debugCovariance && fixes.isNotEmpty) {
- print(' ${fixes.length} fix(es)');
- }
+ return stub;
}
void _createForwardingImplIfNeeded(FunctionNode function) {
@@ -467,28 +480,9 @@
/// Creates a forwarding stub for this node if necessary, and propagates
/// covariance information.
Procedure _finalize() {
- var member = resolve();
- var substitution =
- _interfaceResolver._substitutionFor(member, enclosingClass);
- bool isDeclaredInThisClass =
- identical(member.enclosingClass, enclosingClass);
-
- // Now decide whether we need a forwarding stub or not, and propagate
- // covariance.
- var covarianceFixes = <_CovarianceFix>[];
- if (_interfaceResolver.strongMode) {
- _computeCovarianceFixes(substitution, member, covarianceFixes);
- }
- if (!isDeclaredInThisClass &&
- (!identical(member, _resolvedCandidate(_start)) ||
- covarianceFixes.isNotEmpty)) {
- member = _createForwardingStub(substitution, member);
- }
- var function = member.function;
- for (var fix in covarianceFixes) {
- fix(function);
- }
- return member;
+ return _interfaceResolver.strongMode
+ ? _computeCovarianceFixes(resolve())
+ : resolve();
}
/// Returns the [i]th element of [_candidates], finalizing it if necessary.
@@ -500,29 +494,6 @@
: candidate;
}
- /// Returns a string describing the signature of [procedure], along with the
- /// class it's in.
- ///
- /// Only used if [debugCovariance] is `true`.
- ///
- /// If [class_] is provided, it is used instead of [procedure]'s enclosing
- /// class.
- String _printProcedure(Procedure procedure, [Class class_]) {
- class_ ??= procedure.enclosingClass;
- var buffer = new StringBuffer();
- if (procedure.function == null) {
- buffer.write(procedure.toString());
- } else {
- procedure.accept(new Printer(buffer));
- }
- var text = buffer.toString();
- var newlineIndex = text.indexOf('\n');
- if (newlineIndex != -1) {
- text = text.substring(0, newlineIndex);
- }
- return '$class_: $text';
- }
-
/// Determines which inherited member this node resolves to, and also performs
/// type inference.
Procedure _resolve() {
@@ -797,7 +768,6 @@
int getterIndex = 0;
int setterIndex = 0;
forEachApiMember(candidates, (int start, int end, Name name) {
- // TODO(paulberry): check for illegal getter/method mixing
Procedure member = candidates[start];
ProcedureKind kind = _kindOf(member);
if (kind != ProcedureKind.Getter && kind != ProcedureKind.Setter) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 719ca60..eaa54e0 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -62,10 +62,8 @@
import '../fasta_codes.dart';
-import '../kernel/fasta_accessors.dart'
- show BuilderHelper, CalleeDesignation, FunctionTypeAccessor;
-
-import '../kernel/frontend_accessors.dart' show buildIsNull;
+import '../kernel/expression_generator.dart'
+ show BuilderHelper, CalleeDesignation, FunctionTypeAccessor, buildIsNull;
import '../kernel/kernel_shadow_ast.dart'
show
@@ -496,7 +494,7 @@
var parent = expression.parent;
var t = new VariableDeclaration.forValue(expression, type: actualType)
..fileOffset = fileOffset;
- var nullCheck = buildIsNull(new VariableGet(t), fileOffset);
+ var nullCheck = buildIsNull(new VariableGet(t), fileOffset, helper);
var tearOff =
new PropertyGet(new VariableGet(t), callName, callMember)
..fileOffset = fileOffset;
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index 530b6f0..7842a42 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -216,12 +216,17 @@
static const Keyword IN = const Keyword("in", "IN");
+ static const Keyword INTERFACE =
+ const Keyword("interface", "INTERFACE", isBuiltIn: true);
+
static const Keyword IS =
const Keyword("is", "IS", precedence: RELATIONAL_PRECEDENCE);
static const Keyword LIBRARY = const Keyword("library", "LIBRARY",
isBuiltIn: true, isTopLevelKeyword: true);
+ static const Keyword MIXIN = const Keyword("mixin", "MIXIN", isBuiltIn: true);
+
static const Keyword NATIVE =
const Keyword("native", "NATIVE", isPseudo: true);
@@ -316,8 +321,10 @@
IMPLEMENTS,
IMPORT,
IN,
+ INTERFACE,
IS,
LIBRARY,
+ MIXIN,
NATIVE,
NEW,
NULL,
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 692b8d5..d6a7570 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -1,6 +1,7 @@
# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE.md file.
+
AbstractClassInstantiation/analyzerCode: Fail
AbstractClassInstantiation/example: Fail
AbstractClassMember/script5: Fail
@@ -61,6 +62,26 @@
ConstAndVar/script1: Fail
ConstConstructorNonFinalField/analyzerCode: Fail
ConstConstructorNonFinalField/example: Fail
+ConstEvalContext/analyzerCode: Fail # This is just used for displaying the context.
+ConstEvalContext/example: Fail # This is just used for displaying the context.
+ConstEvalDuplicateKey/dart2jsCode: Fail
+ConstEvalDuplicateKey/example: Fail
+ConstEvalFailedAssertion/dart2jsCode: Fail
+ConstEvalFailedAssertion/example: Fail
+ConstEvalFailedAssertionWithMessage/dart2jsCode: Fail
+ConstEvalFailedAssertionWithMessage/example: Fail
+ConstEvalInvalidBinaryOperandType/analyzerCode: Fail # CONST_EVAL_TYPE_NUM / CONST_EVAL_TYPE_BOOL
+ConstEvalInvalidBinaryOperandType/example: Fail
+ConstEvalInvalidMethodInvocation/dart2jsCode: Fail
+ConstEvalInvalidMethodInvocation/example: Fail
+ConstEvalInvalidStaticInvocation/dart2jsCode: Fail
+ConstEvalInvalidStaticInvocation/example: Fail
+ConstEvalInvalidStringInterpolationOperand/dart2jsCode: Fail
+ConstEvalInvalidStringInterpolationOperand/example: Fail
+ConstEvalInvalidType/analyzerCode: Fail # CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH / CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH / CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH / ...
+ConstEvalInvalidType/example: Fail
+ConstEvalNonConstantLiteral/dart2jsCode: Fail
+ConstEvalNonConstantLiteral/example: Fail
ConstFieldWithoutInitializer/example: Fail
ConstructorHasNoSuchNamedParameter/analyzerCode: Fail
ConstructorHasNoSuchNamedParameter/example: Fail
@@ -170,6 +191,10 @@
FinalFieldWithoutInitializer/example: Fail
FinalInstanceVariableAlreadyInitialized/analyzerCode: Fail
FinalInstanceVariableAlreadyInitialized/example: Fail
+ForInLoopExactlyOneVariable/analyzerCode: Fail # The analyzer doesn't recover well.
+ForInLoopExactlyOneVariable/statement: Fail # Fasta reports too many errors.
+ForInLoopNotAssignable/analyzerCode: Fail # The analyzer reports a different error.
+ForInLoopNotAssignable/statement: Fail
FunctionHasNoSuchNamedParameter/analyzerCode: Fail
FunctionHasNoSuchNamedParameter/example: Fail
FunctionTypeDefaultValue/example: Fail
@@ -390,7 +415,6 @@
TypeVariableInStaticContext/example: Fail
TypeVariableSameNameAsEnclosing/analyzerCode: Fail
TypeVariableSameNameAsEnclosing/example: Fail
-TypedefNotFunction/analyzerCode: Fail
TypedefNotFunction/example: Fail
UnexpectedDollarInString/analyzerCode: Fail
UnexpectedDollarInString/script1: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index f18ea4d..acbe910 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -77,6 +77,43 @@
analyzerCode: ILLEGAL_CHARACTER
expression: "\x1b 1"
+ConstEvalContext:
+ template: "While analyzing:"
+
+ConstEvalDuplicateKey:
+ template: "The key '#constant' conflicts with another existing key in the map."
+ analyzerCode: EQUAL_KEYS_IN_MAP
+
+ConstEvalNonConstantLiteral:
+ template: "Can't have a non-constant #string literal within a const context."
+ analyzerCode: NON_CONSTANT_DEFAULT_VALUE
+
+ConstEvalInvalidType:
+ template: "Expected constant '#constant' to be of type '#type', but was of type '#type2'."
+
+ConstEvalInvalidBinaryOperandType:
+ template: "Binary operator '#string' on '#constant' requires operand of type '#type', but was of type '#type2'."
+
+ConstEvalInvalidMethodInvocation:
+ template: "The method '#string' can't be invoked on '#constant' within a const context."
+ analyzerCode: UNDEFINED_OPERATOR
+
+ConstEvalInvalidStringInterpolationOperand:
+ template: "The '#constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used."
+ analyzerCode: CONST_EVAL_TYPE_BOOL_NUM_STRING
+
+ConstEvalInvalidStaticInvocation:
+ template: "The invocation of '#name' is not allowed within a const context."
+ analyzerCode: CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+
+ConstEvalFailedAssertion:
+ template: "This assertion failed."
+ analyzerCode: CONST_EVAL_THROWS_EXCEPTION
+
+ConstEvalFailedAssertionWithMessage:
+ template: "This assertion failed with message: #string"
+ analyzerCode: CONST_EVAL_THROWS_EXCEPTION
+
NonAsciiIdentifier:
template: "The non-ASCII character '#character' (#unicode) can't be used in identifiers, only in strings and comments."
tip: "Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)."
@@ -1165,7 +1202,7 @@
Read the SDK platform from <file>, which should be in Dill/Kernel IR format
and contain the Dart SDK.
- --target=none|vm|vmcc|vmreify|flutter
+ --target=dart2js|dart2js_server|dart_runner|flutter|flutter_runner|none|vm
Specify the target configuration.
--verify
@@ -1611,6 +1648,8 @@
TypedefNotFunction:
template: "Can't create typedef from non-function type."
+ analyzerCode: INVALID_GENERIC_FUNCTION_TYPE
+ dart2jsCode: "*fatal*"
LibraryDirectiveNotFirst:
template: "The library directive must appear before all other directives."
@@ -2182,3 +2221,19 @@
ExpectedOneExpression:
template: "Expected one expression, but found additional input."
severity: ERROR
+
+ForInLoopNotAssignable:
+ template: "Can't assign to this, so it can't be used in a for-in loop."
+ severity: ERROR
+ statement: "for (1 in []) {}"
+ script: |
+ import "dart:core" as prefix;
+
+ main() {
+ for (prefix in []) {}
+ }
+
+ForInLoopExactlyOneVariable:
+ template: "A for-in loop can't have more than one loop variable."
+ severity: ERROR
+ statement: "for (var x, y in []) {}"
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 1f9aa73..90c0247 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,22 +1,24 @@
name: front_end
-version: 0.1.0-alpha.12
+# Currently, front_end API is not stable and users should not
+# depend on semver semantics when depending on this package.
+version: 0.1.0
author: Dart Team <misc@dartlang.org>
description: Front end for compilation of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
environment:
- sdk: '>=1.12.0 <2.0.0'
+ sdk: '>=2.0.0-dev.48.0 <2.0.0'
dependencies:
charcode: '^1.1.1'
convert: '^2.0.1'
crypto: '^2.0.2'
- kernel: 0.3.0-alpha.12
+ kernel: 0.3.0
meta: '^1.1.1'
package_config: '^1.0.1'
path: '^1.3.9'
source_span: '^1.2.3'
yaml: '^2.1.12'
dev_dependencies:
- analyzer: '>=0.30.0 <0.32.0'
+ analyzer: '>=0.31.0 <0.33.0'
args: '>=0.13.0 <2.0.0'
dart_style: '^1.0.7'
json_rpc_2: ^2.0.4
diff --git a/pkg/front_end/test/fasta/expression_test.dart b/pkg/front_end/test/fasta/expression_test.dart
index 4a21e78..ee97b9d 100644
--- a/pkg/front_end/test/fasta/expression_test.dart
+++ b/pkg/front_end/test/fasta/expression_test.dart
@@ -325,6 +325,7 @@
test.expression,
definitions,
typeParams,
+ "debugExpr",
test.library,
test.className,
test.isStaticMethod);
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
new file mode 100644
index 0000000..de65fd9
--- /dev/null
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test of toString on generators.
+
+import 'package:expect/expect.dart' show Expect;
+
+import 'package:kernel/ast.dart'
+ show
+ Arguments,
+ Class,
+ DartType,
+ Expression,
+ FunctionNode,
+ Library,
+ Member,
+ Name,
+ Procedure,
+ ProcedureKind,
+ StringLiteral,
+ TypeParameter,
+ VariableDeclaration,
+ VariableGet,
+ VoidType;
+
+import 'package:kernel/target/targets.dart' show NoneTarget, TargetFlags;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
+
+import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
+ show
+ KernelLibraryBuilder,
+ KernelTypeVariableBuilder,
+ LoadLibraryBuilder,
+ PrefixBuilder,
+ TypeDeclarationBuilder;
+
+import 'package:front_end/src/fasta/kernel/kernel_target.dart'
+ show KernelTarget;
+
+import 'package:front_end/src/fasta/fasta_codes.dart'
+ show Message, templateUnspecified;
+
+import 'package:front_end/src/fasta/kernel/expression_generator.dart'
+ show
+ DeferredAccessGenerator,
+ FastaAccessor,
+ IncompleteError,
+ IncompletePropertyAccessor,
+ IndexedAccessGenerator,
+ LargeIntAccessGenerator,
+ LoadLibraryGenerator,
+ NullAwarePropertyAccessGenerator,
+ ParenthesizedExpression,
+ PropertyAccessGenerator,
+ ReadOnlyAccessGenerator,
+ SendAccessor,
+ StaticAccessGenerator,
+ SuperIndexedAccessGenerator,
+ SuperPropertyAccessGenerator,
+ ThisAccessGenerator,
+ ThisIndexedAccessGenerator,
+ ThisPropertyAccessGenerator,
+ TypeDeclarationAccessor,
+ UnresolvedAccessor,
+ VariableUseGenerator;
+
+import 'package:front_end/src/fasta/kernel/body_builder.dart'
+ show DelayedAssignment, DelayedPostfixIncrement;
+
+import 'package:front_end/src/fasta/kernel/kernel_body_builder.dart'
+ show KernelBodyBuilder;
+
+import 'package:front_end/src/fasta/scanner.dart' show Token, scanString;
+
+void check(String expected, FastaAccessor<Arguments> generator) {
+ Expect.stringEquals(expected, "$generator");
+}
+
+main() {
+ CompilerContext.runWithDefaultOptions((CompilerContext c) {
+ Token token = scanString(" myToken").tokens;
+ Uri uri = Uri.parse("org-dartlang-test:my_library.dart");
+
+ Arguments arguments = new Arguments(<Expression>[new StringLiteral("arg")]);
+ DartType type = const VoidType();
+ Expression expression =
+ new VariableGet(new VariableDeclaration("expression"));
+ Expression index = new VariableGet(new VariableDeclaration("index"));
+ KernelLibraryBuilder libraryBuilder = new KernelLibraryBuilder(
+ uri,
+ uri,
+ new KernelTarget(
+ null,
+ false,
+ new DillTarget(null, null, new NoneTarget(new TargetFlags())),
+ null)
+ .loader,
+ null,
+ null);
+ LoadLibraryBuilder loadLibraryBuilder =
+ new LoadLibraryBuilder(libraryBuilder, null, -1);
+ Member getter = new Procedure(
+ new Name("myGetter"), ProcedureKind.Getter, new FunctionNode(null));
+ Member interfaceTarget = new Procedure(new Name("myInterfaceTarget"),
+ ProcedureKind.Method, new FunctionNode(null));
+ Member setter = new Procedure(
+ new Name("mySetter"), ProcedureKind.Setter, new FunctionNode(null));
+ Message message = templateUnspecified.withArguments("My Message.");
+ Name binaryOperator = new Name("+");
+ Name name = new Name("bar");
+ PrefixBuilder prefixBuilder =
+ new PrefixBuilder("myPrefix", false, libraryBuilder, -1);
+ String assignmentOperator = "+=";
+ TypeDeclarationBuilder declaration =
+ new KernelTypeVariableBuilder.fromKernel(
+ new TypeParameter("T"), libraryBuilder);
+ VariableDeclaration variable = new VariableDeclaration(null);
+
+ KernelBodyBuilder helper = new KernelBodyBuilder(
+ libraryBuilder, null, null, null, null, null, null, false, uri, null);
+
+ FastaAccessor accessor =
+ new ThisAccessGenerator<Arguments>(helper, token, false);
+
+ Library library = new Library(uri);
+ Class cls = new Class();
+ library.addClass(cls);
+ library.addProcedure(getter);
+ library.addProcedure(setter);
+ cls.addMember(interfaceTarget);
+
+ check(
+ "DelayedAssignment(offset: 4, value: expression,"
+ " assignmentOperator: +=)",
+ new DelayedAssignment<Arguments>(
+ helper, token, accessor, expression, assignmentOperator));
+ check(
+ "DelayedPostfixIncrement(offset: 4, binaryOperator: +,"
+ " interfaceTarget: $uri::#class1::myInterfaceTarget)",
+ new DelayedPostfixIncrement<Arguments>(
+ helper, token, accessor, binaryOperator, interfaceTarget));
+ check(
+ "VariableUseGenerator(offset: 4, variable: dynamic #t1;\n,"
+ " promotedType: void)",
+ new VariableUseGenerator<Arguments>(helper, token, variable, type));
+ check(
+ "PropertyAccessGenerator(offset: 4, _receiverVariable: null,"
+ " receiver: expression, name: bar, getter: $uri::myGetter,"
+ " setter: $uri::mySetter)",
+ new PropertyAccessGenerator<Arguments>.internal(
+ helper, token, expression, name, getter, setter));
+ check(
+ "ThisPropertyAccessGenerator(offset: 4, name: bar,"
+ " getter: $uri::myGetter, setter: $uri::mySetter)",
+ new ThisPropertyAccessGenerator<Arguments>(
+ helper, token, name, getter, setter));
+ check(
+ "NullAwarePropertyAccessGenerator(offset: 4,"
+ " receiver: final dynamic #t1 = expression;\n,"
+ " receiverExpression: expression, name: bar, getter: $uri::myGetter,"
+ " setter: $uri::mySetter, type: void)",
+ new NullAwarePropertyAccessGenerator<Arguments>(
+ helper, token, expression, name, getter, setter, type));
+ check(
+ "SuperPropertyAccessGenerator(offset: 4, name: bar,"
+ " getter: $uri::myGetter, setter: $uri::mySetter)",
+ new SuperPropertyAccessGenerator<Arguments>(
+ helper, token, name, getter, setter));
+ check(
+ "IndexedAccessGenerator(offset: 4, receiver: expression, index: index,"
+ " getter: $uri::myGetter, setter: $uri::mySetter,"
+ " receiverVariable: null, indexVariable: null)",
+ new IndexedAccessGenerator<Arguments>.internal(
+ helper, token, expression, index, getter, setter));
+ check(
+ "ThisIndexedAccessGenerator(offset: 4, index: index,"
+ " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
+ new ThisIndexedAccessGenerator<Arguments>(
+ helper, token, index, getter, setter));
+ check(
+ "SuperIndexedAccessGenerator(offset: 4, index: index,"
+ " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
+ new SuperIndexedAccessGenerator<Arguments>(
+ helper, token, index, getter, setter));
+ check(
+ "StaticAccessGenerator(offset: 4, readTarget: $uri::myGetter,"
+ " writeTarget: $uri::mySetter)",
+ new StaticAccessGenerator<Arguments>(helper, token, getter, setter));
+ check(
+ "LoadLibraryGenerator(offset: 4,"
+ " builder: Instance of 'LoadLibraryBuilder')",
+ new LoadLibraryGenerator<Arguments>(helper, token, loadLibraryBuilder));
+ check(
+ "ThisAccessGenerator(offset: 4, isInitializer: false, isSuper: false)",
+ new ThisAccessGenerator<Arguments>(helper, token, false));
+ check("IncompleteError(offset: 4, message: Unspecified)",
+ new IncompleteError<Arguments>(helper, token, message));
+ check("SendAccessor(offset: 4, name: bar, arguments: (\"arg\"))",
+ new SendAccessor<Arguments>(helper, token, name, arguments));
+ check("IncompletePropertyAccessor(offset: 4, name: bar)",
+ new IncompletePropertyAccessor<Arguments>(helper, token, name));
+ check(
+ "DeferredAccessGenerator(offset: 4, "
+ "builder: Instance of 'PrefixBuilder',"
+ " accessor: ThisAccessGenerator(offset: 4, isInitializer: false,"
+ " isSuper: false))",
+ new DeferredAccessGenerator<Arguments>(
+ helper, token, prefixBuilder, accessor));
+ check(
+ "ReadOnlyAccessGenerator(offset: 4, expression: expression,"
+ " plainNameForRead: foo, value: null)",
+ new ReadOnlyAccessGenerator<Arguments>(
+ helper, token, expression, "foo"));
+ check("LargeIntAccessGenerator(offset: 4, lexeme: myToken)",
+ new LargeIntAccessGenerator<Arguments>(helper, token));
+ check(
+ "ParenthesizedExpression(offset: 4, expression: expression,"
+ " plainNameForRead: null, value: null)",
+ new ParenthesizedExpression<Arguments>(helper, token, expression));
+ check(
+ "TypeDeclarationAccessor(offset: 4, expression: T,"
+ " plainNameForRead: foo, value: null)",
+ new TypeDeclarationAccessor<Arguments>(
+ helper, token, prefixBuilder, -1, declaration, "foo"));
+ check("UnresolvedAccessor(offset: 4, name: bar)",
+ new UnresolvedAccessor<Arguments>(helper, token, name));
+ });
+}
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index c0b27e8..4790175 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -247,7 +247,7 @@
'handleIdentifier T typeReference',
'handleNoTypeArguments >>',
'handleType T >>',
- 'endTypeArguments 1 < >>',
+ 'endTypeArguments 1 < T',
'handleType C >>',
]);
expect(listener.errors, isNull);
@@ -304,16 +304,16 @@
expectedErrors: [error(codeBuiltInIdentifierAsType, 0, 6)]);
expectComplexInfo('abstract Function()',
required: false,
- tokenAfter: 'Function',
+ expectedAfter: 'Function',
expectedErrors: [error(codeBuiltInIdentifierAsType, 0, 8)]);
expectComplexInfo('export Function()',
required: false,
- tokenAfter: 'Function',
+ expectedAfter: 'Function',
expectedErrors: [error(codeBuiltInIdentifierAsType, 0, 6)]);
}
void test_computeType_gft() {
- expectComplexInfo('Function() m', tokenAfter: 'm', expectedCalls: [
+ expectComplexInfo('Function() m', expectedAfter: 'm', expectedCalls: [
'handleNoTypeVariables (',
'beginFunctionType Function',
'handleNoType ',
@@ -321,7 +321,7 @@
'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
'endFunctionType Function m',
]);
- expectComplexInfo('Function<T>() m', tokenAfter: 'm', expectedCalls: [
+ expectComplexInfo('Function<T>() m', expectedAfter: 'm', expectedCalls: [
'beginTypeVariables <',
'beginTypeVariable T',
'beginMetadataStar T',
@@ -336,7 +336,7 @@
'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
'endFunctionType Function m',
]);
- expectComplexInfo('Function(int) m', tokenAfter: 'm', expectedCalls: [
+ expectComplexInfo('Function(int) m', expectedAfter: 'm', expectedCalls: [
'handleNoTypeVariables (',
'beginFunctionType Function',
'handleNoType ',
@@ -354,7 +354,7 @@
'endFormalParameters 1 ( ) MemberKind.GeneralizedFunctionType',
'endFunctionType Function m',
]);
- expectComplexInfo('Function<T>(int) m', tokenAfter: 'm', expectedCalls: [
+ expectComplexInfo('Function<T>(int) m', expectedAfter: 'm', expectedCalls: [
'beginTypeVariables <',
'beginTypeVariable T',
'beginMetadataStar T',
@@ -385,13 +385,13 @@
expectComplexInfo('Function(int x)', required: true);
expectComplexInfo('Function<T>(int x)', required: true);
- expectComplexInfo('Function(int x) m', tokenAfter: 'm');
- expectComplexInfo('Function<T>(int x) m', tokenAfter: 'm');
+ expectComplexInfo('Function(int x) m', expectedAfter: 'm');
+ expectComplexInfo('Function<T>(int x) m', expectedAfter: 'm');
expectComplexInfo('Function<T>(int x) Function<T>(int x)',
- required: false, tokenAfter: 'Function');
+ required: false, expectedAfter: 'Function');
expectComplexInfo('Function<T>(int x) Function<T>(int x)', required: true);
expectComplexInfo('Function<T>(int x) Function<T>(int x) m',
- tokenAfter: 'm');
+ expectedAfter: 'm');
}
void test_computeType_identifier() {
@@ -437,7 +437,7 @@
expectComplexInfo('C Function(int x)', required: true);
expectComplexInfo('C Function<T>(int x)', required: true);
expectComplexInfo('C Function<T>(int x) Function<T>(int x)',
- required: false, tokenAfter: 'Function');
+ required: false, expectedAfter: 'Function');
expectComplexInfo('C Function<T>(int x) Function<T>(int x)',
required: true);
expectComplexInfo('C Function(', // Scanner inserts synthetic ')'.
@@ -510,7 +510,7 @@
'endTypeArguments 1 < >',
'handleType C ',
]);
- expectComplexInfo('C<S,T> f', tokenAfter: 'f', expectedCalls: [
+ expectComplexInfo('C<S,T> f', expectedAfter: 'f', expectedCalls: [
'handleIdentifier C typeReference',
'beginTypeArguments <',
'handleIdentifier S typeReference',
@@ -522,7 +522,7 @@
'endTypeArguments 2 < >',
'handleType C f',
]);
- expectComplexInfo('C<S<T>> f', tokenAfter: 'f', expectedCalls: [
+ expectComplexInfo('C<S<T>> f', expectedAfter: 'f', expectedCalls: [
'handleIdentifier C typeReference',
'beginTypeArguments <',
'handleIdentifier S typeReference',
@@ -555,7 +555,7 @@
'endFunctionType Function ',
]);
expectComplexInfo('C<T> Function<T>(int x) Function<T>(int x)',
- required: false, tokenAfter: 'Function');
+ required: false, expectedAfter: 'Function');
expectComplexInfo('C<T> Function<T>(int x) Function<T>(int x)',
required: true);
}
@@ -594,17 +594,21 @@
], expectedErrors: [
error(codeExpectedType, 2, 1)
]);
- expectComplexInfo('C<> f', required: true, tokenAfter: 'f', expectedCalls: [
- 'handleIdentifier C typeReference',
- 'beginTypeArguments <',
- 'handleIdentifier typeReference',
- 'handleNoTypeArguments >',
- 'handleType >',
- 'endTypeArguments 1 < >',
- 'handleType C f',
- ], expectedErrors: [
- error(codeExpectedType, 2, 1)
- ]);
+ expectComplexInfo('C<> f',
+ required: true,
+ expectedAfter: 'f',
+ expectedCalls: [
+ 'handleIdentifier C typeReference',
+ 'beginTypeArguments <',
+ 'handleIdentifier typeReference',
+ 'handleNoTypeArguments >',
+ 'handleType >',
+ 'endTypeArguments 1 < >',
+ 'handleType C f',
+ ],
+ expectedErrors: [
+ error(codeExpectedType, 2, 1)
+ ]);
// Statements that should not have a type
expectInfo(noType, 'C<T ; T>U;', required: false);
@@ -653,11 +657,11 @@
}
void test_computeType_prefixedComplex() {
- expectComplexInfo('a < b, c > d', tokenAfter: 'd');
- expectComplexInfo('a < b, c > d', tokenAfter: 'd');
+ expectComplexInfo('a < b, c > d', expectedAfter: 'd');
+ expectComplexInfo('a < b, c > d', expectedAfter: 'd');
- expectComplexInfo('a < p.b, c > d', tokenAfter: 'd');
- expectComplexInfo('a < b, p.c > d', tokenAfter: 'd');
+ expectComplexInfo('a < p.b, c > d', expectedAfter: 'd');
+ expectComplexInfo('a < b, p.c > d', expectedAfter: 'd');
expectInfo(noType, 'a < p.q.b, c > d', required: false);
expectInfo(noType, 'a < b, p.q.c > d', required: false);
@@ -682,7 +686,7 @@
'endFunctionType Function ',
]);
expectComplexInfo('C.a Function<T>(int x) Function<T>(int x)',
- required: false, tokenAfter: 'Function');
+ required: false, expectedAfter: 'Function');
expectComplexInfo('C.a Function<T>(int x) Function<T>(int x)',
required: true);
}
@@ -700,7 +704,7 @@
'handleType C ',
]);
- expectComplexInfo('C.a<T> f', tokenAfter: 'f', expectedCalls: [
+ expectComplexInfo('C.a<T> f', expectedAfter: 'f', expectedCalls: [
'handleIdentifier C prefixedTypeReference',
'handleIdentifier a typeReferenceContinuation',
'handleQualified .',
@@ -823,7 +827,7 @@
expectComplexInfo('void Function<T>(int x)', required: true);
expectComplexInfo('void Function<T>(int x) Function<T>(int x)',
- required: false, tokenAfter: 'Function');
+ required: false, expectedAfter: 'Function');
expectComplexInfo('void Function<T>(int x) Function<T>(int x)',
required: true);
}
@@ -846,6 +850,15 @@
expect(listener.errors, isNull);
}
+ void test_noTypeParamOrArg_parseVariables() {
+ final Token start = scanString('before after').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(noTypeParamOrArg.parseVariables(start, new Parser(listener)), start);
+ expect(listener.calls, ['handleNoTypeVariables after']);
+ expect(listener.errors, isNull);
+ }
+
void test_simple_skip() {
final Token start = scanString('before <T> after').tokens;
final Token gt = start.next.next.next;
@@ -879,6 +892,26 @@
expect(listener.errors, isNull);
}
+ void test_simple_parseVariables() {
+ final Token start = scanString('before <T> after').tokens;
+ final Token gt = start.next.next.next;
+ expect(gt.lexeme, '>');
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(simpleTypeArgument1.parseVariables(start, new Parser(listener)), gt);
+ expect(listener.calls, [
+ 'beginTypeVariables <',
+ 'beginTypeVariable T',
+ 'beginMetadataStar T',
+ 'endMetadataStar 0',
+ 'handleIdentifier T typeVariableDeclaration',
+ 'handleNoType T',
+ 'endTypeVariable > null',
+ 'endTypeVariables 1 < >',
+ ]);
+ expect(listener.errors, isNull);
+ }
+
void test_simple_parseArguments2() {
final Token start = scanString('before <S<T>> after').tokens.next.next;
Token t = start.next.next;
@@ -891,7 +924,27 @@
'handleIdentifier T typeReference',
'handleNoTypeArguments >>',
'handleType T >>',
- 'endTypeArguments 1 < >>'
+ 'endTypeArguments 1 < T'
+ ]);
+ expect(listener.errors, isNull);
+ }
+
+ void test_simple_parseVariables2() {
+ final Token start = scanString('before <S<T>> after').tokens.next.next;
+ Token t = start.next.next;
+ expect(t.next.lexeme, '>>');
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(simpleTypeArgument1.parseVariables(start, new Parser(listener)), t);
+ expect(listener.calls, [
+ 'beginTypeVariables <',
+ 'beginTypeVariable T',
+ 'beginMetadataStar T',
+ 'endMetadataStar 0',
+ 'handleIdentifier T typeVariableDeclaration',
+ 'handleNoType T',
+ 'endTypeVariable T null',
+ 'endTypeVariables 1 < T',
]);
expect(listener.errors, isNull);
}
@@ -920,8 +973,8 @@
expect(typeVarInfo, simpleTypeArgument1, reason: source);
}
- void test_computeTypeVar_complex() {
- expectComplexTypeParamOrArg('<S,T>', expectedCalls: [
+ void test_computeTypeArg_complex() {
+ expectComplexTypeArg('<S,T>', expectedCalls: [
'beginTypeArguments <',
'handleIdentifier S typeReference',
'handleNoTypeArguments ,',
@@ -931,7 +984,7 @@
'handleType T >',
'endTypeArguments 2 < >'
]);
- expectComplexTypeParamOrArg('<S Function()>', expectedCalls: [
+ expectComplexTypeArg('<S Function()>', expectedCalls: [
'beginTypeArguments <',
'handleNoTypeVariables (',
'beginFunctionType S',
@@ -943,7 +996,7 @@
'endFunctionType Function >',
'endTypeArguments 1 < >'
]);
- expectComplexTypeParamOrArg('<void Function()>', expectedCalls: [
+ expectComplexTypeArg('<void Function()>', expectedCalls: [
'beginTypeArguments <',
'handleNoTypeVariables (',
'beginFunctionType void',
@@ -953,7 +1006,7 @@
'endFunctionType Function >',
'endTypeArguments 1 < >'
]);
- expectComplexTypeParamOrArg('<S<T>>', expectedCalls: [
+ expectComplexTypeArg('<S<T>>', expectedCalls: [
'beginTypeArguments <',
'handleIdentifier S typeReference',
'beginTypeArguments <',
@@ -964,18 +1017,18 @@
'handleType S >',
'endTypeArguments 1 < >'
]);
- expectComplexTypeParamOrArg('<S<T>>', splitGtGt: false, expectedCalls: [
+ expectComplexTypeArg('<S<T>>', splitGtGt: false, expectedCalls: [
'beginTypeArguments <',
'handleIdentifier S typeReference',
'beginTypeArguments <',
'handleIdentifier T typeReference',
'handleNoTypeArguments >>',
'handleType T >>',
- 'endTypeArguments 1 < >>',
+ 'endTypeArguments 1 < T',
'handleType S >>',
'endTypeArguments 1 < >>'
]);
- expectComplexTypeParamOrArg('<S<Function()>>', expectedCalls: [
+ expectComplexTypeArg('<S<Function()>>', expectedCalls: [
'beginTypeArguments <',
'handleIdentifier S typeReference',
'beginTypeArguments <',
@@ -989,23 +1042,21 @@
'handleType S >',
'endTypeArguments 1 < >'
]);
- expectComplexTypeParamOrArg('<S<Function()>>',
- splitGtGt: false,
- expectedCalls: [
- 'beginTypeArguments <',
- 'handleIdentifier S typeReference',
- 'beginTypeArguments <',
- 'handleNoTypeVariables (',
- 'beginFunctionType Function',
- 'handleNoType <',
- 'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
- 'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
- 'endFunctionType Function >>',
- 'endTypeArguments 1 < >>',
- 'handleType S >>',
- 'endTypeArguments 1 < >>'
- ]);
- expectComplexTypeParamOrArg('<S<void Function()>>', expectedCalls: [
+ expectComplexTypeArg('<S<Function()>>', splitGtGt: false, expectedCalls: [
+ 'beginTypeArguments <',
+ 'handleIdentifier S typeReference',
+ 'beginTypeArguments <',
+ 'handleNoTypeVariables (',
+ 'beginFunctionType Function',
+ 'handleNoType <',
+ 'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
+ 'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
+ 'endFunctionType Function >>',
+ 'endTypeArguments 1 < )',
+ 'handleType S >>',
+ 'endTypeArguments 1 < >>'
+ ]);
+ expectComplexTypeArg('<S<void Function()>>', expectedCalls: [
'beginTypeArguments <',
'handleIdentifier S typeReference',
'beginTypeArguments <',
@@ -1019,7 +1070,7 @@
'handleType S >',
'endTypeArguments 1 < >'
]);
- expectComplexTypeParamOrArg('<S<void Function()>>',
+ expectComplexTypeArg('<S<void Function()>>',
splitGtGt: false,
expectedCalls: [
'beginTypeArguments <',
@@ -1031,14 +1082,44 @@
'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
'endFunctionType Function >>',
- 'endTypeArguments 1 < >>',
+ 'endTypeArguments 1 < )',
'handleType S >>',
'endTypeArguments 1 < >>'
]);
}
- void test_computeTypeVar_complex_recovery() {
- expectComplexTypeParamOrArg('<@A S,T>', expectedErrors: [
+ void test_computeTypeArg_complex_recovery() {
+ expectComplexTypeArg('<S extends T>', expectedErrors: [
+ error(codeUnexpectedToken, 3, 7)
+ ], expectedCalls: [
+ 'beginTypeArguments <',
+ 'handleIdentifier S typeReference',
+ 'handleNoTypeArguments extends',
+ 'handleType S extends',
+ 'endTypeArguments 1 < >',
+ ]);
+ expectComplexTypeArg('<S extends List<T>>', expectedErrors: [
+ error(codeUnexpectedToken, 3, 7)
+ ], expectedCalls: [
+ 'beginTypeArguments <',
+ 'handleIdentifier S typeReference',
+ 'handleNoTypeArguments extends',
+ 'handleType S extends',
+ 'endTypeArguments 1 < >',
+ ]);
+ expectComplexTypeArg('<S extends List<T>>',
+ splitGtGt: false,
+ expectedErrors: [
+ error(codeUnexpectedToken, 3, 7)
+ ],
+ expectedCalls: [
+ 'beginTypeArguments <',
+ 'handleIdentifier S typeReference',
+ 'handleNoTypeArguments extends',
+ 'handleType S extends',
+ 'endTypeArguments 1 < >>',
+ ]);
+ expectComplexTypeArg('<@A S,T>', expectedErrors: [
error(codeUnexpectedToken, 1, 1)
], expectedCalls: [
'beginTypeArguments <',
@@ -1050,7 +1131,7 @@
'handleType T >',
'endTypeArguments 2 < >'
]);
- expectComplexTypeParamOrArg('<@A() S,T>', expectedErrors: [
+ expectComplexTypeArg('<@A() S,T>', expectedErrors: [
error(codeUnexpectedToken, 1, 1)
], expectedCalls: [
'beginTypeArguments <',
@@ -1062,7 +1143,7 @@
'handleType T >',
'endTypeArguments 2 < >'
]);
- expectComplexTypeParamOrArg('<@A() @B S,T>', expectedErrors: [
+ expectComplexTypeArg('<@A() @B S,T>', expectedErrors: [
error(codeUnexpectedToken, 1, 1),
error(codeUnexpectedToken, 6, 1),
], expectedCalls: [
@@ -1076,40 +1157,257 @@
'endTypeArguments 2 < >'
]);
}
+
+ void test_computeTypeParam_complex() {
+ expectComplexTypeParam('<S,T>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoType S',
+ 'endTypeVariable , null',
+ 'beginTypeVariable T',
+ 'beginMetadataStar T',
+ 'endMetadataStar 0',
+ 'handleIdentifier T typeVariableDeclaration',
+ 'handleNoType T',
+ 'endTypeVariable > null',
+ 'endTypeVariables 2 < >',
+ ]);
+ expectComplexTypeParam('<S extends T>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleIdentifier T typeReference',
+ 'handleNoTypeArguments >',
+ 'handleType T >',
+ 'endTypeVariable > extends',
+ 'endTypeVariables 1 < >',
+ ]);
+ expectComplexTypeParam('<S super T>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleIdentifier T typeReference',
+ 'handleNoTypeArguments >',
+ 'handleType T >',
+ 'endTypeVariable > super',
+ 'endTypeVariables 1 < >',
+ ]);
+ expectComplexTypeParam('<S extends List<T>>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleIdentifier List typeReference',
+ 'beginTypeArguments <',
+ 'handleIdentifier T typeReference',
+ 'handleNoTypeArguments >',
+ 'handleType T >',
+ 'endTypeArguments 1 < >',
+ 'handleType List >',
+ 'endTypeVariable > extends',
+ 'endTypeVariables 1 < >',
+ ]);
+ expectComplexTypeParam('<S extends List<T>>',
+ splitGtGt: false,
+ expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleIdentifier List typeReference',
+ 'beginTypeArguments <',
+ 'handleIdentifier T typeReference',
+ 'handleNoTypeArguments >>',
+ 'handleType T >>',
+ 'endTypeArguments 1 < T',
+ 'handleType List >>',
+ 'endTypeVariable >> extends',
+ 'endTypeVariables 1 < >>',
+ ]);
+ expectComplexTypeParam('<R, S extends void Function()>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable R',
+ 'beginMetadataStar R',
+ 'endMetadataStar 0',
+ 'handleIdentifier R typeVariableDeclaration',
+ 'handleNoType R',
+ 'endTypeVariable , null',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoTypeVariables (',
+ 'beginFunctionType void',
+ 'handleVoidKeyword void',
+ 'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
+ 'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
+ 'endFunctionType Function >',
+ 'endTypeVariable > extends',
+ 'endTypeVariables 2 < >',
+ ]);
+ expectComplexTypeParam('<@A S,T>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable @',
+ 'beginMetadataStar @',
+ 'beginMetadata @',
+ 'handleIdentifier A metadataReference',
+ 'handleNoTypeArguments S',
+ 'handleNoArguments S',
+ 'endMetadata @ null S',
+ 'endMetadataStar 1',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoType S',
+ 'endTypeVariable , null',
+ 'beginTypeVariable T',
+ 'beginMetadataStar T',
+ 'endMetadataStar 0',
+ 'handleIdentifier T typeVariableDeclaration',
+ 'handleNoType T',
+ 'endTypeVariable > null',
+ 'endTypeVariables 2 < >',
+ ]);
+ expectComplexTypeParam('<@A() S,T>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable @',
+ 'beginMetadataStar @',
+ 'beginMetadata @',
+ 'handleIdentifier A metadataReference',
+ 'handleNoTypeArguments (',
+ 'beginArguments (',
+ 'endArguments 0 ( )',
+ 'endMetadata @ null S',
+ 'endMetadataStar 1',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoType S',
+ 'endTypeVariable , null',
+ 'beginTypeVariable T',
+ 'beginMetadataStar T',
+ 'endMetadataStar 0',
+ 'handleIdentifier T typeVariableDeclaration',
+ 'handleNoType T',
+ 'endTypeVariable > null',
+ 'endTypeVariables 2 < >',
+ ]);
+ expectComplexTypeParam('<@A() @B S,T>', expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable @',
+ 'beginMetadataStar @',
+ 'beginMetadata @',
+ 'handleIdentifier A metadataReference',
+ 'handleNoTypeArguments (',
+ 'beginArguments (',
+ 'endArguments 0 ( )',
+ 'endMetadata @ null @',
+ 'beginMetadata @',
+ 'handleIdentifier B metadataReference',
+ 'handleNoTypeArguments S',
+ 'handleNoArguments S',
+ 'endMetadata @ null S',
+ 'endMetadataStar 2',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoType S',
+ 'endTypeVariable , null',
+ 'beginTypeVariable T',
+ 'beginMetadataStar T',
+ 'endMetadataStar 0',
+ 'handleIdentifier T typeVariableDeclaration',
+ 'handleNoType T',
+ 'endTypeVariable > null',
+ 'endTypeVariables 2 < >',
+ ]);
+ }
+
+ void test_computeTypeParam_complex_recovery() {
+ expectComplexTypeParam('<S Function()>', expectedErrors: [
+ error(codeUnexpectedToken, 3, 8),
+ ], expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoType S',
+ 'endTypeVariable Function null',
+ 'endTypeVariables 1 < >',
+ ]);
+ expectComplexTypeParam('<void Function()>', expectedErrors: [
+ error(codeExpectedIdentifier, 1, 4),
+ error(codeUnexpectedToken, 1, 4),
+ ], expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable void',
+ 'beginMetadataStar void',
+ 'endMetadataStar 0',
+ 'handleIdentifier typeVariableDeclaration',
+ 'handleNoType ',
+ 'endTypeVariable void null',
+ 'endTypeVariables 1 < >',
+ ]);
+ expectComplexTypeParam('<S<T>>', expectedErrors: [
+ error(codeUnexpectedToken, 2, 1),
+ ], expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoType S',
+ 'endTypeVariable < null',
+ 'endTypeVariables 1 < >',
+ ]);
+ expectComplexTypeParam('<S<T>>',
+ expectedErrors: [
+ error(codeUnexpectedToken, 2, 1),
+ ],
+ splitGtGt: false,
+ expectedCalls: [
+ 'beginTypeVariables <',
+ 'beginTypeVariable S',
+ 'beginMetadataStar S',
+ 'endMetadataStar 0',
+ 'handleIdentifier S typeVariableDeclaration',
+ 'handleNoType S',
+ 'endTypeVariable < null',
+ 'endTypeVariables 1 < >>',
+ ]);
+ }
}
-void expectInfo(expectedInfo, String source,
- {bool required,
- String expectedAfter,
- List<String> expectedCalls,
- List<ExpectedError> expectedErrors}) {
- Token start = scan(source);
+void expectInfo(expectedInfo, String source, {bool required}) {
if (required == null) {
- compute(expectedInfo, source, start, true, expectedAfter, expectedCalls,
- expectedErrors);
- start = scan(source);
- compute(expectedInfo, source, start, false, expectedAfter, expectedCalls,
- expectedErrors);
+ compute(expectedInfo, source, scan(source), true);
+ compute(expectedInfo, source, scan(source), false);
} else {
- compute(expectedInfo, source, start, required, expectedAfter, expectedCalls,
- expectedErrors);
+ compute(expectedInfo, source, scan(source), required);
}
}
void expectComplexInfo(String source,
{bool required,
- String tokenAfter,
+ String expectedAfter,
List<String> expectedCalls,
List<ExpectedError> expectedErrors}) {
- expectInfo(const isInstanceOf<ComplexTypeInfo>(), source,
- required: required,
- expectedAfter: tokenAfter,
- expectedCalls: expectedCalls,
- expectedErrors: expectedErrors);
+ if (required == null) {
+ computeComplex(source, scan(source), true, expectedAfter, expectedCalls,
+ expectedErrors);
+ computeComplex(source, scan(source), false, expectedAfter, expectedCalls,
+ expectedErrors);
+ } else {
+ computeComplex(source, scan(source), required, expectedAfter, expectedCalls,
+ expectedErrors);
+ }
}
-void expectNestedInfo(expectedInfo, String source,
- {List<String> expectedCalls, List<ExpectedError> expectedErrors}) {
+void expectNestedInfo(expectedInfo, String source) {
expect(source.startsWith('<'), isTrue);
Token start = scan(source).next;
Token innerEndGroup = start;
@@ -1119,73 +1417,148 @@
if (!optional('>>', innerEndGroup)) {
innerEndGroup = null;
}
- compute(expectedInfo, source, start, true, innerEndGroup != null ? '>>' : '>',
- expectedCalls, expectedErrors,
- innerEndGroup: innerEndGroup);
+ compute(expectedInfo, source, start, true, innerEndGroup: innerEndGroup);
}
-void expectNestedComplexInfo(String source,
- {List<String> expectedCalls, List<ExpectedError> expectedErrors}) {
- expectNestedInfo(const isInstanceOf<ComplexTypeInfo>(), source,
- expectedCalls: expectedCalls, expectedErrors: expectedErrors);
+void expectNestedComplexInfo(String source) {
+ expectNestedInfo(const isInstanceOf<ComplexTypeInfo>(), source);
}
-void compute(
- expectedInfo,
- String source,
- Token start,
- bool required,
- String expectedAfter,
- List<String> expectedCalls,
- List<ExpectedError> expectedErrors,
+TypeInfo compute(expectedInfo, String source, Token start, bool required,
{Token innerEndGroup}) {
int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
TypeInfo typeInfo = computeType(start, required, innerEndGroup);
expect(typeInfo, expectedInfo, reason: source);
expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
reason: 'computeType should not modify the token stream');
-
- if (typeInfo is ComplexTypeInfo) {
- expect(typeInfo.start, start.next, reason: source);
- expect(typeInfo.couldBeExpression, isFalse);
- expectEnd(expectedAfter, typeInfo.skipType(start));
- expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
- reason: 'TypeInfo.skipType should not modify the token stream');
-
- TypeInfoListener listener;
- assertResult(Token actualEnd) {
- expectEnd(expectedAfter, actualEnd);
- if (expectedCalls != null) {
- // TypeInfoListener listener2 = new TypeInfoListener();
- // new Parser(listener2).parseType(start, TypeContinuation.Required);
- // print('[');
- // for (String call in listener2.calls) {
- // print("'$call',");
- // }
- // print(']');
-
- expect(listener.calls, expectedCalls, reason: source);
- }
- expect(listener.errors, expectedErrors, reason: source);
- }
-
- listener = new TypeInfoListener();
- assertResult(typeInfo.parseType(start, new Parser(listener)));
- } else {
- expect(expectedErrors, isNull);
- }
+ return typeInfo;
}
-void expectComplexTypeParamOrArg(String source,
+ComplexTypeInfo computeComplex(
+ String source,
+ Token start,
+ bool required,
+ String expectedAfter,
+ List<String> expectedCalls,
+ List<ExpectedError> expectedErrors) {
+ int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
+ ComplexTypeInfo typeInfo =
+ compute(const isInstanceOf<ComplexTypeInfo>(), source, start, required);
+ expect(typeInfo.start, start.next, reason: source);
+ expect(typeInfo.couldBeExpression, isFalse);
+ expectEnd(expectedAfter, typeInfo.skipType(start));
+ expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+ reason: 'TypeInfo.skipType should not modify the token stream');
+
+ TypeInfoListener listener = new TypeInfoListener();
+ Token actualEnd = typeInfo.parseType(start, new Parser(listener));
+
+ expectEnd(expectedAfter, actualEnd);
+ if (expectedCalls != null) {
+ // TypeInfoListener listener2 = new TypeInfoListener();
+ // new Parser(listener2).parseType(start, TypeContinuation.Required);
+ // print('[');
+ // for (String call in listener2.calls) {
+ // print("'$call',");
+ // }
+ // print(']');
+
+ expect(listener.calls, expectedCalls, reason: source);
+ }
+ expect(listener.errors, expectedErrors, reason: source);
+ return typeInfo;
+}
+
+void expectComplexTypeArg(String source,
{bool splitGtGt: true,
- String tokenAfter,
+ String expectedAfter,
List<String> expectedCalls,
List<ExpectedError> expectedErrors}) {
- expectTypeParamOrArg(const isInstanceOf<ComplexTypeParamOrArgInfo>(), source,
- splitGtGt: splitGtGt,
- expectedAfter: tokenAfter,
- expectedCalls: expectedCalls,
- expectedErrors: expectedErrors);
+ Token start = scan(source);
+ int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
+ ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
+ const isInstanceOf<ComplexTypeParamOrArgInfo>(), source, start);
+
+ expect(typeVarInfo.start, start.next, reason: source);
+ expectEnd(expectedAfter, typeVarInfo.skip(start));
+ expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+ reason: 'TypeParamOrArgInfo.skipType'
+ ' should not modify the token stream');
+
+ TypeInfoListener listener = new TypeInfoListener();
+ Parser parser = new Parser(listener);
+ if (!splitGtGt) {
+ parser.cachedRewriter = new TokenStreamNonRewriter();
+ }
+ Token actualEnd = typeVarInfo.parseArguments(start, parser);
+ expectEnd(expectedAfter, actualEnd);
+ if (!splitGtGt) {
+ expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+ reason: 'TypeParamOrArgInfo.parseArguments'
+ ' should not modify the token stream');
+ }
+
+ if (expectedCalls != null) {
+ try {
+ expect(listener.calls, expectedCalls, reason: source);
+ } catch (e) {
+ TypeInfoListener listener2 = new TypeInfoListener();
+ new Parser(listener2).parseTypeArgumentsOpt(start);
+ print('Events from parseTypeArgumentsOpt: [');
+ for (String call in listener2.calls) {
+ print(" '$call',");
+ }
+ print(']');
+ rethrow;
+ }
+ }
+ expect(listener.errors, expectedErrors, reason: source);
+}
+
+void expectComplexTypeParam(String source,
+ {bool splitGtGt: true,
+ String expectedAfter,
+ List<String> expectedCalls,
+ List<ExpectedError> expectedErrors}) {
+ Token start = scan(source);
+ int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
+ ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
+ const isInstanceOf<ComplexTypeParamOrArgInfo>(), source, start);
+
+ expect(typeVarInfo.start, start.next, reason: source);
+ expectEnd(expectedAfter, typeVarInfo.skip(start));
+ expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+ reason: 'TypeParamOrArgInfo.skipType'
+ ' should not modify the token stream');
+
+ TypeInfoListener listener = new TypeInfoListener(metadataAllowed: true);
+ Parser parser = new Parser(listener);
+ if (!splitGtGt) {
+ parser.cachedRewriter = new TokenStreamNonRewriter();
+ }
+ Token actualEnd = typeVarInfo.parseVariables(start, parser);
+ expectEnd(expectedAfter, actualEnd);
+ if (!splitGtGt) {
+ expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+ reason: 'TypeParamOrArgInfo.parseVariables'
+ ' should not modify the token stream');
+ }
+
+ if (expectedCalls != null) {
+ try {
+ expect(listener.calls, expectedCalls, reason: source);
+ } catch (e) {
+ TypeInfoListener listener2 = new TypeInfoListener(metadataAllowed: true);
+ new Parser(listener2).parseTypeVariablesOpt(start);
+ print('Events from parseTypeVariablesOpt: [');
+ for (String call in listener2.calls) {
+ print(" '$call',");
+ }
+ print(']');
+ rethrow;
+ }
+ }
+ expect(listener.errors, expectedErrors, reason: source);
}
void expectTypeParamOrArg(expectedInfo, String source,
@@ -1194,59 +1567,16 @@
List<String> expectedCalls,
List<ExpectedError> expectedErrors}) {
Token start = scan(source);
- computeVar(expectedInfo, source, start, splitGtGt, expectedAfter,
- expectedCalls, expectedErrors);
+ computeVar(expectedInfo, source, start);
}
-void computeVar(
- expectedInfo,
- String source,
- Token start,
- bool splitGtGt,
- String expectedAfter,
- List<String> expectedCalls,
- List<ExpectedError> expectedErrors) {
+TypeParamOrArgInfo computeVar(expectedInfo, String source, Token start) {
int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
TypeParamOrArgInfo typeVarInfo = computeTypeParamOrArg(start);
expect(typeVarInfo, expectedInfo, reason: source);
expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
reason: 'computeTypeParamOrArg should not modify the token stream');
-
- if (typeVarInfo is ComplexTypeParamOrArgInfo) {
- expect(typeVarInfo.start, start.next, reason: source);
- expectEnd(expectedAfter, typeVarInfo.skip(start));
- expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
- reason: 'TypeParamOrArgInfo.skipType'
- ' should not modify the token stream');
-
- TypeInfoListener listener = new TypeInfoListener();
- Parser parser = new Parser(listener);
- if (!splitGtGt) {
- parser.cachedRewriter = new TokenStreamNonRewriter();
- }
- Token actualEnd = typeVarInfo.parseArguments(start, parser);
- expectEnd(expectedAfter, actualEnd);
- if (!splitGtGt) {
- expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
- reason: 'TypeParamOrArgInfo.parseArguments'
- ' should not modify the token stream');
- }
-
- if (expectedCalls != null) {
- // TypeInfoListener listener2 = new TypeInfoListener();
- // new Parser(listener2).parseTypeArgumentsOpt(start);
- // print('[');
- // for (String call in listener2.calls) {
- // print("'$call',");
- // }
- // print(']');
-
- expect(listener.calls, expectedCalls, reason: source);
- }
- expect(listener.errors, expectedErrors, reason: source);
- } else {
- expect(expectedErrors, isNull);
- }
+ return typeVarInfo;
}
void expectEnd(String tokenAfter, Token end) {
@@ -1279,9 +1609,21 @@
}
class TypeInfoListener implements Listener {
+ final bool metadataAllowed;
List<String> calls = <String>[];
List<ExpectedError> errors;
+ TypeInfoListener({this.metadataAllowed: false});
+
+ @override
+ void beginArguments(Token token) {
+ if (metadataAllowed) {
+ calls.add('beginArguments $token');
+ } else {
+ throw 'beginArguments should not be called.';
+ }
+ }
+
@override
void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
Token varFinalOrConst) {
@@ -1299,6 +1641,15 @@
}
@override
+ void beginMetadata(Token token) {
+ if (metadataAllowed) {
+ calls.add('beginMetadata $token');
+ } else {
+ throw 'beginMetadata should not be called.';
+ }
+ }
+
+ @override
void beginMetadataStar(Token token) {
calls.add('beginMetadataStar $token');
}
@@ -1325,6 +1676,15 @@
}
@override
+ void endArguments(int count, Token beginToken, Token endToken) {
+ if (metadataAllowed) {
+ calls.add('endArguments $count $beginToken $endToken');
+ } else {
+ throw 'endArguments should not be called.';
+ }
+ }
+
+ @override
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
calls.add('beginTypeVariables $thisKeyword $periodAfterThis '
@@ -1337,6 +1697,15 @@
}
@override
+ void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
+ if (metadataAllowed) {
+ calls.add('endMetadata $beginToken $periodBeforeName $endToken');
+ } else {
+ throw 'endMetadata should not be called.';
+ }
+ }
+
+ @override
void endMetadataStar(int count) {
calls.add('endMetadataStar $count');
}
@@ -1367,6 +1736,15 @@
}
@override
+ void handleNoArguments(Token token) {
+ if (metadataAllowed) {
+ calls.add('handleNoArguments $token');
+ } else {
+ throw 'handleNoArguments should not be called.';
+ }
+ }
+
+ @override
void handleNoName(Token token) {
calls.add('handleNoName $token');
}
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index 0bb2e82..5089798 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -235,9 +235,9 @@
}
}
bool gotError = false;
- List<String> formattedErrors = <String>[];
+ final List<String> formattedErrors = <String>[];
bool gotWarning = false;
- List<String> formattedWarnings = <String>[];
+ final List<String> formattedWarnings = <String>[];
options.onProblem = (FormattedMessage problem, Severity severity,
List<FormattedMessage> context) {
@@ -264,16 +264,8 @@
Stopwatch stopwatch = new Stopwatch()..start();
Component component = await compiler.computeDelta(
fullComponent: brandNewWorld ? false : true);
- if (world["errors"] == true && !gotError) {
- throw "Expected error, but didn't get any.";
- } else if (world["errors"] != true && gotError) {
- throw "Got unexpected error(s): $formattedErrors.";
- }
- if (world["warnings"] == true && !gotWarning) {
- throw "Expected warning, but didn't get any.";
- } else if (world["warnings"] != true && gotWarning) {
- throw "Got unexpected warnings(s): $formattedWarnings.";
- }
+ performErrorAndWarningCheck(
+ world, gotError, formattedErrors, gotWarning, formattedWarnings);
util.throwOnEmptyMixinBodies(component);
print("Compile took ${stopwatch.elapsedMilliseconds} ms");
newestWholeComponent = serializeComponent(component);
@@ -307,13 +299,37 @@
}
{
+ gotError = false;
+ formattedErrors.clear();
+ gotWarning = false;
+ formattedWarnings.clear();
Component component2 = await compiler.computeDelta(fullComponent: true);
+ performErrorAndWarningCheck(
+ world, gotError, formattedErrors, gotWarning, formattedWarnings);
List<int> thisWholeComponent = serializeComponent(component2);
checkIsEqual(newestWholeComponent, thisWholeComponent);
}
}
}
+void performErrorAndWarningCheck(
+ Map<String, dynamic> world,
+ bool gotError,
+ List<String> formattedErrors,
+ bool gotWarning,
+ List<String> formattedWarnings) {
+ if (world["errors"] == true && !gotError) {
+ throw "Expected error, but didn't get any.";
+ } else if (world["errors"] != true && gotError) {
+ throw "Got unexpected error(s): $formattedErrors.";
+ }
+ if (world["warnings"] == true && !gotWarning) {
+ throw "Expected warning, but didn't get any.";
+ } else if (world["warnings"] != true && gotWarning) {
+ throw "Got unexpected warnings(s): $formattedWarnings.";
+ }
+}
+
void checkIsEqual(List<int> a, List<int> b) {
int length = a.length;
if (b.length < length) {
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index 861b2fd..d03ee59 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -592,6 +592,10 @@
_assertKeywordToken("implements");
}
+ void test_keyword_interface() {
+ _assertKeywordToken("interface");
+ }
+
void test_keyword_import() {
_assertKeywordToken("import");
}
@@ -608,6 +612,10 @@
_assertKeywordToken("library");
}
+ void test_keyword_mixin() {
+ _assertKeywordToken("mixin");
+ }
+
void test_keyword_native() {
_assertKeywordToken("native");
}
diff --git a/pkg/front_end/test/summary_generator_test.dart b/pkg/front_end/test/summary_generator_test.dart
index 05d582c..435e5ec 100644
--- a/pkg/front_end/test/summary_generator_test.dart
+++ b/pkg/front_end/test/summary_generator_test.dart
@@ -14,9 +14,9 @@
var summary = await summarize(['a.dart'], allSources);
var component = loadComponentFromBytes(summary);
- // Note: the kernel representation always has an empty '' key in the map,
+ // Note: the kernel representation always has a null key in the map,
// but otherwise no other data is included here.
- expect(component.uriToSource.keys.single, Uri.parse(""));
+ expect(component.uriToSource.keys.single, null);
});
test('summary includes declarations, but no method bodies', () async {
diff --git a/pkg/front_end/test/token_test.dart b/pkg/front_end/test/token_test.dart
index 78ec8ba..aa1e79e 100644
--- a/pkg/front_end/test/token_test.dart
+++ b/pkg/front_end/test/token_test.dart
@@ -158,7 +158,9 @@
Keyword.GET,
Keyword.IMPLEMENTS,
Keyword.IMPORT,
+ Keyword.INTERFACE,
Keyword.LIBRARY,
+ Keyword.MIXIN,
Keyword.OPERATOR,
Keyword.PART,
Keyword.SET,
diff --git a/pkg/front_end/testcases/argument_mismatch.dart.direct.expect b/pkg/front_end/testcases/argument_mismatch.dart.direct.expect
index 5d084af..5f3f9aa 100644
--- a/pkg/front_end/testcases/argument_mismatch.dart.direct.expect
+++ b/pkg/front_end/testcases/argument_mismatch.dart.direct.expect
@@ -4,6 +4,6 @@
static method foo() → dynamic {}
static method test() → dynamic {
- throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[null].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[null]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect b/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
index 5d084af..5f3f9aa 100644
--- a/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
@@ -4,6 +4,6 @@
static method foo() → dynamic {}
static method test() → dynamic {
- throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[null].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[null]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
index 1c3d9f3..d60b2fc 100644
--- a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
@@ -2,4 +2,4 @@
Method not found: 'doit_with_this'. (@0)
}
static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[3]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
index ff2d316..8480ea2 100644
--- a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
@@ -2,4 +2,4 @@
Setter not found: 'z'. (@0)
}
static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[2]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
index 2a1fd01..af61daf 100644
--- a/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
@@ -2,4 +2,4 @@
Method not found: 'doit_with_this'. (@0)
}
static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[2]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/invalid.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
index 1e3cd80..cc26db7 100644
--- a/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
@@ -5,4 +5,4 @@
Getter not found: ''. (@0)
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).*(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#foo, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
+ return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).*(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#foo, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[3]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
index d7a9a32..4c7dfed 100644
--- a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
@@ -2,4 +2,4 @@
Method not found: 'acos'. (@0)
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#acos, 32, const <dart.core::Type>[], <dynamic>[1.0].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#acos, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[1.0]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
index 699e4fa..f6b2dd6 100644
--- a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
@@ -2,4 +2,4 @@
Method not found: 'Directory'. (@4)
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Directory, 32, const <dart.core::Type>[], <dynamic>["test"].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Directory, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>["test"]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect b/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
index 9ac1d76..53674fd 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
@@ -14,28 +14,28 @@
core::String a = "foo";
dynamic b;
if(self::ImplicitScopeTest::alwaysTrue()) {
- dynamic a = "bar";
+ core::String a = "bar";
}
else {
- dynamic b = a;
+ core::String b = a;
}
exp::Expect::equals("foo", a);
exp::Expect::equals(null, b);
while (!self::ImplicitScopeTest::alwaysTrue()) {
- dynamic a = "bar";
- dynamic b = "baz";
+ core::String a = "bar";
+ core::String b = "baz";
}
exp::Expect::equals("foo", a);
exp::Expect::equals(null, b);
for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
- dynamic a = "bar";
- dynamic b = "baz";
+ core::String a = "bar";
+ core::String b = "baz";
}
exp::Expect::equals("foo", a);
exp::Expect::equals(null, b);
do {
- dynamic a = "bar";
- dynamic b = "baz";
+ core::String a = "bar";
+ core::String b = "baz";
}
while ("black".{core::String::==}("white"))
exp::Expect::equals("foo", a);
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect b/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
index 9ac1d76..53674fd 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
@@ -14,28 +14,28 @@
core::String a = "foo";
dynamic b;
if(self::ImplicitScopeTest::alwaysTrue()) {
- dynamic a = "bar";
+ core::String a = "bar";
}
else {
- dynamic b = a;
+ core::String b = a;
}
exp::Expect::equals("foo", a);
exp::Expect::equals(null, b);
while (!self::ImplicitScopeTest::alwaysTrue()) {
- dynamic a = "bar";
- dynamic b = "baz";
+ core::String a = "bar";
+ core::String b = "baz";
}
exp::Expect::equals("foo", a);
exp::Expect::equals(null, b);
for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
- dynamic a = "bar";
- dynamic b = "baz";
+ core::String a = "bar";
+ core::String b = "baz";
}
exp::Expect::equals("foo", a);
exp::Expect::equals(null, b);
do {
- dynamic a = "bar";
- dynamic b = "baz";
+ core::String a = "bar";
+ core::String b = "baz";
}
while ("black".{core::String::==}("white"))
exp::Expect::equals("foo", a);
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml
new file mode 100644
index 0000000..f1213e3
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml
@@ -0,0 +1,69 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application that's fine.
+# Invalidate a file that's been updated and fine (and would pull in another
+# library). Also invalidate another file that's been updated to produce a
+# compile time error.
+# Update again, fixing the error.
+# The invalidation of the good file should still apply, i.e. the new library
+# that it pulled in should be included.
+
+type: newworld
+strong: false
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ import "b.dart";
+ main() {
+ print("hello");
+ b();
+ }
+ b.dart: |
+ b() {
+ print("hello from b");
+ }
+ c.dart: |
+ c() {
+ print("hello from c");
+ }
+ expectedLibraryCount: 2
+ - entry: main.dart
+ worldType: updated
+ expectInitializeFromDill: false
+ checkInvalidatedFiles: false
+ invalidate:
+ - b.dart
+ - main.dart
+ sources:
+ main.dart: |
+ import "b.dart";
+ import "nonexistin.dart";
+ main() {
+ print("hello");
+ b();
+ }
+ b.dart: |
+ import "c.dart";
+ b() {
+ print("hello from b");
+ c();
+ }
+ errors: true
+ expectedLibraryCount: 1
+ - entry: main.dart
+ worldType: updated
+ expectInitializeFromDill: false
+ checkInvalidatedFiles: false
+ invalidate:
+ - main.dart
+ sources:
+ main.dart: |
+ import "b.dart";
+ main() {
+ print("hello");
+ b();
+ }
+ expectedLibraryCount: 3
\ No newline at end of file
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.expect
index 238fc77..98124f7 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
index d3553bd..440a04c 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.outline.expect b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
index e39f077..b0f41cc 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
index 7c6f301..ab76573 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
index d6b1ae2..5f0821f 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
index 433be3a..8dd522c 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
index 4a812f5..2c71d0b 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
index 73bad2f..a5f1b36 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
index 28f970f..aea52b3 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
index 05ea1f5..11ee82f 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
index c317b12..14bbd85 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
index 87a94a2..79dea19 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
index 9d89e58..7260212 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
index ed1cac1..2c1403c 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
index a2ad76f..79ba4a3 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
index 8457b85..d0224a3 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
index d8ab165..c2e1984 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
index 62658a3..c373616 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
index 44f49a0..4a8eee5 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
index a90f007..4181e8a 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
index be6b273..c74cdc3 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
index 434b5d6..7ea34b6 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
index 9beae3a..98b7e61 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
index b6243b1..5013ebe 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
index 60890bc..c81cc0b 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
index f2f15cd..ef09e80 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
index fbba4bf..cd172d7 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
index 40bc63d..d37757e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
index ffc7080..63e39eb 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
index 2fa2c058..633179c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
index d571a7d..58fc7dc 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
index 6ce1dea..ce0b933 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
index 215e634..4d5d177 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
index ef2e0fb..ef96253 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
index 3497766..60b455d 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
index a4ca1ff..cf77812 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
index 801d3e8..0e1c731 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
index 5ceaae0..8299fbb 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
index af913b3..9207e2c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
index cae896d..e57873c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
index 94ca72c..5efa1a5 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
index a20328a..4d49b6e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
index 06319b5..4375997 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
index 6d3f557..468ec31 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
index 57291da..66fd5b3 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
index 77de0e0..ba9e600 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
index 4b0e44c..af3fa30 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
index 5d100b9..792ef91 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
index 2665c52..5d21b4b 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
index cb0d0d1..e57d937 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
index 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
index 9e96f13..1eddb4a 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
index aeb0d5a..311f23d 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
index 4f7b85b..4d6cabd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
index 4f7b85b..4d6cabd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
index b0ad581..c63fbb8 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
index 544b68b..f73a813 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
index 671d8b5..62c39b7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
index 8e506d2..dcb5ae3 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
index 8e506d2..dcb5ae3 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
index b0ad581..c63fbb8 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
index dec6374..1e8d4cc 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
index 70bf88a..2f256a9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
index 78825bf..994012f 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
index 78825bf..994012f 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
index f7f3336..cfcba8d 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
index e5af8f4..73b2edf 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::double> f = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
index 2a2356f..7380ae9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::double> f = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
index cf63b53..81cd117 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return x ? 42 : asy::Future::value<dynamic>(42);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
index b058d42..9397ba5 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
index cb95b45..d6eb3cf 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int>
;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
index 011546b..360051f 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return (x ?{core::Object} 42 : asy::Future::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
index ed67f60..61d62cb 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
index d08eb4f..696d941 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return x ? 42 : new self::MyFuture::value<dynamic>(42);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
index fa93ea9..f31e5ca 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
index cb95b45..d6eb3cf 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int>
;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
index a5c2511..27f64bd 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return (x ?{core::Object} 42 : new self::MyFuture::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
index 611b1c4..ab69947 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
index 31c6b7a..eb9e275 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
index 167fe79..fab89fe 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
index 2bad4e8..8fbf742 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
index ab7fd1f..a2ccb18 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
index 97f2740..c8a55a9 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
index e8e6411..88065da 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
index 24fedaa..b669441 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
index 2bad4e8..8fbf742 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
index ff63cfd..bf7763d 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
index 9a1784c..9dfa187 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
index 9027e83..55b480f 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
index aacc250..7e22485 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
index 4e0c84c..08527e8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
index 74ed3dc..3ad2061 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
index e53a2b4..55eb919 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
index 4873748..5ec4bdd 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
index 87239a3..7d02922 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
index 4e0c84c..08527e8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
@@ -12,10 +12,14 @@
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
index afa05ba..d06ad27 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
index 1234c31..f9e32bb 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
@@ -12,10 +12,14 @@
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+ no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+ return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
index 9daa0ae..74cc102 100644
--- a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method method<generic-covariant-impl U extends self::Foo::T = dynamic>(self::Foo::method::U u) → self::Foo::method::U
+ method method<generic-covariant-impl U extends self::Foo::T = self::Foo::T>(self::Foo::method::U u) → self::Foo::method::U
return u;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
index 7572fdd..39a38a2 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method m<T extends core::num = dynamic>(self::C::m::T x, self::C::m::T y) → self::C::m::T
+ method m<T extends core::num = core::num>(self::C::m::T x, self::C::m::T y) → self::C::m::T
return null;
}
static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
index a687df6..4a4c032 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method m<T extends core::num = dynamic>(self::C::m::T x, self::C::m::T y) → self::C::m::T
+ method m<T extends core::num = core::num>(self::C::m::T x, self::C::m::T y) → self::C::m::T
return null;
}
static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
index 544bc96..9071805 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
@@ -6,7 +6,7 @@
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
function g() → dynamic
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
index 544bc96..9071805 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
@@ -6,7 +6,7 @@
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
function g() → dynamic
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
index 1b564d8..ab874a0 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
@@ -9,10 +9,10 @@
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
- function g() → dynamic
+ function g() → core::int
return 0;
}
() → dynamic v = f;
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
index fa37ad4..ab874a0 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
@@ -9,10 +9,10 @@
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
{
- let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
- function g() → dynamic
+ function g() → core::int
return 0;
}
() → dynamic v = f;
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect
index a25cdbd..0c5b98a 100644
--- a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect
@@ -14,7 +14,7 @@
;
abstract method bar() → void;
}
-static method f<T extends self::B = dynamic>(self::f::T a) → void {
+static method f<T extends self::B = self::B>(self::f::T a) → void {
if(a is core::String) {
a.{self::B::foo}();
}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
index a25cdbd..0c5b98a 100644
--- a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
;
abstract method bar() → void;
}
-static method f<T extends self::B = dynamic>(self::f::T a) → void {
+static method f<T extends self::B = self::B>(self::f::T a) → void {
if(a is core::String) {
a.{self::B::foo}();
}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
index 637e4c1..b5ce346 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.direct.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
@@ -64,7 +64,7 @@
{
self::T t;
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -72,7 +72,7 @@
}
{
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -81,7 +81,7 @@
{
self::T t;
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
@@ -89,7 +89,7 @@
}
{
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
index 637e4c1..b5ce346 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
@@ -64,7 +64,7 @@
{
self::T t;
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -72,7 +72,7 @@
}
{
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -81,7 +81,7 @@
{
self::T t;
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
@@ -89,7 +89,7 @@
}
{
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
index 3c4db65..3790ec0 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
@@ -66,7 +66,7 @@
{
self::T t;
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -74,7 +74,7 @@
}
{
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -83,7 +83,7 @@
{
self::T t;
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
@@ -91,7 +91,7 @@
}
{
{
- let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
index 155e18a..94ed7c1 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
@@ -66,7 +66,7 @@
{
self::T t;
{
- let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -74,7 +74,7 @@
}
{
{
- let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
^";
function T() → self::T {}
@@ -83,7 +83,7 @@
{
self::T t;
{
- let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
@@ -91,7 +91,7 @@
}
{
{
- let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
^";
function T(self::T t) → self::T {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect
index f5898c4..e05ba5e 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect
@@ -16,7 +16,8 @@
class B extends self::A implements self::I {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect
index a299436..f1b794a 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect
@@ -17,7 +17,8 @@
class B extends self::A implements self::I {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect
@@ -20,6 +20,7 @@
synthetic constructor •() → void
: super self::A::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect
index 7463788..5d8ddf7 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect
@@ -8,7 +8,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class M extends core::Object {
synthetic constructor •() → void
@@ -23,7 +24,8 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&M = core::Object with self::M {
}
@@ -31,6 +33,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect
index 49caf94..eb2d0a0 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect
@@ -8,7 +8,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class M extends core::Object {
synthetic constructor •() → void
@@ -28,7 +29,8 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&M extends core::Object implements self::M {
synthetic constructor •() → void
@@ -41,6 +43,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect
index f61d498..0901c24 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect
@@ -7,7 +7,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class M extends core::Object {
synthetic constructor •() → void
@@ -20,14 +21,16 @@
class A extends self::_A&Object&M implements self::I {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&M = core::Object with self::M {
}
class B extends self::_B&Object&M implements self::I {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect
index 7463788..5d8ddf7 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect
@@ -8,7 +8,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class M extends core::Object {
synthetic constructor •() → void
@@ -23,7 +24,8 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&M = core::Object with self::M {
}
@@ -31,6 +33,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect
index 49caf94..eb2d0a0 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect
@@ -8,7 +8,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class M extends core::Object {
synthetic constructor •() → void
@@ -28,7 +29,8 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&M extends core::Object implements self::M {
synthetic constructor •() → void
@@ -41,6 +43,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect
index aeadca5..0283bae 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect
@@ -14,7 +14,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&A = core::Object with self::A {
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect
index f43923a..bf046d8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect
@@ -14,7 +14,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&A extends core::Object implements self::A {
synthetic constructor •() → void
@@ -22,7 +23,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class B extends self::_B&Object&A {
synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect
index 71c513d..63d5358 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect
@@ -12,7 +12,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&A = core::Object with self::A {
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect
index aeadca5..0283bae 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect
@@ -14,7 +14,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&A = core::Object with self::A {
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect
index f43923a..bf046d8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect
@@ -14,7 +14,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
abstract class _B&Object&A extends core::Object implements self::A {
synthetic constructor •() → void
@@ -22,7 +23,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
return null;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class B extends self::_B&Object&A {
synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect
@@ -13,6 +13,7 @@
synthetic constructor •() → void
: super self::M::•()
;
- abstract no-such-method-forwarder method call(core::String s) → void;
+ no-such-method-forwarder method call(core::String s) → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect
@@ -13,6 +13,7 @@
synthetic constructor •() → void
: super self::M::•()
;
- abstract no-such-method-forwarder method call(core::String s) → void;
+ no-such-method-forwarder method call(core::String s) → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect
index 6fdc38e..b0427dc 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect
@@ -11,7 +11,8 @@
class A extends self::M {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method call(core::String s) → void;
+ no-such-method-forwarder method call(core::String s) → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect
@@ -13,6 +13,7 @@
synthetic constructor •() → void
: super self::M::•()
;
- abstract no-such-method-forwarder method call(core::String s) → void;
+ no-such-method-forwarder method call(core::String s) → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect
@@ -13,6 +13,7 @@
synthetic constructor •() → void
: super self::M::•()
;
- abstract no-such-method-forwarder method call(core::String s) → void;
+ no-such-method-forwarder method call(core::String s) → void
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect
index 82b4b89..012c9be 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect
@@ -16,6 +16,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect
index 224585c..5b1b182 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect
@@ -22,6 +22,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect
index 6e0c11e..3a59956 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect
@@ -13,7 +13,8 @@
class B extends self::_B&Object&A {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect
index 82b4b89..012c9be 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect
@@ -16,6 +16,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect
index 224585c..5b1b182 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect
@@ -22,6 +22,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect
index 937b5a6..125b323 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect
@@ -14,7 +14,8 @@
synthetic constructor •() → void
: super self::Foo::•()
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class Baz extends self::Foo implements pri::Fisk {
synthetic constructor •() → void
@@ -22,6 +23,7 @@
;
method _hest() → dynamic
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect
index 937b5a6..125b323 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect
@@ -14,7 +14,8 @@
synthetic constructor •() → void
: super self::Foo::•()
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class Baz extends self::Foo implements pri::Fisk {
synthetic constructor •() → void
@@ -22,6 +23,7 @@
;
method _hest() → dynamic
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
index 1817793..36ff954 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
@@ -12,14 +12,16 @@
class Bar extends self::Foo implements pri::Fisk {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class Baz extends self::Foo implements pri::Fisk {
synthetic constructor •() → void
;
method _hest() → dynamic
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
index 937b5a6..125b323 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
@@ -14,7 +14,8 @@
synthetic constructor •() → void
: super self::Foo::•()
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class Baz extends self::Foo implements pri::Fisk {
synthetic constructor •() → void
@@ -22,6 +23,7 @@
;
method _hest() → dynamic
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
index 937b5a6..125b323 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
@@ -14,7 +14,8 @@
synthetic constructor •() → void
: super self::Foo::•()
;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
class Baz extends self::Foo implements pri::Fisk {
synthetic constructor •() → void
@@ -22,6 +23,7 @@
;
method _hest() → dynamic
return null;
- abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+ no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+ return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect
@@ -14,6 +14,7 @@
;
method noSuchMethod(core::Invocation invocation) → dynamic
return null;
- abstract no-such-method-forwarder method _foo() → void;
+ no-such-method-forwarder method _foo() → void
+ return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect
@@ -14,6 +14,7 @@
;
method noSuchMethod(core::Invocation invocation) → dynamic
return null;
- abstract no-such-method-forwarder method _foo() → void;
+ no-such-method-forwarder method _foo() → void
+ return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect
index 8dc462e..e8cddd1 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect
@@ -12,7 +12,8 @@
;
method noSuchMethod(core::Invocation invocation) → dynamic
;
- abstract no-such-method-forwarder method _foo() → void;
+ no-such-method-forwarder method _foo() → void
+ return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect
@@ -14,6 +14,7 @@
;
method noSuchMethod(core::Invocation invocation) → dynamic
return null;
- abstract no-such-method-forwarder method _foo() → void;
+ no-such-method-forwarder method _foo() → void
+ return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect
@@ -14,6 +14,7 @@
;
method noSuchMethod(core::Invocation invocation) → dynamic
return null;
- abstract no-such-method-forwarder method _foo() → void;
+ no-such-method-forwarder method _foo() → void
+ return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect
@@ -9,6 +9,7 @@
method noSuchMethod(core::Invocation i) → dynamic {
return null;
}
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect
@@ -9,6 +9,7 @@
method noSuchMethod(core::Invocation i) → dynamic {
return null;
}
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect
index ef9c2e6..279022d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect
@@ -7,7 +7,8 @@
;
method noSuchMethod(core::Invocation i) → dynamic
;
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect
@@ -9,6 +9,7 @@
method noSuchMethod(core::Invocation i) → dynamic {
return null;
}
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect
@@ -9,6 +9,7 @@
method noSuchMethod(core::Invocation i) → dynamic {
return null;
}
- abstract no-such-method-forwarder method foo() → void;
+ no-such-method-forwarder method foo() → void
+ return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
index 4ff7688..4ae2d71 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
@@ -22,6 +22,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → core::int;
+ no-such-method-forwarder method foo() → core::int
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
index 01d96cb..198f601 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
@@ -28,6 +28,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → core::int;
+ no-such-method-forwarder method foo() → core::int
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
index 7e40698..5d00e53 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
@@ -18,7 +18,8 @@
class A extends self::_A&Object&M implements self::I<core::int> {
synthetic constructor •() → void
;
- abstract no-such-method-forwarder method foo() → core::int;
+ no-such-method-forwarder method foo() → core::int
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
index 4ff7688..4ae2d71 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
@@ -22,6 +22,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → core::int;
+ no-such-method-forwarder method foo() → core::int
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
index 01d96cb..198f601 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
@@ -28,6 +28,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract no-such-method-forwarder method foo() → core::int;
+ no-such-method-forwarder method foo() → core::int
+ return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect
index c4f7d99..ad208b6 100644
--- a/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect
@@ -3,7 +3,9 @@
import "dart:core" as core;
static method main() → dynamic {
- for (final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/issue_000042.dart:6:8: Error: Expected lvalue, but got [x, y]\n for (var x, y in []) {}\n ^" in <dynamic>[]) {
+ for (final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/issue_000042.dart:6:8: Error: A for-loop can't have more than one loop variable.
+ for (var x, y in []) {}
+ ^^^" in <dynamic>[]) {
}
#L1:
{
diff --git a/pkg/front_end/testcases/rasta/static.dart.direct.expect b/pkg/front_end/testcases/rasta/static.dart.direct.expect
index e047d82..2154f49 100644
--- a/pkg/front_end/testcases/rasta/static.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.direct.expect
@@ -29,24 +29,24 @@
self::use(self::Foo::staticGetter);
throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
self::use(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[#t1.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t1.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
self::Foo::staticField = self::Foo::staticField.+(1);
self::use(let final dynamic #t3 = self::Foo::staticField in let final dynamic #t4 = self::Foo::staticField = #t3.+(1) in #t3);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[#t5.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[#t7.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t5.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
self::use(let final dynamic #t9 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in let final dynamic #t10 = self::Foo::staticSetter = #t9.+(1) in #t9);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticField = self::Foo::staticField.+(1);
self::use(self::Foo::staticField = self::Foo::staticField.+(1));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
self::use(self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1));
self::Foo::staticConstant.call();
@@ -59,24 +59,24 @@
self::use(self::Foo::staticGetter.call());
(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call();
self::use((throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call());
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticField = 87;
self::use(self::Foo::staticField = 87);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticSetter = 87;
self::use(self::Foo::staticSetter = 87);
- self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
- self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
+ self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+ self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
self::Foo::staticField.==(null) ? self::Foo::staticField = 87 : null;
self::use(let final dynamic #t12 = self::Foo::staticField in #t12.==(null) ? self::Foo::staticField = 87 : #t12);
- self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
- self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
- self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
- self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
+ self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+ self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
+ self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+ self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).==(null) ? self::Foo::staticSetter = 87 : null;
self::use(let final dynamic #t15 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t15.==(null) ? self::Foo::staticSetter = 87 : #t15);
}
diff --git a/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
index e047d82..2154f49 100644
--- a/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
@@ -29,24 +29,24 @@
self::use(self::Foo::staticGetter);
throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
self::use(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[#t1.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t1.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
self::Foo::staticField = self::Foo::staticField.+(1);
self::use(let final dynamic #t3 = self::Foo::staticField in let final dynamic #t4 = self::Foo::staticField = #t3.+(1) in #t3);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[#t5.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[#t7.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t5.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
self::use(let final dynamic #t9 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in let final dynamic #t10 = self::Foo::staticSetter = #t9.+(1) in #t9);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticField = self::Foo::staticField.+(1);
self::use(self::Foo::staticField = self::Foo::staticField.+(1));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
self::use(self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1));
self::Foo::staticConstant.call();
@@ -59,24 +59,24 @@
self::use(self::Foo::staticGetter.call());
(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call();
self::use((throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call());
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticField = 87;
self::use(self::Foo::staticField = 87);
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
self::Foo::staticSetter = 87;
self::use(self::Foo::staticSetter = 87);
- self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
- self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
+ self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+ self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
self::Foo::staticField.==(null) ? self::Foo::staticField = 87 : null;
self::use(let final dynamic #t12 = self::Foo::staticField in #t12.==(null) ? self::Foo::staticField = 87 : #t12);
- self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
- self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
- self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
- self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
+ self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+ self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
+ self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+ self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).==(null) ? self::Foo::staticSetter = 87 : null;
self::use(let final dynamic #t15 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t15.==(null) ? self::Foo::staticSetter = 87 : #t15);
}
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
index 9a7f7e0..09a7e0c 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
@@ -13,19 +13,19 @@
core::print(this.key);
}
for (final dynamic #t2 in x) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+ for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Can't assign to this, so it can't be used in a for-in loop.
for (collection in x) {
- ^" in x) {
+ ^^^^^^^^^^" in x) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
}
for (final dynamic #t4 in x) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t4].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t4]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(() → void);
}
- for (final dynamic #t5 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected lvalue, but got 1
+ for (final dynamic #t5 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
for (1 in x) {
^" in x) {
core::print(this.key);
@@ -40,23 +40,23 @@
static method main(dynamic arguments) → dynamic {
new self::Fisk::•();
for (final dynamic #t6 in arguments) {
- throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], <dynamic>[#t6].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t6]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
}
for (final dynamic #t7 in arguments) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t7].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+ for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Can't assign to this, so it can't be used in a for-in loop.
for (collection in arguments) {
- ^" in arguments) {
+ ^^^^^^^^^^" in arguments) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
}
for (final dynamic #t9 in arguments) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t9].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t9]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(() → void);
}
- for (final dynamic #t10 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected lvalue, but got 1
+ for (final dynamic #t10 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
for (1 in arguments) {
^" in arguments) {
core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
index 9a7f7e0..09a7e0c 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
@@ -13,19 +13,19 @@
core::print(this.key);
}
for (final dynamic #t2 in x) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+ for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Can't assign to this, so it can't be used in a for-in loop.
for (collection in x) {
- ^" in x) {
+ ^^^^^^^^^^" in x) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
}
for (final dynamic #t4 in x) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t4].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t4]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(() → void);
}
- for (final dynamic #t5 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected lvalue, but got 1
+ for (final dynamic #t5 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
for (1 in x) {
^" in x) {
core::print(this.key);
@@ -40,23 +40,23 @@
static method main(dynamic arguments) → dynamic {
new self::Fisk::•();
for (final dynamic #t6 in arguments) {
- throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], <dynamic>[#t6].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t6]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
}
for (final dynamic #t7 in arguments) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t7].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+ for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Can't assign to this, so it can't be used in a for-in loop.
for (collection in arguments) {
- ^" in arguments) {
+ ^^^^^^^^^^" in arguments) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
}
for (final dynamic #t9 in arguments) {
- let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t9].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t9]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(() → void);
}
- for (final dynamic #t10 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected lvalue, but got 1
+ for (final dynamic #t10 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
for (1 in arguments) {
^" in arguments) {
core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
index 0161677..be6f8dc 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
@@ -22,6 +22,6 @@
new self::A::•().foo();
new self::A::•().foo(1, 2);
new self::A::foo();
- throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[1, 2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
index 0161677..be6f8dc 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
@@ -22,6 +22,6 @@
new self::A::•().foo();
new self::A::•().foo(1, 2);
new self::A::foo();
- throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[1, 2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
index 680a6d3..be7bde0 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
@@ -26,6 +26,6 @@
new self::A::•().{self::A::foo}();
new self::A::•().{self::A::foo}(1, 2);
new self::A::foo();
- throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[1, 2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
index 33b060d..494d91f 100644
--- a/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
@@ -10,11 +10,11 @@
return null;
}
static method main() → dynamic {
- function bar<T extends self::A = dynamic>(T t) → void {
+ function bar<T extends self::A = self::A>(T t) → void {
core::print("t.foo()=${t.{self::A::foo}()}");
}
bar.call<self::A>(new self::A::•());
- (<S extends self::A = dynamic>(S s) → core::Null {
+ (<S extends self::A = self::A>(S s) → core::Null {
core::print("s.foo()=${s.{self::A::foo}()}");
}).call<self::A>(new self::A::•());
}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
index 33b060d..494d91f 100644
--- a/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
@@ -10,11 +10,11 @@
return null;
}
static method main() → dynamic {
- function bar<T extends self::A = dynamic>(T t) → void {
+ function bar<T extends self::A = self::A>(T t) → void {
core::print("t.foo()=${t.{self::A::foo}()}");
}
bar.call<self::A>(new self::A::•());
- (<S extends self::A = dynamic>(S s) → core::Null {
+ (<S extends self::A = self::A>(S s) → core::Null {
core::print("s.foo()=${s.{self::A::foo}()}");
}).call<self::A>(new self::A::•());
}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect
index fc1a7b3..6f08277 100644
--- a/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect
@@ -5,6 +5,6 @@
static method main() → dynamic {
core::print(self::main is () → dynamic);
core::print((<T extends core::Object = dynamic>(T x) → T => x).{core::Object::runtimeType});
- core::print((<T extends core::num = dynamic>(T x) → T => x).{core::Object::runtimeType});
- core::print((<T extends core::Comparable<T> = dynamic>(T x) → T => x).{core::Object::runtimeType});
+ core::print((<T extends core::num = core::num>(T x) → T => x).{core::Object::runtimeType});
+ core::print((<T extends core::Comparable<T> = core::Comparable<dynamic>>(T x) → T => x).{core::Object::runtimeType});
}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
index fc1a7b3..6f08277 100644
--- a/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
@@ -5,6 +5,6 @@
static method main() → dynamic {
core::print(self::main is () → dynamic);
core::print((<T extends core::Object = dynamic>(T x) → T => x).{core::Object::runtimeType});
- core::print((<T extends core::num = dynamic>(T x) → T => x).{core::Object::runtimeType});
- core::print((<T extends core::Comparable<T> = dynamic>(T x) → T => x).{core::Object::runtimeType});
+ core::print((<T extends core::num = core::num>(T x) → T => x).{core::Object::runtimeType});
+ core::print((<T extends core::Comparable<T> = core::Comparable<dynamic>>(T x) → T => x).{core::Object::runtimeType});
}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
index 9ca2a67..798b35d 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method f<U extends (self::C::T) → void = dynamic>(self::C::f::U x) → void {}
+ method f<U extends (self::C::T) → void = (self::C::T) → void>(self::C::f::U x) → void {}
}
static method g(self::C<core::num> c) → void {
c.{self::C::f}<(core::Object) → void>((core::Object o) → core::Null {});
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
index 9ca2a67..798b35d 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method f<U extends (self::C::T) → void = dynamic>(self::C::f::U x) → void {}
+ method f<U extends (self::C::T) → void = (self::C::T) → void>(self::C::f::U x) → void {}
}
static method g(self::C<core::num> c) → void {
c.{self::C::f}<(core::Object) → void>((core::Object o) → core::Null {});
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
index b8a0214..8427437 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
@@ -6,8 +6,8 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
- method g1<generic-covariant-impl U extends self::C::T = dynamic>() → void {
+ method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
+ method g1<generic-covariant-impl U extends self::C::T = self::C::T>() → void {
this.{self::C::f}<self::C::g1::U>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'test::C::g1::U'.
Try changing the type of the left hand side, or casting the right hand side to 'test::C::g1::U'.
this.f<U>(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
index 91a46da..b595fdf 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -6,8 +6,8 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
- method g1<generic-covariant-impl U extends self::C::T = dynamic>() → void {
+ method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
+ method g1<generic-covariant-impl U extends self::C::T = self::C::T>() → void {
this.{self::C::f}<self::C::g1::U>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'test::C::g1::U'.
Try changing the type of the left hand side, or casting the right hand side to 'test::C::g1::U'.
this.f<U>(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect
index bddd915..f5a72bc 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
+ method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
}
static method g1(dynamic d) → void {
d.f<core::num>(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
index bddd915..f5a72bc 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
+ method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
}
static method g1(dynamic d) → void {
d.f<core::num>(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect
index 89abbed..452359a 100644
--- a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect
@@ -8,7 +8,7 @@
;
method f(generic-covariant-impl self::B::T x) → void {}
method g({generic-covariant-impl self::B::T x = null}) → void {}
- method h<generic-covariant-impl U extends self::B::T = dynamic>() → void {}
+ method h<generic-covariant-impl U extends self::B::T = self::B::T>() → void {}
}
class C extends self::B<core::int> {
synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
index 89abbed..452359a 100644
--- a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
;
method f(generic-covariant-impl self::B::T x) → void {}
method g({generic-covariant-impl self::B::T x = null}) → void {}
- method h<generic-covariant-impl U extends self::B::T = dynamic>() → void {}
+ method h<generic-covariant-impl U extends self::B::T = self::B::T>() → void {}
}
class C extends self::B<core::int> {
synthetic constructor •() → void
diff --git a/pkg/front_end/tool/_fasta/additional_targets.dart b/pkg/front_end/tool/_fasta/additional_targets.dart
new file mode 100644
index 0000000..dd9a0a3
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/additional_targets.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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 fasta.tool.additional_targets;
+
+import 'package:kernel/target/targets.dart' show TargetFlags, targets;
+
+import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
+
+import 'package:vm/target/dart_runner.dart' show DartRunnerTarget;
+
+import 'package:vm/target/flutter_runner.dart' show FlutterRunnerTarget;
+
+void installAdditionalTargets() {
+ // If you add new targets here, please also update FastaUsageLong in
+ // ../../messages.yaml.
+ targets["dart2js"] =
+ (TargetFlags flags) => new Dart2jsTarget("dart2js", flags);
+ targets["dart2js_server"] =
+ (TargetFlags flags) => new Dart2jsTarget("dart2js_server", flags);
+ targets["dart_runner"] = (TargetFlags flags) => new DartRunnerTarget(flags);
+ targets["flutter_runner"] =
+ (TargetFlags flags) => new FlutterRunnerTarget(flags);
+}
diff --git a/pkg/front_end/tool/_fasta/additional_targets_test.dart b/pkg/front_end/tool/_fasta/additional_targets_test.dart
new file mode 100644
index 0000000..041a363
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/additional_targets_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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 fasta.tool.additional_targets_test;
+
+import 'package:kernel/target/targets.dart' show targets;
+
+import 'package:front_end/src/fasta/fasta_codes.dart'
+ show MessageCode, messageFastaUsageLong;
+
+import 'additional_targets.dart' show installAdditionalTargets;
+
+main() {
+ installAdditionalTargets();
+ String expected = " --target=${(targets.keys.toList()..sort()).join('|')}";
+ MessageCode code = messageFastaUsageLong;
+ if (!code.message.contains(expected)) {
+ throw "Error: ${code.name} in pkg/front_end/messages.yaml doesn't contain"
+ " '$expected'.";
+ }
+}
diff --git a/pkg/front_end/tool/_fasta/compile_platform.dart b/pkg/front_end/tool/_fasta/compile_platform.dart
index 58cd0ce..52afecd 100644
--- a/pkg/front_end/tool/_fasta/compile_platform.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform.dart
@@ -8,17 +8,9 @@
import 'dart:io' show File, Platform, exitCode;
-import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
-
import 'package:vm/bytecode/gen_bytecode.dart'
show generateBytecode, isKernelBytecodeEnabledForPlatform;
-import 'package:vm/target/dart_runner.dart' show DartRunnerTarget;
-
-import 'package:vm/target/flutter_runner.dart' show FlutterRunnerTarget;
-
-import 'package:kernel/target/targets.dart' show TargetFlags, targets;
-
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/fasta/deprecated_problems.dart'
@@ -36,18 +28,14 @@
import 'package:front_end/src/fasta/get_dependencies.dart' show getDependencies;
+import 'additional_targets.dart' show installAdditionalTargets;
+
import 'command_line.dart' show withGlobalOptions;
const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
Future main(List<String> arguments) async {
- targets["dart2js"] =
- (TargetFlags flags) => new Dart2jsTarget("dart2js", flags);
- targets["dart2js_server"] =
- (TargetFlags flags) => new Dart2jsTarget("dart2js_server", flags);
- targets["dart_runner"] = (TargetFlags flags) => new DartRunnerTarget(flags);
- targets["flutter_runner"] =
- (TargetFlags flags) => new FlutterRunnerTarget(flags);
+ installAdditionalTargets();
for (int i = 0; i < iterations; i++) {
if (i > 0) {
print("\n");
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 1586b35..a8b6a15 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -10,13 +10,9 @@
import 'dart:io' show File, exitCode, stderr, stdin, stdout;
-import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
-
import 'package:kernel/kernel.dart'
show CanonicalName, Library, Component, Source, loadComponentFromBytes;
-import 'package:kernel/target/targets.dart' show TargetFlags, targets;
-
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions;
@@ -42,6 +38,8 @@
import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
+import 'additional_targets.dart' show installAdditionalTargets;
+
import 'command_line.dart' show withGlobalOptions;
const bool summary = const bool.fromEnvironment("summary", defaultValue: false);
@@ -49,10 +47,7 @@
const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
compileEntryPoint(List<String> arguments) async {
- targets["dart2js"] =
- (TargetFlags flags) => new Dart2jsTarget("dart2js", flags);
- targets["dart2js_server"] =
- (TargetFlags flags) => new Dart2jsTarget("dart2js_server", flags);
+ installAdditionalTargets();
// Timing results for each iteration
List<double> elapsedTimes = <double>[];
@@ -75,6 +70,8 @@
}
outlineEntryPoint(List<String> arguments) async {
+ installAdditionalTargets();
+
for (int i = 0; i < iterations; i++) {
if (i > 0) {
print("\n");
@@ -84,6 +81,8 @@
}
batchEntryPoint(List<String> arguments) {
+ installAdditionalTargets();
+
return new BatchCompiler(
stdin.transform(utf8.decoder).transform(new LineSplitter()))
.run();
diff --git a/pkg/front_end/tool/_fasta/generate_messages.dart b/pkg/front_end/tool/_fasta/generate_messages.dart
index 0ec9a18..397bded 100644
--- a/pkg/front_end/tool/_fasta/generate_messages.dart
+++ b/pkg/front_end/tool/_fasta/generate_messages.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:async';
+
import 'dart:io';
import 'dart:isolate';
@@ -14,6 +16,17 @@
main(List<String> arguments) async {
var port = new ReceivePort();
+ await new File.fromUri(await computeGeneratedFile())
+ .writeAsString(await generateMessagesFile(), flush: true);
+ port.close();
+}
+
+Future<Uri> computeGeneratedFile() {
+ return Isolate.resolvePackageUri(
+ Uri.parse('package:front_end/src/fasta/fasta_codes_generated.dart'));
+}
+
+Future<String> generateMessagesFile() async {
Uri messagesFile = Platform.script.resolve("../../messages.yaml");
Map yaml = loadYaml(await new File.fromUri(messagesFile).readAsStringSync());
StringBuffer sb = new StringBuffer();
@@ -45,13 +58,7 @@
map['analyzerCode'], map['dart2jsCode'], map['severity']));
}
- String dartfmtedText = new DartFormatter().format("$sb");
-
- Uri problemsFile = await Isolate.resolvePackageUri(
- Uri.parse('package:front_end/src/fasta/fasta_codes_generated.dart'));
- await new File.fromUri(problemsFile)
- .writeAsString(dartfmtedText, flush: true);
- port.close();
+ return new DartFormatter().format("$sb");
}
final RegExp placeholderPattern = new RegExp("#[a-zA-Z0-9_]+");
@@ -172,6 +179,11 @@
arguments.add("'count2': count2");
break;
+ case "#constant":
+ parameters.add("Constant constant");
+ arguments.add("'constant': constant");
+ break;
+
default:
throw "Unhandled placeholder in template: ${match[0]}";
}
diff --git a/pkg/front_end/tool/_fasta/generate_messages_test.dart b/pkg/front_end/tool/_fasta/generate_messages_test.dart
new file mode 100644
index 0000000..f242f01
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/generate_messages_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io" show File;
+
+import "package:async_helper/async_helper.dart" show asyncTest;
+
+import "package:expect/expect.dart" show Expect;
+
+import "generate_messages.dart" show computeGeneratedFile, generateMessagesFile;
+
+main() {
+ asyncTest(() async {
+ Uri generatedFile = await computeGeneratedFile();
+ String generated = await generateMessagesFile();
+ String actual = await new File.fromUri(generatedFile).readAsString();
+ Expect.stringEquals(
+ generated, actual, "${generatedFile.path} is out of date");
+ });
+}
diff --git a/pkg/kernel/README.md b/pkg/kernel/README.md
index fd48574..778bcc7 100644
--- a/pkg/kernel/README.md
+++ b/pkg/kernel/README.md
@@ -15,7 +15,9 @@
- Serialization of kernel code
_Note:_ The APIs in this package are in an early state; developers should be
-careful about depending on this package.
+careful about depending on this package. In particular, there is no semver
+contract for release versions of this package. Please depend directly
+on individual versions.
Getting Kernel
------------
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index 1898ede..ae16bda 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -12,7 +12,6 @@
import 'package:kernel/kernel.dart';
import 'package:kernel/src/tool/batch_util.dart';
import 'package:kernel/target/targets.dart';
-import 'package:kernel/transformations/closure_conversion.dart' as closures;
import 'package:kernel/transformations/constants.dart' as constants;
import 'package:kernel/transformations/continuation.dart' as cont;
import 'package:kernel/transformations/empty.dart' as empty;
@@ -94,9 +93,6 @@
mix.transformLibraries(
new NoneTarget(null), coreTypes, hierarchy, component.libraries);
break;
- case 'closures':
- component = closures.transformComponent(coreTypes, component);
- break;
case 'coq':
component = coq.transformComponent(coreTypes, component);
break;
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 7bb45af..13b28bf 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -131,11 +131,11 @@
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
- UInt32 formatVersion;
- MetadataPayload[] metadataPayloads;
+ UInt32 formatVersion = 6;
Library[] libraries;
UriSource sourceMap;
List<CanonicalName> canonicalNames;
+ MetadataPayload[] metadataPayloads;
RList<MetadataMapping> metadataMappings;
StringTable strings;
List<Constant> constants;
@@ -149,9 +149,8 @@
type MetadataMapping {
UInt32 tag; // StringReference of a fixed size.
+ // Node offsets are absolute, while metadata offsets are relative to metadataPayloads.
RList<Pair<UInt32, UInt32>> nodeOffsetToMetadataOffset;
- RList<UInt32> nodeReferences; // If metadata payload references nodes
- // they are encoded as indices in this array.
}
// Component index with all fixed-size-32-bit integers.
@@ -162,6 +161,8 @@
type ComponentIndex {
UInt32 binaryOffsetForSourceTable;
UInt32 binaryOffsetForCanonicalNames;
+ UInt32 binaryOffsetForMetadataPayloads;
+ UInt32 binaryOffsetForMetadataMappings;
UInt32 binaryOffsetForStringTable;
UInt32 binaryOffsetForConstantTable;
UInt32 mainMethodReference; // This is a ProcedureReference with a fixed-size integer.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index a87b1b4..7ff892f 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1575,7 +1575,6 @@
}
void set isNoSuchMethodForwarder(bool value) {
- assert(isAbstract);
flags = value
? (flags | FlagNoSuchMethodForwarder)
: (flags & ~FlagNoSuchMethodForwarder);
@@ -2565,6 +2564,17 @@
positional = <Expression>[],
named = <NamedExpression>[];
+ factory Arguments.forwarded(FunctionNode function) {
+ return new Arguments(
+ function.positionalParameters.map((p) => new VariableGet(p)).toList(),
+ named: function.namedParameters
+ .map((p) => new NamedExpression(p.name, new VariableGet(p)))
+ .toList(),
+ types: function.typeParameters
+ .map((p) => new TypeParameterType(p))
+ .toList());
+ }
+
accept(TreeVisitor v) => v.visitArguments(this);
visitChildren(Visitor v) {
@@ -5527,14 +5537,28 @@
/// Mutable mapping between nodes and their metadata.
Map<TreeNode, T> get mapping;
- /// Write the given metadata object into the given [BinarySink].
+ /// Write [metadata] object corresponding to the given [Node] into
+ /// the given [BinarySink].
///
- /// Note: [metadata] must be an object owned by this repository.
- void writeToBinary(T metadata, BinarySink sink);
+ /// Metadata is serialized immediately before serializing [node],
+ /// so implementation of this method can use serialization context of
+ /// [node]'s parents (such as declared type parameters and variables).
+ /// In order to use scope declared by the [node] itself, implementation of
+ /// this method can use [BinarySink.enterScope] and [BinarySink.leaveScope]
+ /// methods.
+ ///
+ /// [metadata] must be an object owned by this repository.
+ void writeToBinary(T metadata, Node node, BinarySink sink);
/// Construct a metadata object from its binary payload read from the
/// given [BinarySource].
- T readFromBinary(BinarySource source);
+ ///
+ /// Metadata is deserialized immediately after deserializing [node],
+ /// so it can use deserialization context of [node]'s parents.
+ /// In order to use scope declared by the [node] itself, implementation of
+ /// this method can use [BinarySource.enterScope] and
+ /// [BinarySource.leaveScope] methods.
+ T readFromBinary(Node node, BinarySource source);
/// Method to check whether a node can have metadata attached to it
/// or referenced from the metadata payload.
@@ -5557,12 +5581,17 @@
void writeCanonicalNameReference(CanonicalName name);
void writeStringReference(String str);
+ void writeDartType(DartType type);
+ void writeNode(Node node);
- /// Write a reference to a given node into the sink.
- ///
- /// Note: node must not be [MapEntry] because [MapEntry] and [MapEntry.key]
- /// have the same offset in the binary and can't be distinguished.
- void writeNodeReference(Node node);
+ void enterScope(
+ {List<TypeParameter> typeParameters,
+ bool memberScope: false,
+ bool variableScope: false});
+ void leaveScope(
+ {List<TypeParameter> typeParameters,
+ bool memberScope: false,
+ bool variableScope: false});
}
abstract class BinarySource {
@@ -5578,7 +5607,11 @@
CanonicalName readCanonicalNameReference();
String readStringReference();
- Node readNodeReference();
+ DartType readDartType();
+ FunctionNode readFunctionNode();
+
+ void enterScope({List<TypeParameter> typeParameters});
+ void leaveScope({List<TypeParameter> typeParameters});
}
// ------------------------------------------------------------------------
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 4ff4a37..0b8053d 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -23,9 +23,13 @@
}
class _ComponentIndex {
+ static const numberOfFixedFields = 9;
+
int binaryOffsetForSourceTable;
- int binaryOffsetForStringTable;
int binaryOffsetForCanonicalNames;
+ int binaryOffsetForMetadataPayloads;
+ int binaryOffsetForMetadataMappings;
+ int binaryOffsetForStringTable;
int binaryOffsetForConstantTable;
int mainMethodReference;
List<int> libraryOffsets;
@@ -141,19 +145,16 @@
return string;
}
- /// Read metadataMappings section from the binary. Return [true] if
- /// any metadata mapping contains metadata with node references.
- /// In this case we need to disable lazy loading of the binary.
- bool _readMetadataSection(Component component) {
+ /// Read metadataMappings section from the binary.
+ void _readMetadataMappings(
+ Component component, int binaryOffsetForMetadataPayloads) {
// Default reader ignores metadata section entirely.
- return false;
}
- /// Process any pending metadata associations. Called once the Component
- /// is fully deserialized and metadata containing references to nodes can
- /// be safely parsed.
- void _processPendingMetadataAssociations(Component component) {
+ /// Reads metadata for the given [node].
+ Node _associateMetadata(Node node, int nodeOffset) {
// Default reader ignores metadata section entirely.
+ return node;
}
void readStringTable(List<String> table) {
@@ -401,6 +402,22 @@
}
}
+ /// Deserializes the source and stores it in [component].
+ ///
+ /// The input bytes may contain multiple files concatenated.
+ void readComponentSource(Component component) {
+ List<int> componentFileSizes = _indexComponents();
+ if (componentFileSizes.length > 1) {
+ _disableLazyReading = true;
+ }
+ int componentFileIndex = 0;
+ while (_byteOffset < _bytes.length) {
+ _readOneComponentSource(
+ component, componentFileSizes[componentFileIndex]);
+ ++componentFileIndex;
+ }
+ }
+
/// Reads a single component file from the input and loads it into [component],
/// overwriting and reusing any existing data in the component.
///
@@ -445,14 +462,16 @@
}
// Skip to the start of the index.
- // There are these fields: file size, library count, library count + 1
- // offsets, main reference, string table offset, canonical name offset and
- // source table offset. That's 6 fields + number of libraries.
- _byteOffset -= (result.libraryCount + 8) * 4;
+ _byteOffset -=
+ ((result.libraryCount + 1) + _ComponentIndex.numberOfFixedFields) * 4;
// Now read the component index.
result.binaryOffsetForSourceTable = _componentStartOffset + readUint32();
result.binaryOffsetForCanonicalNames = _componentStartOffset + readUint32();
+ result.binaryOffsetForMetadataPayloads =
+ _componentStartOffset + readUint32();
+ result.binaryOffsetForMetadataMappings =
+ _componentStartOffset + readUint32();
result.binaryOffsetForStringTable = _componentStartOffset + readUint32();
result.binaryOffsetForConstantTable = _componentStartOffset + readUint32();
result.mainMethodReference = readUint32();
@@ -465,6 +484,31 @@
return result;
}
+ void _readOneComponentSource(Component component, int componentFileSize) {
+ _componentStartOffset = _byteOffset;
+
+ final int magic = readUint32();
+ if (magic != Tag.ComponentFile) {
+ throw fail('This is not a binary dart file. '
+ 'Magic number was: ${magic.toRadixString(16)}');
+ }
+
+ final int formatVersion = readUint32();
+ if (formatVersion != Tag.BinaryFormatVersion) {
+ throw fail('Invalid kernel binary format version '
+ '(found ${formatVersion}, expected ${Tag.BinaryFormatVersion})');
+ }
+
+ // Read component index from the end of this ComponentFiles serialized data.
+ _ComponentIndex index = _readComponentIndex(componentFileSize);
+
+ _byteOffset = index.binaryOffsetForSourceTable;
+ Map<Uri, Source> uriToSource = readUriToSource();
+ component.uriToSource.addAll(uriToSource);
+
+ _byteOffset = _componentStartOffset + componentFileSize;
+ }
+
void _readOneComponent(Component component, int componentFileSize) {
_componentStartOffset = _byteOffset;
@@ -489,9 +533,9 @@
_byteOffset = index.binaryOffsetForCanonicalNames;
readLinkTable(component.root);
- _byteOffset = index.binaryOffsetForStringTable;
- _disableLazyReading =
- _readMetadataSection(component) || _disableLazyReading;
+ // TODO(alexmarkov): reverse metadata mappings and read forwards
+ _byteOffset = index.binaryOffsetForStringTable; // Read backwards.
+ _readMetadataMappings(component, index.binaryOffsetForMetadataPayloads);
_byteOffset = index.binaryOffsetForSourceTable;
Map<Uri, Source> uriToSource = readUriToSource();
@@ -510,7 +554,7 @@
getMemberReferenceFromInt(index.mainMethodReference, allowNull: true);
component.mainMethodName ??= mainMethod;
- _processPendingMetadataAssociations(component);
+ _associateMetadata(component, _componentStartOffset);
_byteOffset = _componentStartOffset + componentFileSize;
}
@@ -523,7 +567,9 @@
Map<Uri, Source> uriToSource = <Uri, Source>{};
for (int i = 0; i < length; ++i) {
List<int> uriBytes = readByteList();
- Uri uri = Uri.parse(const Utf8Decoder().convert(uriBytes));
+ Uri uri = uriBytes.isEmpty
+ ? null
+ : Uri.parse(const Utf8Decoder().convert(uriBytes));
_sourceUriTable[i] = uri;
List<int> sourceCode = readByteList();
int lineCount = readUInt();
@@ -918,7 +964,7 @@
debugPath.add(node.name?.name ?? 'constructor');
return true;
}());
- var function = readFunctionNode(false, -1);
+ var function = readFunctionNode();
pushVariableDeclarations(function.positionalParameters);
pushVariableDeclarations(function.namedParameters);
if (shouldWriteData) {
@@ -1075,11 +1121,13 @@
FunctionNode readFunctionNodeOption(bool lazyLoadBody, int outerEndOffset) {
return readAndCheckOptionTag()
- ? readFunctionNode(lazyLoadBody, outerEndOffset)
+ ? readFunctionNode(
+ lazyLoadBody: lazyLoadBody, outerEndOffset: outerEndOffset)
: null;
}
- FunctionNode readFunctionNode(bool lazyLoadBody, int outerEndOffset) {
+ FunctionNode readFunctionNode(
+ {bool lazyLoadBody: false, int outerEndOffset: -1}) {
int tag = readByte();
assert(tag == Tag.FunctionNode);
int offset = readOffset();
@@ -1398,8 +1446,7 @@
return new AwaitExpression(readExpression());
case Tag.FunctionExpression:
int offset = readOffset();
- return new FunctionExpression(readFunctionNode(false, -1))
- ..fileOffset = offset;
+ return new FunctionExpression(readFunctionNode())..fileOffset = offset;
case Tag.Let:
var variable = readVariableDeclaration();
int stackHeight = variableStack.length;
@@ -1584,7 +1631,7 @@
int offset = readOffset();
var variable = readVariableDeclaration();
variableStack.add(variable); // Will be popped by the enclosing scope.
- var function = readFunctionNode(false, -1);
+ var function = readFunctionNode();
return new FunctionDeclaration(variable, function)..fileOffset = offset;
default:
throw fail('Invalid statement tag: $tag');
@@ -1845,17 +1892,12 @@
/// and are awaiting to be parsed and attached to nodes.
List<_MetadataSubsection> _subsections;
- /// Current mapping from node references to nodes used by readNodeReference.
- /// Note: each metadata subsection has its own mapping.
- List<Node> _referencedNodes;
-
BinaryBuilderWithMetadata(bytes, [filename])
: super(bytes, filename: filename);
@override
- bool _readMetadataSection(Component component) {
- bool containsNodeReferences = false;
-
+ void _readMetadataMappings(
+ Component component, int binaryOffsetForMetadataPayloads) {
// At the beginning of this function _byteOffset points right past
// metadataMappings to string table.
@@ -1865,15 +1907,10 @@
int endOffset = _byteOffset - 4; // End offset of the current subsection.
for (var i = 0; i < subSectionCount; i++) {
- // RList<UInt32> nodeReferences
- _byteOffset = endOffset - 4;
- final referencesLength = readUint32();
- final referencesStart = (endOffset - 4) - 4 * referencesLength;
-
// RList<Pair<UInt32, UInt32>> nodeOffsetToMetadataOffset
- _byteOffset = referencesStart - 4;
+ _byteOffset = endOffset - 4;
final mappingLength = readUint32();
- final mappingStart = (referencesStart - 4) - 4 * 2 * mappingLength;
+ final mappingStart = (endOffset - 4) - 4 * 2 * mappingLength;
_byteOffset = mappingStart - 4;
// UInt32 tag (fixed size StringReference)
@@ -1881,73 +1918,49 @@
final repository = component.metadata[tag];
if (repository != null) {
- // Read nodeReferences (if any).
- Map<int, int> offsetToReferenceId;
- List<Node> referencedNodes;
- if (referencesLength > 0) {
- offsetToReferenceId = <int, int>{};
- _byteOffset = referencesStart;
- for (var j = 0; j < referencesLength; j++) {
- final nodeOffset = readUint32();
- offsetToReferenceId[nodeOffset] = j;
- }
- referencedNodes =
- new List<Node>.filled(referencesLength, null, growable: true);
- containsNodeReferences = true;
- }
-
// Read nodeOffsetToMetadataOffset mapping.
final mapping = <int, int>{};
_byteOffset = mappingStart;
for (var j = 0; j < mappingLength; j++) {
final nodeOffset = readUint32();
- final metadataOffset = readUint32();
+ final metadataOffset = binaryOffsetForMetadataPayloads + readUint32();
mapping[nodeOffset] = metadataOffset;
}
_subsections ??= <_MetadataSubsection>[];
- _subsections.add(new _MetadataSubsection(
- repository, mapping, offsetToReferenceId, referencedNodes));
+ _subsections.add(new _MetadataSubsection(repository, mapping));
}
// Start of the subsection and the end of the previous one.
endOffset = mappingStart - 4;
}
-
- return containsNodeReferences;
}
- @override
- void _processPendingMetadataAssociations(Component component) {
- if (_subsections == null) {
- return;
- }
-
- _associateMetadata(component, _componentStartOffset);
-
- for (var subsection in _subsections) {
- if (subsection.pending == null) {
- continue;
- }
-
- _referencedNodes = subsection.referencedNodes;
- for (var i = 0; i < subsection.pending.length; i += 2) {
- final Node node = subsection.pending[i];
- final int metadataOffset = subsection.pending[i + 1];
- subsection.repository.mapping[node] =
- _readMetadata(subsection.repository, metadataOffset);
- }
- }
- }
-
- Object _readMetadata(MetadataRepository repository, int offset) {
+ Object _readMetadata(Node node, MetadataRepository repository, int offset) {
final int savedOffset = _byteOffset;
_byteOffset = offset;
- final metadata = repository.readFromBinary(this);
+
+ final metadata = repository.readFromBinary(node, this);
+
_byteOffset = savedOffset;
return metadata;
}
+ @override
+ void enterScope({List<TypeParameter> typeParameters}) {
+ if (typeParameters != null) {
+ typeParameterStack.addAll(typeParameters);
+ }
+ }
+
+ @override
+ void leaveScope({List<TypeParameter> typeParameters}) {
+ if (typeParameters != null) {
+ typeParameterStack.length -= typeParameters.length;
+ }
+ }
+
+ @override
Node _associateMetadata(Node node, int nodeOffset) {
if (_subsections == null) {
return node;
@@ -1957,28 +1970,8 @@
// First check if there is any metadata associated with this node.
final metadataOffset = subsection.mapping[nodeOffset];
if (metadataOffset != null) {
- if (subsection.nodeOffsetToReferenceId == null) {
- // This subsection does not contain any references to nodes from
- // inside the payload. In this case we can deserialize metadata
- // eagerly.
- subsection.repository.mapping[node] =
- _readMetadata(subsection.repository, metadataOffset);
- } else {
- // Metadata payload might contain references to nodes that
- // are not yet deserialized. Postpone association of metadata
- // with this node.
- subsection.pending ??= <Object>[];
- subsection.pending..add(node)..add(metadataOffset);
- }
- }
-
- // Check if this node is referenced from this section and update
- // referencedNodes array if that is the case.
- if (subsection.nodeOffsetToReferenceId != null) {
- final id = subsection.nodeOffsetToReferenceId[nodeOffset];
- if (id != null) {
- subsection.referencedNodes[id] = node;
- }
+ subsection.repository.mapping[node] =
+ _readMetadata(node, subsection.repository, metadataOffset);
}
}
@@ -2049,9 +2042,11 @@
}
@override
- FunctionNode readFunctionNode(bool lazyLoadBody, int outerEndOffset) {
+ FunctionNode readFunctionNode(
+ {bool lazyLoadBody: false, int outerEndOffset: -1}) {
final nodeOffset = _byteOffset;
- final result = super.readFunctionNode(lazyLoadBody, outerEndOffset);
+ final result = super.readFunctionNode(
+ lazyLoadBody: lazyLoadBody, outerEndOffset: outerEndOffset);
return _associateMetadata(result, nodeOffset);
}
@@ -2144,12 +2139,6 @@
@override
List<int> get bytes => _bytes;
-
- @override
- Node readNodeReference() {
- final id = readUInt();
- return id == 0 ? null : _referencedNodes[id - 1];
- }
}
/// Deserialized MetadataMapping corresponding to the given metadata repository.
@@ -2160,18 +2149,5 @@
/// Deserialized mapping from node offsets to metadata offsets.
final Map<int, int> mapping;
- /// Deserialized mapping from node offset to node reference ids.
- final Map<int, int> nodeOffsetToReferenceId;
-
- /// Array mapping node reference ids to corresponding nodes.
- /// Will be gradually filled as nodes are deserialized.
- final List<Node> referencedNodes;
-
- /// A list of pairs (Node, int metadataOffset) that describes pending
- /// metadata associations which will be processed once all nodes
- /// are parsed.
- List<Object> pending;
-
- _MetadataSubsection(this.repository, this.mapping,
- this.nodeOffsetToReferenceId, this.referencedNodes);
+ _MetadataSubsection(this.repository, this.mapping);
}
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index a65dd03..0329a1f 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -8,8 +8,8 @@
import '../ast.dart';
import 'tag.dart';
import 'dart:convert';
+import 'dart:io' show BytesBuilder;
import 'dart:typed_data';
-import 'dart:collection';
/// Writes to a binary file.
///
@@ -22,25 +22,25 @@
final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer();
final StringIndexer stringIndexer;
ConstantIndexer _constantIndexer;
- final StringIndexer _sourceUriIndexer = new StringIndexer();
+ final UriIndexer _sourceUriIndexer = new UriIndexer();
final Set<Uri> _knownSourceUri = new Set<Uri>();
Map<LibraryDependency, int> _libraryDependencyIndex =
<LibraryDependency, int>{};
List<_MetadataSubsection> _metadataSubsections;
- /// Map used to assign reference ids to nodes contained within metadata
- /// payloads.
- Map<Node, int> _nodeReferences;
-
- final BufferedSink _sink;
+ final BufferedSink _mainSink;
+ final BufferedSink _metadataSink;
+ BufferedSink _sink;
List<int> libraryOffsets;
List<int> classOffsets;
List<int> procedureOffsets;
int _binaryOffsetForSourceTable = -1;
- int _binaryOffsetForStringTable = -1;
int _binaryOffsetForLinkTable = -1;
+ int _binaryOffsetForMetadataPayloads = -1;
+ int _binaryOffsetForMetadataMappings = -1;
+ int _binaryOffsetForStringTable = -1;
int _binaryOffsetForConstantTable = -1;
List<CanonicalName> _canonicalNameList;
@@ -51,14 +51,12 @@
///
/// The BinaryPrinter will use its own buffer, so the [sink] does not need
/// one.
- ///
- /// If multiple binaries are to be written based on the same IR, a shared
- /// [globalIndexer] may be passed in to avoid rebuilding the same indices
- /// in every printer.
BinaryPrinter(Sink<List<int>> sink, {StringIndexer stringIndexer})
- : _sink = new BufferedSink(sink),
+ : _mainSink = new BufferedSink(sink),
+ _metadataSink = new BufferedSink(new BytesSink()),
stringIndexer = stringIndexer ?? new StringIndexer() {
_constantIndexer = new ConstantIndexer(this.stringIndexer);
+ _sink = _mainSink;
}
void _flush() {
@@ -103,15 +101,23 @@
_binaryOffsetForStringTable = getBufferOffset();
// Write the end offsets.
- writeUInt30(indexer.numberOfStrings);
+ writeUInt30(indexer.index.length);
int endOffset = 0;
- for (var entry in indexer.entries) {
- endOffset += entry.utf8Bytes.length;
+ List<List<int>> data =
+ new List<List<int>>.filled(indexer.index.length, null);
+ int i = 0;
+ Utf8Encoder utf8Encoder = const Utf8Encoder();
+ for (String key in indexer.index.keys) {
+ List<int> utf8Bytes = utf8Encoder.convert(key);
+ data[i] = utf8Bytes;
+ endOffset += utf8Bytes.length;
writeUInt30(endOffset);
+ i++;
}
+
// Write the UTF-8 encoded strings.
- for (var entry in indexer.entries) {
- writeBytes(entry.utf8Bytes);
+ for (var entry in data) {
+ writeBytes(entry);
}
}
@@ -206,11 +212,12 @@
// Returns the new active file uri.
Uri writeUriReference(Uri uri) {
if (_knownSourceUri.contains(uri)) {
- final int index = _sourceUriIndexer.put(uri == null ? "" : "$uri");
+ final int index = _sourceUriIndexer.put(uri);
writeUInt30(index);
return uri;
} else {
- final int index = 0; // equivalent to index = _sourceUriIndexer[""];
+ // This is equivalent to `index = _sourceUriIndexer[null];`.
+ final int index = 0;
writeUInt30(index);
return null;
}
@@ -232,7 +239,7 @@
void writeNode(Node node) {
if (_metadataSubsections != null) {
- _recordNodeOffsetForMetadataMapping(node);
+ _writeNodeMetadata(node);
}
node.accept(this);
}
@@ -303,11 +310,9 @@
writeUInt32(Tag.BinaryFormatVersion);
indexLinkTable(component);
indexUris(component);
- // Note: must write metadata payloads before any other node in the component
- // to collect references to nodes contained within metadata payloads.
- _writeMetadataPayloads(component);
+ _collectMetadata(component);
if (_metadataSubsections != null) {
- _recordNodeOffsetForMetadataMappingImpl(component, componentOffset);
+ _writeNodeMetadataImpl(component, componentOffset);
}
libraryOffsets = <int>[];
CanonicalName main = getCanonicalNameOfMember(component.mainMethod);
@@ -317,7 +322,7 @@
writeLibraries(component);
writeUriToSource(component.uriToSource);
writeLinkTable(component);
- _writeMetadataMappingSection(component);
+ _writeMetadataSection(component);
writeStringTable(stringIndexer);
writeConstantTable(_constantIndexer);
writeComponentIndex(component, component.libraries);
@@ -325,87 +330,95 @@
_flush();
}
- @override
- void writeNodeReference(Node node) {
- if (!MetadataRepository.isSupported(node)) {
- throw "Can't reference nodes of type ${node.runtimeType} from metadata.";
- }
-
- if (node == null) {
- writeUInt30(0);
- } else {
- final id =
- _nodeReferences.putIfAbsent(node, () => _nodeReferences.length);
- writeUInt30(id + 1);
- }
- }
-
- /// Collect and write out all metadata contained in metadata repositories
- /// associated with the component.
- ///
- /// Non-empty metadata subsections will be collected in [_metadataSubsections]
- /// and used to generate metadata mappings after all nodes in the component
- /// are written and all node offsets are known.
- ///
- /// Note: must write metadata payloads before any other node in the component
- /// to collect references to nodes contained within metadata payloads.
- void _writeMetadataPayloads(Component component) {
+ /// Collect non-empty metadata repositories associated with the component.
+ void _collectMetadata(Component component) {
component.metadata.forEach((tag, repository) {
if (repository.mapping.isEmpty) {
return;
}
- // Write all payloads collecting outgoing node references and remembering
- // metadata offset for each node that had associated metadata.
- _nodeReferences = <Node, int>{};
- final metadataOffsets = <Node, int>{};
- repository.mapping.forEach((node, value) {
- if (!MetadataRepository.isSupported(node)) {
- throw "Nodes of type ${node.runtimeType} can't have metadata.";
- }
-
- metadataOffsets[node] = getBufferOffset();
- repository.writeToBinary(value, this);
- });
-
_metadataSubsections ??= <_MetadataSubsection>[];
- _metadataSubsections.add(new _MetadataSubsection(
- repository, metadataOffsets, _nodeReferences));
-
- _nodeReferences = null;
+ _metadataSubsections.add(new _MetadataSubsection(repository));
});
}
- /// If the given [Node] has any metadata associated with it or is referenced
- /// from some metadata payload then we need to record its offset.
- void _recordNodeOffsetForMetadataMapping(Node node) {
- _recordNodeOffsetForMetadataMappingImpl(node, getBufferOffset());
+ /// Writes metadata associated with the given [Node].
+ void _writeNodeMetadata(Node node) {
+ _writeNodeMetadataImpl(node, getBufferOffset());
}
- void _recordNodeOffsetForMetadataMappingImpl(Node node, int nodeOffset) {
+ void _writeNodeMetadataImpl(Node node, int nodeOffset) {
for (var subsection in _metadataSubsections) {
- final metadataOffset = subsection.metadataOffsets[node];
- if (metadataOffset != null) {
- subsection.metadataMapping..add(nodeOffset)..add(metadataOffset);
+ final repository = subsection.repository;
+ final value = repository.mapping[node];
+ if (value == null) {
+ continue;
}
- if (subsection.nodeToReferenceId != null) {
- final id = subsection.nodeToReferenceId[node];
- if (id != null) {
- subsection.offsetsOfReferencedNodes[id] = nodeOffset;
- }
+
+ if (!MetadataRepository.isSupported(node)) {
+ throw "Nodes of type ${node.runtimeType} can't have metadata.";
}
+
+ if (!identical(_sink, _mainSink)) {
+ throw "Node written into metadata can't have metadata "
+ "(metadata: ${repository.tag}, node: ${node.runtimeType} $node)";
+ }
+
+ _sink = _metadataSink;
+ subsection.metadataMapping.add(nodeOffset);
+ subsection.metadataMapping.add(getBufferOffset());
+ repository.writeToBinary(value, node, this);
+ _sink = _mainSink;
}
}
- void _writeMetadataMappingSection(Component component) {
+ @override
+ void enterScope(
+ {List<TypeParameter> typeParameters,
+ bool memberScope: false,
+ bool variableScope: false}) {
+ if (typeParameters != null) {
+ _typeParameterIndexer.enter(typeParameters);
+ }
+ if (memberScope) {
+ _variableIndexer = new VariableIndexer();
+ }
+ if (variableScope) {
+ _variableIndexer.pushScope();
+ }
+ }
+
+ @override
+ void leaveScope(
+ {List<TypeParameter> typeParameters,
+ bool memberScope: false,
+ bool variableScope: false}) {
+ if (variableScope) {
+ _variableIndexer.popScope();
+ }
+ if (memberScope) {
+ _variableIndexer = null;
+ }
+ if (typeParameters != null) {
+ _typeParameterIndexer.exit(typeParameters);
+ }
+ }
+
+ void _writeMetadataSection(Component component) {
+ _binaryOffsetForMetadataPayloads = getBufferOffset();
+
if (_metadataSubsections == null) {
+ _binaryOffsetForMetadataMappings = getBufferOffset();
writeUInt32(0); // Empty section.
return;
}
- _recordNodeOffsetForMetadataMappingImpl(component, 0);
+ assert(identical(_sink, _mainSink));
+ _metadataSink.flushAndDestroy();
+ writeBytes((_metadataSink._sink as BytesSink).builder.takeBytes());
// RList<MetadataMapping> metadataMappings
+ _binaryOffsetForMetadataMappings = getBufferOffset();
for (var subsection in _metadataSubsections) {
// UInt32 tag
writeUInt32(stringIndexer.put(subsection.repository.tag));
@@ -417,32 +430,6 @@
writeUInt32(subsection.metadataMapping[i + 1]); // metadata offset
}
writeUInt32(mappingLength ~/ 2);
-
- // RList<UInt32> nodeReferences
- if (subsection.nodeToReferenceId != null) {
- final offsets = subsection.offsetsOfReferencedNodes;
- for (int i = 0; i < offsets.length; ++i) {
- final nodeOffset = offsets[i];
- if (nodeOffset < 0) {
- // Dangling reference.
- // Find a node which was referenced to report meaningful error.
- Node referencedNode;
- subsection.nodeToReferenceId.forEach((node, id) {
- if (id == i) {
- referencedNode = node;
- }
- });
- throw 'Unable to write reference to node'
- ' ${referencedNode.runtimeType} $referencedNode'
- ' from metadata ${subsection.repository.tag}'
- ' (node is not written into kernel binary)';
- }
- writeUInt32(nodeOffset);
- }
- writeUInt32(subsection.offsetsOfReferencedNodes.length);
- } else {
- writeUInt32(0);
- }
}
writeUInt32(_metadataSubsections.length);
}
@@ -458,6 +445,10 @@
writeUInt32(_binaryOffsetForSourceTable);
assert(_binaryOffsetForLinkTable >= 0);
writeUInt32(_binaryOffsetForLinkTable);
+ assert(_binaryOffsetForMetadataPayloads >= 0);
+ writeUInt32(_binaryOffsetForMetadataPayloads);
+ assert(_binaryOffsetForMetadataMappings >= 0);
+ writeUInt32(_binaryOffsetForMetadataMappings);
assert(_binaryOffsetForStringTable >= 0);
writeUInt32(_binaryOffsetForStringTable);
assert(_binaryOffsetForConstantTable >= 0);
@@ -487,19 +478,19 @@
void writeUriToSource(Map<Uri, Source> uriToSource) {
_binaryOffsetForSourceTable = getBufferOffset();
- int length = _sourceUriIndexer.numberOfStrings;
+ int length = _sourceUriIndexer.index.length;
writeUInt32(length);
- List<int> index = new List<int>(_sourceUriIndexer.entries.length);
+ List<int> index = new List<int>(length);
// Write data.
- for (int i = 0; i < length; ++i) {
+ int i = 0;
+ Utf8Encoder utf8Encoder = const Utf8Encoder();
+ for (Uri uri in _sourceUriIndexer.index.keys) {
index[i] = getBufferOffset();
- StringTableEntry uri = _sourceUriIndexer.entries[i];
- Source source = uriToSource[Uri.parse(uri.value)] ??
- new Source(<int>[], const <int>[]);
+ Source source = uriToSource[uri] ?? new Source(<int>[], const <int>[]);
- writeByteList(uri.utf8Bytes);
+ writeByteList(utf8Encoder.convert(uri == null ? "" : "$uri"));
writeByteList(source.source);
List<int> lineStarts = source.lineStarts;
writeUInt30(lineStarts.length);
@@ -508,6 +499,7 @@
writeUInt30(lineStart - previousLineStart);
previousLineStart = lineStart;
});
+ i++;
}
// Write index for random access.
@@ -588,7 +580,7 @@
void writeName(Name node) {
if (_metadataSubsections != null) {
- _recordNodeOffsetForMetadataMapping(node);
+ _writeNodeMetadata(node);
}
writeStringReference(node.name);
// TODO: Consider a more compressed format for private names within the
@@ -662,7 +654,7 @@
void writeLibraryDependency(LibraryDependency node) {
if (_metadataSubsections != null) {
- _recordNodeOffsetForMetadataMapping(node);
+ _writeNodeMetadata(node);
}
writeOffset(node.fileOffset);
writeByte(node.flags);
@@ -687,7 +679,7 @@
void writeLibraryPart(LibraryPart node) {
if (_metadataSubsections != null) {
- _recordNodeOffsetForMetadataMapping(node);
+ _writeNodeMetadata(node);
}
writeAnnotationList(node.annotations);
writeStringReference(node.partUri);
@@ -702,10 +694,10 @@
writeOffset(node.fileOffset);
writeStringReference(node.name);
writeAnnotationList(node.annotations);
- _typeParameterIndexer.enter(node.typeParameters);
+ enterScope(typeParameters: node.typeParameters);
writeNodeList(node.typeParameters);
writeNode(node.type);
- _typeParameterIndexer.exit(node.typeParameters);
+ leaveScope(typeParameters: node.typeParameters);
_activeFileUri = activeFileUriSaved;
}
@@ -758,7 +750,7 @@
writeStringReference(node.name ?? '');
writeAnnotationList(node.annotations);
- _typeParameterIndexer.enter(node.typeParameters);
+ enterScope(typeParameters: node.typeParameters);
writeNodeList(node.typeParameters);
writeOptionalNode(node.supertype);
writeOptionalNode(node.mixedInType);
@@ -769,7 +761,7 @@
writeNodeList(node.procedures);
procedureOffsets.add(getBufferOffset());
writeNodeList(node.redirectingFactoryConstructors);
- _typeParameterIndexer.exit(node.typeParameters);
+ leaveScope(typeParameters: node.typeParameters);
_activeFileUri = activeFileUriSaved;
@@ -787,7 +779,7 @@
if (node.canonicalName == null) {
throw 'Missing canonical name for $node';
}
- _variableIndexer = new VariableIndexer();
+ enterScope(memberScope: true);
writeByte(Tag.Constructor);
writeCanonicalNameReference(getCanonicalNameOfMember(node));
@@ -809,7 +801,7 @@
_activeFileUri = activeFileUriSaved;
- _variableIndexer = null;
+ leaveScope(memberScope: true);
}
@override
@@ -819,7 +811,7 @@
if (node.canonicalName == null) {
throw 'Missing canonical name for $node';
}
- _variableIndexer = new VariableIndexer();
+ enterScope(memberScope: true);
writeByte(Tag.Procedure);
writeCanonicalNameReference(getCanonicalNameOfMember(node));
@@ -838,7 +830,7 @@
_activeFileUri = activeFileUriSaved;
- _variableIndexer = null;
+ leaveScope(memberScope: true);
assert((node.forwardingStubSuperTarget != null) ||
!(node.isForwardingStub && node.function.body != null));
@@ -849,7 +841,7 @@
if (node.canonicalName == null) {
throw 'Missing canonical name for $node';
}
- _variableIndexer = new VariableIndexer();
+ enterScope(memberScope: true);
writeByte(Tag.Field);
writeCanonicalNameReference(getCanonicalNameOfMember(node));
@@ -866,7 +858,7 @@
_activeFileUri = activeFileUriSaved;
- _variableIndexer = null;
+ leaveScope(memberScope: true);
}
@override
@@ -875,9 +867,10 @@
throw 'Missing canonical name for $node';
}
writeByte(Tag.RedirectingFactoryConstructor);
- _variableIndexer = new VariableIndexer();
- _variableIndexer.pushScope();
- _typeParameterIndexer.enter(node.typeParameters);
+ enterScope(
+ typeParameters: node.typeParameters,
+ memberScope: true,
+ variableScope: true);
writeCanonicalNameReference(getCanonicalNameOfMember(node));
final Uri activeFileUriSaved = _activeFileUri;
@@ -896,12 +889,13 @@
writeUInt30(node.requiredParameterCount);
writeVariableDeclarationList(node.positionalParameters);
writeVariableDeclarationList(node.namedParameters);
- _typeParameterIndexer.exit(node.typeParameters);
_activeFileUri = activeFileUriSaved;
- _variableIndexer.popScope();
- _variableIndexer = null;
+ leaveScope(
+ typeParameters: node.typeParameters,
+ memberScope: true,
+ variableScope: true);
}
@override
@@ -951,14 +945,12 @@
@override
void visitFunctionNode(FunctionNode node) {
writeByte(Tag.FunctionNode);
- assert(_variableIndexer != null);
- _variableIndexer.pushScope();
+ enterScope(typeParameters: node.typeParameters, variableScope: true);
var oldLabels = _labelIndexer;
_labelIndexer = null;
var oldCases = _switchCaseIndexer;
_switchCaseIndexer = null;
// Note: FunctionNode has no tag.
- _typeParameterIndexer.enter(node.typeParameters);
writeOffset(node.fileOffset);
writeOffset(node.fileEndOffset);
writeByte(node.asyncMarker.index);
@@ -972,8 +964,7 @@
writeOptionalNode(node.body);
_labelIndexer = oldLabels;
_switchCaseIndexer = oldCases;
- _typeParameterIndexer.exit(node.typeParameters);
- _variableIndexer.popScope();
+ leaveScope(typeParameters: node.typeParameters, variableScope: true);
}
@override
@@ -1591,7 +1582,7 @@
void writeVariableDeclaration(VariableDeclaration node) {
if (_metadataSubsections != null) {
- _recordNodeOffsetForMetadataMapping(node);
+ _writeNodeMetadata(node);
}
node.binaryOffsetNoTag = getBufferOffset();
writeOffset(node.fileOffset);
@@ -1683,7 +1674,7 @@
writeNode(node.returnType);
} else {
writeByte(Tag.FunctionType);
- _typeParameterIndexer.enter(node.typeParameters);
+ enterScope(typeParameters: node.typeParameters);
writeNodeList(node.typeParameters);
writeUInt30(node.requiredParameterCount);
writeUInt30(
@@ -1693,7 +1684,7 @@
writeStringReferenceList(node.positionalParameterNames);
writeReference(node.typedefReference);
writeNode(node.returnType);
- _typeParameterIndexer.exit(node.typeParameters);
+ leaveScope(typeParameters: node.typeParameters);
}
}
@@ -2024,59 +2015,32 @@
ConstantIndexer(this.stringIndexer);
- defaultConstantReference(Constant node) {
- put(node);
- }
-
int put(Constant constant) {
- final int value = index[constant];
- if (value != null) return value;
+ final int oldIndex = index[constant];
+ if (oldIndex != null) return oldIndex;
// Traverse DAG in post-order to ensure children have their id's assigned
// before the parent.
- return constant.accept(this);
- }
+ constant.visitChildren(this);
- defaultConstant(Constant node) {
- final int oldIndex = index[node];
- if (oldIndex != null) return oldIndex;
-
- if (node is StringConstant) {
- stringIndexer.put(node.value);
- } else if (node is DoubleConstant) {
- stringIndexer.put('${node.value}');
- } else if (node is IntConstant) {
- final int value = node.value;
+ if (constant is StringConstant) {
+ stringIndexer.put(constant.value);
+ } else if (constant is DoubleConstant) {
+ stringIndexer.put('${constant.value}');
+ } else if (constant is IntConstant) {
+ final int value = constant.value;
if ((value.abs() >> 30) != 0) {
stringIndexer.put('$value');
}
}
final int newIndex = entries.length;
- entries.add(node);
- return index[node] = newIndex;
+ entries.add(constant);
+ return index[constant] = newIndex;
}
- visitMapConstant(MapConstant node) {
- for (final ConstantMapEntry entry in node.entries) {
- put(entry.key);
- put(entry.value);
- }
- return defaultConstant(node);
- }
-
- visitListConstant(ListConstant node) {
- for (final Constant entry in node.entries) {
- put(entry);
- }
- return defaultConstant(node);
- }
-
- visitInstanceConstant(InstanceConstant node) {
- for (final Constant entry in node.fieldValues.values) {
- put(entry);
- }
- return defaultConstant(node);
+ defaultConstantReference(Constant node) {
+ put(node);
}
int operator [](Constant node) => index[node];
@@ -2095,34 +2059,24 @@
void exit(List<TypeParameter> typeParameters) {
stackHeight -= typeParameters.length;
+ typeParameters.forEach(index.remove);
}
- int operator [](TypeParameter parameter) => index[parameter];
-}
-
-class StringTableEntry {
- final String value;
- final List<int> utf8Bytes;
-
- StringTableEntry(String value)
- : value = value,
- utf8Bytes = const Utf8Encoder().convert(value);
+ int operator [](TypeParameter parameter) =>
+ index[parameter] ?? (throw 'Type parameter $parameter is not indexed');
}
class StringIndexer {
- final List<StringTableEntry> entries = <StringTableEntry>[];
- final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>();
+ // Note that the iteration order is important.
+ final Map<String, int> index = new Map<String, int>();
StringIndexer() {
put('');
}
- int get numberOfStrings => index.length;
-
int put(String string) {
var result = index[string];
if (result == null) {
- entries.add(new StringTableEntry(string));
result = index.length;
index[string] = result;
}
@@ -2132,50 +2086,21 @@
int operator [](String string) => index[string];
}
-/// Computes and stores the index of a library, class, or member within its
-/// parent list.
-class GlobalIndexer extends TreeVisitor {
- final Map<TreeNode, int> indices = <TreeNode, int>{};
+class UriIndexer {
+ // Note that the iteration order is important.
+ final Map<Uri, int> index = new Map<Uri, int>();
- void buildIndexForContainer(TreeNode libraryOrClass) {
- libraryOrClass.accept(this);
+ UriIndexer() {
+ put(null);
}
- void buildIndexForList(List<TreeNode> list) {
- for (int i = 0; i < list.length; ++i) {
- TreeNode child = list[i];
- if (child != null) {
- indices[child] = i;
- }
+ int put(Uri uri) {
+ var result = index[uri];
+ if (result == null) {
+ result = index.length;
+ index[uri] = result;
}
- }
-
- visitComponent(Component node) {
- buildIndexForList(node.libraries);
- }
-
- visitLibrary(Library node) {
- buildIndexForList(node.classes);
- buildIndexForList(node.fields);
- buildIndexForList(node.procedures);
- }
-
- visitClass(Class node) {
- buildIndexForList(node.fields);
- buildIndexForList(node.constructors);
- buildIndexForList(node.procedures);
- }
-
- int operator [](TreeNode memberOrLibraryOrClass) {
- var node = memberOrLibraryOrClass;
- assert(node is Member || node is Library || node is Class);
- int index = indices[node];
- if (index == null) {
- buildIndexForContainer(node.parent);
- return indices[node];
- } else {
- return index;
- }
+ return result;
}
}
@@ -2279,29 +2204,27 @@
class _MetadataSubsection {
final MetadataRepository<Object> repository;
- /// Offsets of metadata payloads associated with the nodes.
- final Map<Node, int> metadataOffsets;
-
/// List of (nodeOffset, metadataOffset) pairs.
/// Gradually filled by the writer as writing progresses, which by
/// construction guarantees that pairs are sorted by first component
/// (nodeOffset) in ascending order.
final List<int> metadataMapping = <int>[];
- /// Mapping between nodes that are referenced from inside metadata payloads
- /// and their ids.
- final Map<Node, int> nodeToReferenceId;
+ _MetadataSubsection(this.repository);
+}
- /// Mapping between reference ids and offsets of referenced nodes.
- /// Gradually filled by the writer as writing progresses but is not
- /// guaranteed to be sorted.
- final List<int> offsetsOfReferencedNodes;
+/// A [Sink] that directly writes data into a byte builder.
+// TODO(dartbug.com/28316): Remove this wrapper class.
+class BytesSink implements Sink<List<int>> {
+ final BytesBuilder builder = new BytesBuilder();
- _MetadataSubsection(
- this.repository, this.metadataOffsets, Map<Node, int> nodeToReferenceId)
- : nodeToReferenceId =
- nodeToReferenceId.isNotEmpty ? nodeToReferenceId : null,
- offsetsOfReferencedNodes = nodeToReferenceId.isNotEmpty
- ? new List<int>.filled(nodeToReferenceId.length, -1)
- : null;
+ @override
+ void add(List<int> data) {
+ builder.add(data);
+ }
+
+ @override
+ void close() {
+ // Nothing to do.
+ }
}
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 877657f..1d016af 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -134,8 +134,8 @@
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
- /// Keep in sync with runtime/vm/kernel_binary.h.
- static const int BinaryFormatVersion = 5;
+ /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
+ static const int BinaryFormatVersion = 6;
}
abstract class ConstantTag {
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index be0c79a..3a9a036 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -3,10 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
library kernel.class_hierarchy;
-import 'ast.dart';
-import 'dart:collection' show IterableBase;
+import 'dart:collection';
import 'dart:math';
import 'dart:typed_data';
+
+import 'ast.dart';
import 'src/heap.dart';
import 'type_algebra.dart';
@@ -17,16 +18,10 @@
}
/// Interface for answering various subclassing queries.
-/// TODO(scheglov) Several methods are not used, or used only in tests.
-/// Check if these methods are not useful and should be removed .
abstract class ClassHierarchy {
factory ClassHierarchy(Component component,
{HandleAmbiguousSupertypes onAmbiguousSupertypes,
MixinInferrer mixinInferrer}) {
- int numberOfClasses = 0;
- for (var library in component.libraries) {
- numberOfClasses += library.classes.length;
- }
onAmbiguousSupertypes ??= (Class cls, Supertype a, Supertype b) {
if (!cls.isSyntheticMixinImplementation) {
// See https://github.com/dart-lang/sdk/issues/32091
@@ -34,33 +29,21 @@
}
};
return new ClosedWorldClassHierarchy._internal(
- component, numberOfClasses, onAmbiguousSupertypes)
- .._initialize(mixinInferrer);
+ onAmbiguousSupertypes, mixinInferrer)
+ .._initialize(component.libraries);
}
+ void set onAmbiguousSupertypes(
+ HandleAmbiguousSupertypes onAmbiguousSupertypes);
+
/// Given the [unordered] classes, return them in such order that classes
/// occur after their superclasses. If some superclasses are not in
/// [unordered], they are not included.
Iterable<Class> getOrderedClasses(Iterable<Class> unordered);
- /// Returns the unique index of the [class_].
- int getClassIndex(Class class_);
-
/// True if the component contains another class that is a subtype of given one.
bool hasProperSubtypes(Class class_);
- /// Returns the number of steps in the longest inheritance path from [class_]
- /// to [Object].
- int getClassDepth(Class class_);
-
- /// Returns a list of classes appropriate for use in calculating a least upper
- /// bound.
- ///
- /// The returned list is a list of all classes that [class_] is a subtype of
- /// (including itself), sorted first by depth (deepest first) and then by
- /// class index.
- List<Class> getRankedSuperclasses(Class class_);
-
/// Returns the least upper bound of two interface types, as defined by Dart
/// 1.0.
///
@@ -119,12 +102,6 @@
/// The returned list should not be modified.
List<Member> getDispatchTargets(Class class_, {bool setters: false});
- /// Returns the single concrete target for invocation of the given interface
- /// target, or `null` if it could not be resolved or there are multiple
- /// possible targets.
- Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
- {bool setter: false});
-
/// Returns the possibly abstract interface member of [class_] with the given
/// [name].
///
@@ -153,20 +130,10 @@
/// classes.
List<Member> getDeclaredMembers(Class class_, {bool setters: false});
- /// Returns the subclasses of [class_] as an interval list.
- ClassSet getSubclassesOf(Class class_);
-
- /// Returns the subtypes of [class_] as an interval list.
- ClassSet getSubtypesOf(Class class_);
-
/// True if [subclass] inherits from [superclass] though zero or more
/// `extends` relationships.
bool isSubclassOf(Class subclass, Class superclass);
- /// True if [submixture] inherits from [superclass] though zero or more
- /// `extends` and `with` relationships.
- bool isSubmixtureOf(Class submixture, Class superclass);
-
/// True if [subtype] inherits from [superclass] though zero or more
/// `extends`, `with`, and `implements` relationships.
bool isSubtypeOf(Class subtype, Class superclass);
@@ -175,12 +142,6 @@
/// mixin application (i.e. [Class.mixedInType]).
bool isUsedAsMixin(Class class_);
- /// True if the given class is the direct super class of another class.
- bool isUsedAsSuperClass(Class class_);
-
- /// True if the given class is used in an `implements` clause.
- bool isUsedAsSuperInterface(Class class_);
-
/// Invokes [callback] for every member declared in or inherited by [class_]
/// that overrides or implements a member in a supertype of [class_]
/// (or in rare cases, overrides a member declared in [class_]).
@@ -211,11 +172,27 @@
void forEachOverridePair(Class class_,
callback(Member declaredMember, Member interfaceMember, bool isSetter));
- /// This method is invoked by the client after it changed the [classes], and
- /// some of the information that this hierarchy might have cached, is not
- /// valid anymore. The hierarchy may perform required updates and return the
- /// same instance, or return a new instance.
- ClassHierarchy applyChanges(Iterable<Class> classes);
+ /// This method is invoked by the client after a change: removal, addition,
+ /// or modification of classes.
+ ///
+ /// For modified classes specify a class as both removed and added: Some of
+ /// the information that this hierarchy might have cached, is not valid
+ /// anymore.
+ ///
+ /// Note, that it is the clients responsibility to mark all subclasses as
+ /// changed too.
+ ClassHierarchy applyTreeChanges(
+ Iterable<Class> removedClasses, Iterable<Class> addedClasses,
+ {Component reissueAmbiguousSupertypesFor});
+
+ /// This method is invoked by the client after a member change on classes:
+ /// Some of the information that this hierarchy might have cached,
+ /// is not valid anymore.
+ /// Note, that it is the clients responsibility to mark all subclasses as
+ /// changed too, or - if [findDescendants] is true, the ClassHierarchy will
+ /// spend the time to find them for the caller.
+ ClassHierarchy applyMemberChanges(Iterable<Class> classes,
+ {bool findDescendants: false});
/// Merges two sorted lists.
///
@@ -328,35 +305,160 @@
}
}
-/// Implementation of [ClassHierarchy] for closed world.
-class ClosedWorldClassHierarchy implements ClassHierarchy {
- final HandleAmbiguousSupertypes _onAmbiguousSupertypes;
+abstract class ClassHierarchySubtypes {
+ /// Returns the subtypes of [class_] as an interval list.
+ ClassSet getSubtypesOf(Class class_);
- /// The [Component] that this class hierarchy represents.
- final Component _component;
+ /// Returns the single concrete target for invocation of the given interface
+ /// target, or `null` if it could not be resolved or there are multiple
+ /// possible targets.
+ Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+ {bool setter: false});
+}
- /// All classes in the component.
- ///
- /// The list is ordered so that classes occur after their super classes.
- final List<Class> classes;
+class _ClassInfoSubtype {
+ final _ClassInfo classInfo;
+ int topDownIndex = -1;
- final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{};
+ /// Top-down indices of all subclasses of this class, represented as
+ /// interleaved begin/end interval end points.
+ Uint32List subtypeIntervalList;
- /// All classes ordered by [_ClassInfo.topDownIndex].
+ _ClassInfoSubtype(this.classInfo);
+}
+
+class _ClosedWorldClassHierarchySubtypes implements ClassHierarchySubtypes {
+ final ClosedWorldClassHierarchy hierarchy;
final List<Class> _classesByTopDownIndex;
+ final Map<Class, _ClassInfoSubtype> _infoFor = <Class, _ClassInfoSubtype>{};
+ bool invalidated = false;
- ClosedWorldClassHierarchy._internal(
- this._component, int numberOfClasses, this._onAmbiguousSupertypes)
- : classes = new List<Class>(numberOfClasses),
- _classesByTopDownIndex = new List<Class>(numberOfClasses);
+ _ClosedWorldClassHierarchySubtypes(this.hierarchy)
+ : _classesByTopDownIndex = new List<Class>(hierarchy._infoFor.length) {
+ if (hierarchy._infoFor.isNotEmpty) {
+ for (Class class_ in hierarchy._infoFor.keys) {
+ _infoFor[class_] = new _ClassInfoSubtype(hierarchy._infoFor[class_]);
+ }
+
+ _topDownSortVisit(_infoFor[hierarchy._infoFor.keys.first]);
+ }
+ }
+
+ /// Downwards traversal of the class hierarchy that orders classes so local
+ /// hierarchies have contiguous indices.
+ int _topDownSortIndex = 0;
+ void _topDownSortVisit(_ClassInfoSubtype subInfo) {
+ if (subInfo.topDownIndex != -1) return;
+ int index = _topDownSortIndex++;
+ subInfo.topDownIndex = index;
+ _classesByTopDownIndex[index] = subInfo.classInfo.classNode;
+ var subtypeSetBuilder = new _IntervalListBuilder()..addSingleton(index);
+ for (_ClassInfo subtype in subInfo.classInfo.directExtenders) {
+ _ClassInfoSubtype subtypeInfo = _infoFor[subtype.classNode];
+ _topDownSortVisit(subtypeInfo);
+ subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
+ }
+ for (_ClassInfo subtype in subInfo.classInfo.directMixers) {
+ _ClassInfoSubtype subtypeInfo = _infoFor[subtype.classNode];
+ _topDownSortVisit(subtypeInfo);
+ subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
+ }
+ for (_ClassInfo subtype in subInfo.classInfo.directImplementers) {
+ _ClassInfoSubtype subtypeInfo = _infoFor[subtype.classNode];
+ _topDownSortVisit(subtypeInfo);
+ subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
+ }
+ subInfo.subtypeIntervalList = subtypeSetBuilder.buildIntervalList();
+ }
@override
- int getClassIndex(Class class_) => _infoFor[class_].topologicalIndex;
+ Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+ {bool setter: false}) {
+ if (invalidated) throw "This datastructure has been invalidated";
+ Name name = interfaceTarget.name;
+ Member target = null;
+ ClassSet subtypes = getSubtypesOf(interfaceTarget.enclosingClass);
+ for (Class c in subtypes) {
+ if (!c.isAbstract) {
+ Member candidate = hierarchy.getDispatchTarget(c, name, setter: setter);
+ if ((candidate != null) && !candidate.isAbstract) {
+ if (target == null) {
+ target = candidate;
+ } else if (target != candidate) {
+ return null;
+ }
+ }
+ }
+ }
+ return target;
+ }
+
+ @override
+ ClassSet getSubtypesOf(Class class_) {
+ if (invalidated) throw "This datastructure has been invalidated";
+ Set<Class> result = new Set<Class>();
+ Uint32List list = _infoFor[class_].subtypeIntervalList;
+ for (int i = 0; i < list.length; i += 2) {
+ int from = list[i];
+ int to = list[i + 1];
+ for (int j = from; j < to; j++) {
+ result.add(_classesByTopDownIndex[j]);
+ }
+ }
+ return new ClassSet(result);
+ }
+}
+
+/// Implementation of [ClassHierarchy] for closed world.
+class ClosedWorldClassHierarchy implements ClassHierarchy {
+ HandleAmbiguousSupertypes _onAmbiguousSupertypes;
+ HandleAmbiguousSupertypes _onAmbiguousSupertypesNotWrapped;
+ MixinInferrer mixinInferrer;
+
+ void set onAmbiguousSupertypes(
+ HandleAmbiguousSupertypes onAmbiguousSupertypes) {
+ _onAmbiguousSupertypesNotWrapped = onAmbiguousSupertypes;
+ _onAmbiguousSupertypes = (Class class_, Supertype a, Supertype b) {
+ onAmbiguousSupertypes(class_, a, b);
+ List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
+ if (recorded == null) {
+ recorded = new List<Supertype>();
+ _recordedAmbiguousSupertypes[class_] = recorded;
+ }
+ recorded.add(a);
+ recorded.add(b);
+ };
+ }
+
+ /// The insert order is important.
+ final Map<Class, _ClassInfo> _infoFor =
+ new LinkedHashMap<Class, _ClassInfo>();
+
+ /// Recorded errors for classes we have already calculated the class hierarchy
+ /// for, but will have to be reissued when re-using the calculation.
+ final Map<Class, List<Supertype>> _recordedAmbiguousSupertypes =
+ new LinkedHashMap<Class, List<Supertype>>();
+
+ Iterable<Class> get classes => _infoFor.keys;
+ int get numberOfClasses => _infoFor.length;
+
+ _ClosedWorldClassHierarchySubtypes _cachedClassHierarchySubtypes;
+
+ ClosedWorldClassHierarchy._internal(
+ HandleAmbiguousSupertypes onAmbiguousSupertypes, this.mixinInferrer) {
+ this.onAmbiguousSupertypes = onAmbiguousSupertypes;
+ }
+
+ ClassHierarchySubtypes computeSubtypesInformation() {
+ _cachedClassHierarchySubtypes ??=
+ new _ClosedWorldClassHierarchySubtypes(this);
+ return _cachedClassHierarchySubtypes;
+ }
@override
Iterable<Class> getOrderedClasses(Iterable<Class> unordered) {
var unorderedSet = unordered.toSet();
- return classes.where(unorderedSet.contains);
+ return _infoFor.keys.where(unorderedSet.contains);
}
@override
@@ -366,42 +468,16 @@
}
@override
- bool isSubmixtureOf(Class submixture, Class superclass) {
- if (identical(submixture, superclass)) return true;
- return _infoFor[submixture].isSubmixtureOf(_infoFor[superclass]);
- }
-
- @override
bool isSubtypeOf(Class subtype, Class superclass) {
if (identical(subtype, superclass)) return true;
return _infoFor[subtype].isSubtypeOf(_infoFor[superclass]);
}
@override
- bool isUsedAsSuperClass(Class class_) {
- return _infoFor[class_].directExtenders.isNotEmpty;
- }
-
- @override
bool isUsedAsMixin(Class class_) {
return _infoFor[class_].directMixers.isNotEmpty;
}
- @override
- bool isUsedAsSuperInterface(Class class_) {
- return _infoFor[class_].directImplementers.isNotEmpty;
- }
-
- @override
- int getClassDepth(Class class_) => _infoFor[class_].depth;
-
- @override
- List<Class> getRankedSuperclasses(Class class_) {
- return _getRankedSuperclassInfos(_infoFor[class_])
- .map((info) => info.classNode)
- .toList();
- }
-
List<_ClassInfo> _getRankedSuperclassInfos(_ClassInfo info) {
if (info.leastUpperBoundInfos != null) return info.leastUpperBoundInfos;
var heap = new _LubHeap()..add(info);
@@ -561,27 +637,6 @@
}
@override
- Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
- {bool setter: false}) {
- Name name = interfaceTarget.name;
- Member target = null;
- ClassSet subtypes = getSubtypesOf(interfaceTarget.enclosingClass);
- for (Class c in subtypes) {
- if (!c.isAbstract) {
- Member candidate = getDispatchTarget(c, name, setter: setter);
- if ((candidate != null) && !candidate.isAbstract) {
- if (target == null) {
- target = candidate;
- } else if (target != candidate) {
- return null;
- }
- }
- }
- }
- return target;
- }
-
- @override
Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
List<Member> list = getInterfaceMembers(class_, setters: setter);
return ClassHierarchy.findMemberByName(list, name);
@@ -663,25 +718,111 @@
@override
bool hasProperSubtypes(Class class_) {
- // If there are no subtypes then the subtype set contains the class itself.
- return !getSubtypesOf(class_).isSingleton;
+ _ClassInfo info = _infoFor[class_];
+ return info.directExtenders.isNotEmpty ||
+ info.directImplementers.isNotEmpty ||
+ info.directMixers.isNotEmpty;
}
@override
- ClassSet getSubtypesOf(Class class_) {
- return new ClassSet(this, _infoFor[class_].subtypeIntervalList);
+ ClassHierarchy applyTreeChanges(
+ Iterable<Class> removedClasses, Iterable<Class> addedClasses,
+ {Component reissueAmbiguousSupertypesFor}) {
+ // Remove all references to the removed classes.
+ for (Class class_ in removedClasses) {
+ _ClassInfo info = _infoFor[class_];
+ if (class_.supertype != null) {
+ _infoFor[class_.supertype.classNode]?.directExtenders?.remove(info);
+ }
+ if (class_.mixedInType != null) {
+ _infoFor[class_.mixedInType.classNode]?.directMixers?.remove(info);
+ }
+ for (var supertype in class_.implementedTypes) {
+ _infoFor[supertype.classNode]?.directImplementers?.remove(info);
+ }
+
+ _infoFor.remove(class_);
+ _recordedAmbiguousSupertypes.remove(class_);
+ }
+
+ // If we have a cached computation of subtypes, invalidate it and stop
+ // caching it.
+ if (_cachedClassHierarchySubtypes != null) {
+ _cachedClassHierarchySubtypes.invalidated = true;
+ }
+
+ if (_recordedAmbiguousSupertypes.isNotEmpty &&
+ reissueAmbiguousSupertypesFor != null) {
+ Set<Library> libs =
+ new Set<Library>.from(reissueAmbiguousSupertypesFor.libraries);
+ for (Class class_ in _recordedAmbiguousSupertypes.keys) {
+ if (!libs.contains(class_.enclosingLibrary)) continue;
+ List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
+ for (int i = 0; i < recorded.length; i += 2) {
+ _onAmbiguousSupertypesNotWrapped(
+ class_, recorded[i], recorded[i + 1]);
+ }
+ }
+ }
+
+ // Add the new classes.
+ List<Class> addedClassesSorted = new List<Class>();
+ int expectedStartIndex = _topSortIndex;
+ for (Class class_ in addedClasses) {
+ _topologicalSortVisit(class_, new Set<Class>(),
+ orderedList: addedClassesSorted);
+ }
+ _initializeTopologicallySortedClasses(
+ addedClassesSorted, expectedStartIndex);
+
+ return this;
}
@override
- ClassSet getSubclassesOf(Class class_) {
- return new ClassSet(this, _infoFor[class_].subclassIntervalList);
- }
-
- @override
- ClassHierarchy applyChanges(Iterable<Class> classes) {
+ ClassHierarchy applyMemberChanges(Iterable<Class> classes,
+ {bool findDescendants: false}) {
if (classes.isEmpty) return this;
- return new ClassHierarchy(_component,
- onAmbiguousSupertypes: _onAmbiguousSupertypes);
+
+ List<_ClassInfo> infos = new List<_ClassInfo>();
+ if (findDescendants) {
+ Set<_ClassInfo> processedClasses = new Set<_ClassInfo>();
+ List<_ClassInfo> worklist = <_ClassInfo>[];
+ for (Class class_ in classes) {
+ _ClassInfo info = _infoFor[class_];
+ worklist.add(info);
+ }
+
+ while (worklist.isNotEmpty) {
+ _ClassInfo info = worklist.removeLast();
+ if (processedClasses.add(info)) {
+ worklist.addAll(info.directExtenders);
+ worklist.addAll(info.directImplementers);
+ worklist.addAll(info.directMixers);
+ }
+ }
+ infos.addAll(processedClasses);
+ } else {
+ for (Class class_ in classes) {
+ _ClassInfo info = _infoFor[class_];
+ infos.add(info);
+ }
+ }
+
+ infos.sort((_ClassInfo a, _ClassInfo b) {
+ return a.topologicalIndex - b.topologicalIndex;
+ });
+
+ for (_ClassInfo info in infos) {
+ Class class_ = info.classNode;
+ _buildDeclaredMembers(class_, info);
+ _buildImplementedMembers(class_, info);
+ info.interfaceSetters = null;
+ info.interfaceGettersAndCalls = null;
+ _buildInterfaceMembers(class_, info, setters: true);
+ _buildInterfaceMembers(class_, info, setters: false);
+ }
+
+ return this;
}
@override
@@ -698,19 +839,29 @@
return map == null ? null : map[superclass]?.first;
}
- void _initialize(MixinInferrer mixinInferrer) {
+ void _initialize(List<Library> libraries) {
// Build the class ordering based on a topological sort.
- for (var library in _component.libraries) {
+ for (var library in libraries) {
for (var classNode in library.classes) {
- _topologicalSortVisit(classNode);
+ _topologicalSortVisit(classNode, new Set<Class>());
}
}
- // Build index of direct children. Do this after the topological sort so
- // that super types always occur before subtypes.
- for (int i = 0; i < classes.length; ++i) {
- var class_ = classes[i];
- var info = _infoFor[class_];
+ _initializeTopologicallySortedClasses(_infoFor.keys, 0);
+ }
+
+ /// - Build index of direct children.
+ /// - Build list of super classes and super types.
+ /// - Infer and record supertypes for the classes.
+ /// - Record interface members.
+ /// - Perform some sanity checking.
+ /// Do this after the topological sort so that super types always occur
+ /// before subtypes.
+ void _initializeTopologicallySortedClasses(
+ Iterable<Class> classes, int expectedStartingTopologicalIndex) {
+ int i = expectedStartingTopologicalIndex;
+ for (Class class_ in classes) {
+ _ClassInfo info = _infoFor[class_];
if (class_.supertype != null) {
_infoFor[class_.supertype.classNode].directExtenders.add(info);
}
@@ -720,53 +871,30 @@
for (var supertype in class_.implementedTypes) {
_infoFor[supertype.classNode].directImplementers.add(info);
}
- }
+ _collectSupersForClass(class_);
- // Run a downward traversal from the root, compute preorder numbers for
- // each class, and build their subtype sets as interval lists.
- if (classes.isNotEmpty) {
- _topDownSortVisit(_infoFor[classes[0]]);
- }
-
- // Now that the intervals for subclass, mixer, and implementer queries are
- // built, we may infer and record supertypes for the classes.
- for (int i = 0; i < classes.length; ++i) {
- Class classNode = classes[i];
- _ClassInfo info = _infoFor[classNode];
- if (classNode.supertype != null) {
- _recordSuperTypes(info, classNode.supertype);
+ if (class_.supertype != null) {
+ _recordSuperTypes(info, class_.supertype);
}
- if (classNode.mixedInType != null) {
- mixinInferrer?.infer(this, classNode);
- _recordSuperTypes(info, classNode.mixedInType);
+ if (class_.mixedInType != null) {
+ mixinInferrer?.infer(this, class_);
+ _recordSuperTypes(info, class_.mixedInType);
}
- for (Supertype supertype in classNode.implementedTypes) {
+ for (Supertype supertype in class_.implementedTypes) {
_recordSuperTypes(info, supertype);
}
- }
- for (int i = 0; i < classes.length; ++i) {
- var class_ = classes[i];
- _buildInterfaceMembers(class_, _infoFor[class_], setters: true);
- _buildInterfaceMembers(class_, _infoFor[class_], setters: false);
- }
+ _buildInterfaceMembers(class_, info, setters: true);
+ _buildInterfaceMembers(class_, info, setters: false);
- for (int i = 0; i < classes.length; ++i) {
- Class cls = classes[i];
- if (cls == null) {
- throw "No class at index $i.";
- }
- _ClassInfo info = _infoFor[cls];
if (info == null) {
- throw "No info for ${cls.name} from ${cls.fileUri}.";
+ throw "No info for ${class_.name} from ${class_.fileUri}.";
}
if (info.topologicalIndex != i) {
throw "Unexpected topologicalIndex (${info.topologicalIndex} != $i) "
- "for ${cls.name} from ${cls.fileUri}.";
+ "for ${class_.name} from ${class_.fileUri}.";
}
- if (info.subtypeIntervalList == null) {
- throw "No subtypeIntervalList for ${cls.name} from ${cls.fileUri}.";
- }
+ i++;
}
}
@@ -776,34 +904,45 @@
/// Returns the depth of the visited class (the number of steps in the longest
/// inheritance path to the root class).
int _topSortIndex = 0;
- int _topologicalSortVisit(Class classNode) {
+ int _topologicalSortVisit(Class classNode, Set<Class> beingVisited,
+ {List<Class> orderedList}) {
var info = _infoFor[classNode];
if (info != null) {
- if (info.isBeingVisited) {
- throw 'Cyclic inheritance involving ${info.classNode.name}';
- }
- return info.depth; // Already built.
+ return info.depth;
}
+
+ if (!beingVisited.add(classNode)) {
+ throw 'Cyclic inheritance involving ${classNode.name}';
+ }
+
+ info = new _ClassInfo(classNode);
+
int superDepth = -1;
- _infoFor[classNode] = info = new _ClassInfo(classNode);
- info.isBeingVisited = true;
if (classNode.supertype != null) {
- superDepth =
- max(superDepth, _topologicalSortVisit(classNode.supertype.classNode));
+ superDepth = max(
+ superDepth,
+ _topologicalSortVisit(classNode.supertype.classNode, beingVisited,
+ orderedList: orderedList));
}
if (classNode.mixedInType != null) {
superDepth = max(
- superDepth, _topologicalSortVisit(classNode.mixedInType.classNode));
+ superDepth,
+ _topologicalSortVisit(classNode.mixedInType.classNode, beingVisited,
+ orderedList: orderedList));
}
for (var supertype in classNode.implementedTypes) {
- superDepth = max(superDepth, _topologicalSortVisit(supertype.classNode));
+ superDepth = max(
+ superDepth,
+ _topologicalSortVisit(supertype.classNode, beingVisited,
+ orderedList: orderedList));
}
_buildDeclaredMembers(classNode, info);
_buildImplementedMembers(classNode, info);
- int id = _topSortIndex++;
- info.topologicalIndex = id;
- classes[id] = info.classNode;
- info.isBeingVisited = false;
+ info.topologicalIndex = _topSortIndex++;
+
+ _infoFor[classNode] = info;
+ orderedList?.add(classNode);
+ beingVisited.remove(classNode);
return info.depth = superDepth + 1;
}
@@ -1004,54 +1143,49 @@
}
}
- /// Downwards traversal of the class hierarchy that orders classes so local
- /// hierarchies have contiguous indices.
- int _topDownSortIndex = 0;
- void _topDownSortVisit(_ClassInfo info) {
- if (info.topDownIndex != -1) return;
- bool isMixedIn = info.directMixers.isNotEmpty;
- int index = _topDownSortIndex++;
- info.topDownIndex = index;
- _classesByTopDownIndex[index] = info.classNode;
- var subclassSetBuilder = new _IntervalListBuilder()..addSingleton(index);
- var submixtureSetBuilder =
- isMixedIn ? (new _IntervalListBuilder()..addSingleton(index)) : null;
- var subtypeSetBuilder = new _IntervalListBuilder()..addSingleton(index);
- for (var subtype in info.directExtenders) {
- _topDownSortVisit(subtype);
- subclassSetBuilder.addIntervalList(subtype.subclassIntervalList);
- submixtureSetBuilder?.addIntervalList(subtype.submixtureIntervalList);
- subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+ /// Build lists of super types and super classes.
+ /// Note that the super class and super types of the class must already have
+ /// had their supers collected.
+ void _collectSupersForClass(Class class_) {
+ _ClassInfo info = _infoFor[class_];
+
+ var superclassSetBuilder = new _IntervalListBuilder()
+ ..addSingleton(info.topologicalIndex);
+ var supertypeSetBuilder = new _IntervalListBuilder()
+ ..addSingleton(info.topologicalIndex);
+
+ if (class_.supertype != null) {
+ _ClassInfo supertypeInfo = _infoFor[class_.supertype.classNode];
+ superclassSetBuilder
+ .addIntervalList(supertypeInfo.superclassIntervalList);
+ supertypeSetBuilder.addIntervalList(supertypeInfo.supertypeIntervalList);
}
- for (var subtype in info.directMixers) {
- _topDownSortVisit(subtype);
- submixtureSetBuilder.addIntervalList(subtype.submixtureIntervalList);
- subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+
+ if (class_.mixedInType != null) {
+ _ClassInfo mixedInTypeInfo = _infoFor[class_.mixedInType.classNode];
+ supertypeSetBuilder
+ .addIntervalList(mixedInTypeInfo.supertypeIntervalList);
}
- for (var subtype in info.directImplementers) {
- _topDownSortVisit(subtype);
- subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+
+ for (Supertype supertype in class_.implementedTypes) {
+ _ClassInfo supertypeInfo = _infoFor[supertype.classNode];
+ supertypeSetBuilder.addIntervalList(supertypeInfo.supertypeIntervalList);
}
- info.subclassIntervalList = subclassSetBuilder.buildIntervalList();
- info.submixtureIntervalList = isMixedIn
- ? submixtureSetBuilder.buildIntervalList()
- : info.subclassIntervalList;
- info.subtypeIntervalList = subtypeSetBuilder.buildIntervalList();
+
+ info.superclassIntervalList = superclassSetBuilder.buildIntervalList();
+ info.supertypeIntervalList = supertypeSetBuilder.buildIntervalList();
}
/// Creates a histogram such that index `N` contains the number of classes
- /// that have `N` intervals in its subclass or subtype set (whichever is
- /// larger).
+ /// that have `N` intervals in its supertype set.
///
/// The more numbers are condensed near the beginning, the more efficient the
/// internal data structure is.
List<int> getExpenseHistogram() {
var result = <int>[];
- for (Class class_ in classes) {
+ for (Class class_ in _infoFor.keys) {
var info = _infoFor[class_];
- int intervals = max(info.subclassIntervalList.length,
- info.subtypeIntervalList.length) ~/
- 2;
+ int intervals = info.supertypeIntervalList.length ~/ 2;
if (intervals >= result.length) {
int oldLength = result.length;
result.length = intervals + 1;
@@ -1062,29 +1196,30 @@
return result;
}
- /// Returns the average number of intervals per subtype relation (less
+ /// Returns the average number of intervals per supertype relation (less
/// is better, 1.0 is bad).
///
/// This is an estimate of the memory use compared to a data structure that
- /// enumerates all subclass/subtype pairs.
+ /// enumerates all superclass/supertype pairs.
double getCompressionRatio() {
int intervals = 0;
int sizes = 0;
- for (Class class_ in classes) {
+ for (Class class_ in _infoFor.keys) {
var info = _infoFor[class_];
- intervals += (info.subclassIntervalList.length +
- info.subtypeIntervalList.length) ~/
+ intervals += (info.superclassIntervalList.length +
+ info.supertypeIntervalList.length) ~/
2;
- sizes += _intervalListSize(info.subclassIntervalList) +
- _intervalListSize(info.subtypeIntervalList);
+ sizes += _intervalListSize(info.superclassIntervalList) +
+ _intervalListSize(info.supertypeIntervalList);
}
+
return sizes == 0 ? 1.0 : intervals / sizes;
}
/// Returns the number of entries in hash tables storing hierarchy data.
int getSuperTypeHashTableSize() {
int sum = 0;
- for (Class class_ in classes) {
+ for (Class class_ in _infoFor.keys) {
sum += _infoFor[class_].genericSuperTypes?.length ?? 0;
}
return sum;
@@ -1179,8 +1314,6 @@
class _ClassInfo {
final Class classNode;
int topologicalIndex = 0;
- int topDownIndex = -1;
- bool isBeingVisited = false;
int depth = 0;
// Super types must always occur before subtypes in these lists.
@@ -1191,30 +1324,15 @@
//
// Here `A` must occur before `B` in the list of direct extenders of Object,
// because `B` is a subtype of `A`.
- final List<_ClassInfo> directExtenders = <_ClassInfo>[];
- final List<_ClassInfo> directMixers = <_ClassInfo>[];
- final List<_ClassInfo> directImplementers = <_ClassInfo>[];
+ final Set<_ClassInfo> directExtenders = new LinkedHashSet<_ClassInfo>();
+ final Set<_ClassInfo> directMixers = new LinkedHashSet<_ClassInfo>();
+ final Set<_ClassInfo> directImplementers = new LinkedHashSet<_ClassInfo>();
- /// Top-down indices of all subclasses of this class, represented as
- /// interleaved begin/end interval end points.
- Uint32List subclassIntervalList;
- Uint32List submixtureIntervalList;
- Uint32List subtypeIntervalList;
+ Uint32List superclassIntervalList;
+ Uint32List supertypeIntervalList;
List<_ClassInfo> leastUpperBoundInfos;
- bool isSubclassOf(_ClassInfo other) {
- return _intervalListContains(other.subclassIntervalList, topDownIndex);
- }
-
- bool isSubmixtureOf(_ClassInfo other) {
- return _intervalListContains(other.submixtureIntervalList, topDownIndex);
- }
-
- bool isSubtypeOf(_ClassInfo other) {
- return _intervalListContains(other.subtypeIntervalList, topDownIndex);
- }
-
/// Maps generic supertype classes to the instantiation implemented by this
/// class.
///
@@ -1243,6 +1361,15 @@
_ClassInfo(this.classNode);
+ bool isSubclassOf(_ClassInfo other) {
+ return _intervalListContains(
+ superclassIntervalList, other.topologicalIndex);
+ }
+
+ bool isSubtypeOf(_ClassInfo other) {
+ return _intervalListContains(supertypeIntervalList, other.topologicalIndex);
+ }
+
void recordGenericSuperType(Class cls, Supertype type,
HandleAmbiguousSupertypes onAmbiguousSupertypes) {
List<Supertype> existing = genericSuperTypes[cls];
@@ -1255,79 +1382,23 @@
}
}
-/// An immutable set of classes, internally represented as an interval list.
+/// An immutable set of classes.
class ClassSet extends IterableBase<Class> {
- final ClosedWorldClassHierarchy _hierarchy;
- final Uint32List _intervalList;
+ final Set<Class> _classes;
+ ClassSet(this._classes);
- ClassSet(this._hierarchy, this._intervalList);
-
- bool get isEmpty => _intervalList.isEmpty;
-
- bool get isSingleton {
- var list = _intervalList;
- return list.length == 2 && list[0] + 1 == list[1];
- }
-
- @override
bool contains(Object class_) {
- return _intervalListContains(
- _intervalList, _hierarchy._infoFor[class_ as Class].topDownIndex);
+ return _classes.contains(_classes);
}
ClassSet union(ClassSet other) {
- assert(_hierarchy == other._hierarchy);
- if (identical(_intervalList, other._intervalList)) return this;
- _IntervalListBuilder builder = new _IntervalListBuilder();
- builder.addIntervalList(_intervalList);
- builder.addIntervalList(other._intervalList);
- return new ClassSet(_hierarchy, builder.buildIntervalList());
+ Set<Class> result = new Set<Class>.from(_classes);
+ result.addAll(other._classes);
+ return new ClassSet(result);
}
@override
- Iterator<Class> get iterator =>
- new _ClassSetIterator(_hierarchy, _intervalList);
-}
-
-/// Iterator for [ClassSet].
-class _ClassSetIterator implements Iterator<Class> {
- final ClosedWorldClassHierarchy _hierarchy;
- final Uint32List _intervalList;
- int _intervalIndex;
- int _classIndex;
- int _classIndexLimit;
-
- // Interval list is a list of pairs (start, end).
- static const int _intervalIndexStep = 2;
-
- _ClassSetIterator(this._hierarchy, this._intervalList)
- : _intervalIndex = -_intervalIndexStep,
- _classIndex = -1,
- _classIndexLimit = -1;
-
- @override
- bool moveNext() {
- if (_classIndex + 1 < _classIndexLimit) {
- _classIndex++;
- return true;
- }
-
- if (_intervalIndex + _intervalIndexStep < _intervalList.length) {
- _intervalIndex += _intervalIndexStep;
- _classIndex = _intervalList[_intervalIndex];
- _classIndexLimit = _intervalList[_intervalIndex + 1];
- assert(_classIndex < _classIndexLimit);
- return true;
- }
-
- _classIndex = _classIndexLimit = -1;
- return false;
- }
-
- @override
- Class get current => (_classIndex >= 0)
- ? _hierarchy._classesByTopDownIndex[_classIndex]
- : null;
+ Iterator<Class> get iterator => _classes.iterator;
}
/// Heap for use in computing least upper bounds.
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index c781398..e0fe377 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -62,6 +62,7 @@
Class _noSuchMethodErrorClass;
Constructor _noSuchMethodErrorDefaultConstructor;
Procedure _listFromConstructor;
+ Procedure _listUnmodifiableConstructor;
Procedure _printProcedure;
Procedure _identicalProcedure;
Constructor _constantExpressionErrorDefaultConstructor;
@@ -272,6 +273,11 @@
index.getMember('dart:core', 'List', 'from');
}
+ Procedure get listUnmodifiableConstructor {
+ return _listUnmodifiableConstructor ??=
+ index.getMember('dart:core', 'List', 'unmodifiable');
+ }
+
Class get mapClass {
return _mapClass ??= index.getClass('dart:core', 'Map');
}
diff --git a/pkg/kernel/lib/frontend/accessors.dart b/pkg/kernel/lib/frontend/accessors.dart
deleted file mode 100644
index e132d55..0000000
--- a/pkg/kernel/lib/frontend/accessors.dart
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// A library to help transform compounds and null-aware accessors into
-/// let expressions.
-library kernel.frontend.accessors;
-
-import '../ast.dart';
-
-final Name indexGetName = new Name("[]");
-
-final Name indexSetName = new Name("[]=");
-
-/// An [Accessor] represents a subexpression for which we can't yet build a
-/// kernel [Expression] because we don't yet know the context in which it is
-/// used.
-///
-/// Once the context is known, an [Accessor] can be converted into an
-/// [Expression] by calling a "build" method.
-///
-/// For example, when building a kernel representation for `a[x] = b`, after
-/// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
-/// generate an invocation of `operator[]` or `operator[]=`, so we generate an
-/// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be
-/// called.
-abstract class Accessor {
- final int offset;
-
- // [builtBinary] and [builtGetter] capture the inner nodes. Used by
- // dart2js+rasta for determining how subexpressions map to legacy dart2js Ast
- // nodes. This will be removed once dart2js type analysis (aka inference) is
- // reimplemented on kernel.
- Expression builtBinary;
- Expression builtGetter;
-
- Accessor(this.offset);
-
- /// Builds an [Expression] representing a read from the accessor.
- Expression buildSimpleRead() {
- return _finish(_makeSimpleRead());
- }
-
- /// Builds an [Expression] representing an assignment with the accessor on
- /// the LHS and [value] on the RHS.
- ///
- /// The returned expression evaluates to the assigned value, unless
- /// [voidContext] is true, in which case it may evaluate to anything.
- Expression buildAssignment(Expression value, {bool voidContext: false}) {
- return _finish(_makeSimpleWrite(value, voidContext));
- }
-
- /// Returns an [Expression] representing a null-aware assignment (`??=`) with
- /// the accessor on the LHS and [value] on the RHS.
- ///
- /// The returned expression evaluates to the assigned value, unless
- /// [voidContext] is true, in which case it may evaluate to anything.
- ///
- /// [type] is the static type of the RHS.
- Expression buildNullAwareAssignment(Expression value, DartType type,
- {bool voidContext: false}) {
- if (voidContext) {
- return _finish(new ConditionalExpression(buildIsNull(_makeRead()),
- _makeWrite(value, false), new NullLiteral(), type));
- }
- var tmp = new VariableDeclaration.forValue(_makeRead());
- return _finish(makeLet(
- tmp,
- new ConditionalExpression(buildIsNull(new VariableGet(tmp)),
- _makeWrite(value, false), new VariableGet(tmp), type)));
- }
-
- /// Returns an [Expression] representing a compound assignment (e.g. `+=`)
- /// with the accessor on the LHS and [value] on the RHS.
- Expression buildCompoundAssignment(Name binaryOperator, Expression value,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- return _finish(_makeWrite(
- builtBinary = makeBinary(
- _makeRead(), binaryOperator, interfaceTarget, value,
- offset: offset),
- voidContext));
- }
-
- /// Returns an [Expression] representing a pre-increment or pre-decrement
- /// of the accessor.
- Expression buildPrefixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- return buildCompoundAssignment(binaryOperator, new IntLiteral(1),
- offset: offset,
- voidContext: voidContext,
- interfaceTarget: interfaceTarget);
- }
-
- /// Returns an [Expression] representing a post-increment or post-decrement
- /// of the accessor.
- Expression buildPostfixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- if (voidContext) {
- return buildPrefixIncrement(binaryOperator,
- offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
- }
- var value = new VariableDeclaration.forValue(_makeRead());
- valueAccess() => new VariableGet(value);
- var dummy = new VariableDeclaration.forValue(_makeWrite(
- builtBinary = makeBinary(
- valueAccess(), binaryOperator, interfaceTarget, new IntLiteral(1),
- offset: offset),
- true));
- return _finish(makeLet(value, makeLet(dummy, valueAccess())));
- }
-
- Expression _makeSimpleRead() => _makeRead();
-
- Expression _makeSimpleWrite(Expression value, bool voidContext) {
- return _makeWrite(value, voidContext);
- }
-
- Expression _makeRead();
-
- Expression _makeWrite(Expression value, bool voidContext);
-
- Expression _finish(Expression body) => body;
-
- /// Returns an [Expression] representing a compile-time error.
- makeInvalidRead() => new InvalidExpression(null);
-
- /// Returns an [Expression] representing a compile-time error wrapping
- /// [value].
- ///
- /// The expression will be a compile-time error but will contain [value] as a
- /// subexpression before the compile-time error.
- makeInvalidWrite(Expression value) => wrapInvalid(value);
-}
-
-class VariableAccessor extends Accessor {
- VariableDeclaration variable;
- DartType promotedType;
-
- VariableAccessor(this.variable, this.promotedType, int offset)
- : super(offset);
-
- _makeRead() => new VariableGet(variable, promotedType)..fileOffset = offset;
-
- _makeWrite(Expression value, bool voidContext) {
- return variable.isFinal || variable.isConst
- ? makeInvalidWrite(value)
- : new VariableSet(variable, value)
- ..fileOffset = offset;
- }
-}
-
-class PropertyAccessor extends Accessor {
- VariableDeclaration _receiverVariable;
- Expression receiver;
- Name name;
- Member getter, setter;
-
- static Accessor make(
- Expression receiver, Name name, Member getter, Member setter,
- {int offset: TreeNode.noOffset}) {
- if (receiver is ThisExpression) {
- return new ThisPropertyAccessor(name, getter, setter, offset);
- } else {
- return new PropertyAccessor.internal(
- receiver, name, getter, setter, offset);
- }
- }
-
- PropertyAccessor.internal(
- this.receiver, this.name, this.getter, this.setter, int offset)
- : super(offset);
-
- _makeSimpleRead() =>
- new PropertyGet(receiver, name, getter)..fileOffset = offset;
-
- _makeSimpleWrite(Expression value, bool voidContext) {
- return new PropertySet(receiver, name, value, setter)..fileOffset = offset;
- }
-
- receiverAccess() {
- _receiverVariable ??= new VariableDeclaration.forValue(receiver);
- return new VariableGet(_receiverVariable)..fileOffset = offset;
- }
-
- _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter)
- ..fileOffset = offset;
-
- _makeWrite(Expression value, bool voidContext) {
- return new PropertySet(receiverAccess(), name, value, setter)
- ..fileOffset = offset;
- }
-
- _finish(Expression body) => makeLet(_receiverVariable, body);
-}
-
-/// Special case of [PropertyAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisPropertyAccessor extends Accessor {
- Name name;
- Member getter, setter;
-
- ThisPropertyAccessor(this.name, this.getter, this.setter, int offset)
- : super(offset);
-
- _makeRead() => builtGetter =
- new PropertyGet(new ThisExpression(), name, getter)..fileOffset = offset;
-
- _makeWrite(Expression value, bool voidContext) {
- return new PropertySet(new ThisExpression(), name, value, setter)
- ..fileOffset = offset;
- }
-}
-
-class NullAwarePropertyAccessor extends Accessor {
- VariableDeclaration receiver;
- Name name;
- Member getter, setter;
- DartType type;
-
- NullAwarePropertyAccessor(Expression receiver, this.name, this.getter,
- this.setter, this.type, int offset)
- : this.receiver = makeOrReuseVariable(receiver),
- super(offset);
-
- receiverAccess() => new VariableGet(receiver);
-
- _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter);
-
- _makeWrite(Expression value, bool voidContext) {
- return new PropertySet(receiverAccess(), name, value, setter);
- }
-
- _finish(Expression body) => makeLet(
- receiver,
- new ConditionalExpression(
- buildIsNull(receiverAccess()), new NullLiteral(), body, type));
-}
-
-class SuperPropertyAccessor extends Accessor {
- Name name;
- Member getter, setter;
-
- SuperPropertyAccessor(this.name, this.getter, this.setter, int offset)
- : super(offset);
-
- _makeRead() {
- if (getter == null) return makeInvalidRead();
- // TODO(ahe): Use [DirectPropertyGet] when possible.
- return builtGetter = new SuperPropertyGet(name, getter)
- ..fileOffset = offset;
- }
-
- _makeWrite(Expression value, bool voidContext) {
- if (setter == null) return makeInvalidWrite(value);
- // TODO(ahe): Use [DirectPropertySet] when possible.
- return new SuperPropertySet(name, value, setter)..fileOffset = offset;
- }
-}
-
-class IndexAccessor extends Accessor {
- Expression receiver;
- Expression index;
- VariableDeclaration receiverVariable;
- VariableDeclaration indexVariable;
- Procedure getter, setter;
-
- static Accessor make(
- Expression receiver, Expression index, Procedure getter, Procedure setter,
- {int offset: TreeNode.noOffset}) {
- if (receiver is ThisExpression) {
- return new ThisIndexAccessor(index, getter, setter, offset);
- } else {
- return new IndexAccessor.internal(
- receiver, index, getter, setter, offset);
- }
- }
-
- IndexAccessor.internal(
- this.receiver, this.index, this.getter, this.setter, int offset)
- : super(offset);
-
- _makeSimpleRead() => new MethodInvocation(
- receiver, indexGetName, new Arguments(<Expression>[index]), getter)
- ..fileOffset = offset;
-
- _makeSimpleWrite(Expression value, bool voidContext) {
- if (!voidContext) return _makeWriteAndReturn(value);
- return new MethodInvocation(receiver, indexSetName,
- new Arguments(<Expression>[index, value]), setter)
- ..fileOffset = offset;
- }
-
- receiverAccess() {
- // We cannot reuse the receiver if it is a variable since it might be
- // reassigned in the index expression.
- receiverVariable ??= new VariableDeclaration.forValue(receiver);
- return new VariableGet(receiverVariable)..fileOffset = offset;
- }
-
- indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable)..fileOffset = offset;
- }
-
- _makeRead() {
- return builtGetter = new MethodInvocation(receiverAccess(), indexGetName,
- new Arguments(<Expression>[indexAccess()]), getter)
- ..fileOffset = offset;
- }
-
- _makeWrite(Expression value, bool voidContext) {
- if (!voidContext) return _makeWriteAndReturn(value);
- return new MethodInvocation(receiverAccess(), indexSetName,
- new Arguments(<Expression>[indexAccess(), value]), setter)
- ..fileOffset = offset;
- }
-
- // TODO(dmitryas): remove this method after the "[]=" operator of the Context
- // class is made to return a value.
- _makeWriteAndReturn(Expression value) {
- // The call to []= does not return the value like direct-style assignments
- // do. We need to bind the value in a let.
- var valueVariable = new VariableDeclaration.forValue(value);
- var dummy = new VariableDeclaration.forValue(new MethodInvocation(
- receiverAccess(),
- indexSetName,
- new Arguments(
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- setter)
- ..fileOffset = offset);
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
- Expression _finish(Expression body) {
- return makeLet(receiverVariable, makeLet(indexVariable, body));
- }
-}
-
-/// Special case of [IndexAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisIndexAccessor extends Accessor {
- Expression index;
- VariableDeclaration indexVariable;
- Procedure getter, setter;
-
- ThisIndexAccessor(this.index, this.getter, this.setter, int offset)
- : super(offset);
-
- _makeSimpleRead() {
- return new MethodInvocation(new ThisExpression(), indexGetName,
- new Arguments(<Expression>[index]), getter);
- }
-
- _makeSimpleWrite(Expression value, bool voidContext) {
- if (!voidContext) return _makeWriteAndReturn(value);
- return new MethodInvocation(new ThisExpression(), indexSetName,
- new Arguments(<Expression>[index, value]), setter);
- }
-
- indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable);
- }
-
- _makeRead() => builtGetter = new MethodInvocation(new ThisExpression(),
- indexGetName, new Arguments(<Expression>[indexAccess()]), getter);
-
- _makeWrite(Expression value, bool voidContext) {
- if (!voidContext) return _makeWriteAndReturn(value);
- return new MethodInvocation(new ThisExpression(), indexSetName,
- new Arguments(<Expression>[indexAccess(), value]), setter);
- }
-
- _makeWriteAndReturn(Expression value) {
- var valueVariable = new VariableDeclaration.forValue(value);
- var dummy = new VariableDeclaration.forValue(new MethodInvocation(
- new ThisExpression(),
- indexSetName,
- new Arguments(
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- setter));
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
- Expression _finish(Expression body) => makeLet(indexVariable, body);
-}
-
-class SuperIndexAccessor extends Accessor {
- Expression index;
- VariableDeclaration indexVariable;
- Member getter, setter;
-
- SuperIndexAccessor(this.index, this.getter, this.setter, int offset)
- : super(offset);
-
- indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable);
- }
-
- _makeSimpleRead() => new SuperMethodInvocation(
- indexGetName, new Arguments(<Expression>[index]), getter);
-
- _makeSimpleWrite(Expression value, bool voidContext) {
- if (!voidContext) return _makeWriteAndReturn(value);
- return new SuperMethodInvocation(
- indexSetName, new Arguments(<Expression>[index, value]), setter);
- }
-
- _makeRead() {
- return builtGetter = new SuperMethodInvocation(
- indexGetName, new Arguments(<Expression>[indexAccess()]), getter);
- }
-
- _makeWrite(Expression value, bool voidContext) {
- if (!voidContext) return _makeWriteAndReturn(value);
- return new SuperMethodInvocation(indexSetName,
- new Arguments(<Expression>[indexAccess(), value]), setter);
- }
-
- _makeWriteAndReturn(Expression value) {
- var valueVariable = new VariableDeclaration.forValue(value);
- var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation(
- indexSetName,
- new Arguments(
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- setter));
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
- Expression _finish(Expression body) {
- return makeLet(indexVariable, body);
- }
-}
-
-class StaticAccessor extends Accessor {
- Member readTarget;
- Member writeTarget;
-
- StaticAccessor(this.readTarget, this.writeTarget, int offset) : super(offset);
-
- _makeRead() => builtGetter =
- readTarget == null ? makeInvalidRead() : new StaticGet(readTarget)
- ..fileOffset = offset;
-
- _makeWrite(Expression value, bool voidContext) {
- return writeTarget == null
- ? makeInvalidWrite(value)
- : new StaticSet(writeTarget, value)
- ..fileOffset = offset;
- }
-}
-
-class ReadOnlyAccessor extends Accessor {
- Expression expression;
- VariableDeclaration value;
-
- ReadOnlyAccessor(this.expression, int offset) : super(offset);
-
- _makeSimpleRead() => expression;
-
- _makeRead() {
- value ??= new VariableDeclaration.forValue(expression);
- return new VariableGet(value);
- }
-
- _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value);
-
- Expression _finish(Expression body) => makeLet(value, body);
-}
-
-Expression makeLet(VariableDeclaration variable, Expression body) {
- if (variable == null) return body;
- return new Let(variable, body);
-}
-
-Expression makeBinary(
- Expression left, Name operator, Procedure interfaceTarget, Expression right,
- {int offset: TreeNode.noOffset}) {
- return new MethodInvocation(
- left, operator, new Arguments(<Expression>[right]), interfaceTarget)
- ..fileOffset = offset;
-}
-
-final Name _equalOperator = new Name('==');
-
-Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) {
- return makeBinary(value, _equalOperator, null, new NullLiteral(),
- offset: offset);
-}
-
-VariableDeclaration makeOrReuseVariable(Expression value) {
- // TODO: Devise a way to remember if a variable declaration was reused
- // or is fresh (hence needs a let binding).
- return new VariableDeclaration.forValue(value);
-}
-
-Expression wrapInvalid(Expression e) {
- return new Let(
- new VariableDeclaration.forValue(e), new InvalidExpression(null));
-}
diff --git a/pkg/kernel/lib/frontend/readme.md b/pkg/kernel/lib/frontend/readme.md
deleted file mode 100644
index 53037ab..0000000
--- a/pkg/kernel/lib/frontend/readme.md
+++ /dev/null
@@ -1 +0,0 @@
-Utility method to help the frontend generate kernel IR.
diff --git a/pkg/kernel/lib/frontend/super_initializers.dart b/pkg/kernel/lib/frontend/super_initializers.dart
deleted file mode 100644
index 0dd3925..0000000
--- a/pkg/kernel/lib/frontend/super_initializers.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// A library to help move super calls last in the initializer list.
-library kernel.frontend.super_calls;
-
-import '../ast.dart';
-
-/// Mutates the initializer list of [node] so that its super initializer occurs
-/// last, while its arguments are evaluated at the correct place.
-///
-/// Does nothing if there is no super initializer or if it is already last.
-void moveSuperInitializerLast(Constructor node) {
- List<Initializer> initializers = node.initializers;
- if (initializers.isEmpty) return;
- if (initializers.last is SuperInitializer) return;
- int superIndex = -1;
- for (int i = initializers.length - 1; i >= 0; --i) {
- Initializer initializer = initializers[i];
- if (initializer is SuperInitializer) {
- superIndex = i;
- break;
- }
- }
- if (superIndex == -1) return;
- SuperInitializer superCall = initializers[superIndex];
- Arguments arguments = superCall.arguments;
- int argumentCount = arguments.positional.length + arguments.named.length;
-
- // We move all initializers after the super call to the place where the super
- // call was, but reserve [argumentCount] slots before that for
- // [LocalInitializer]s.
- initializers.length += argumentCount;
- initializers.setRange(
- superIndex + argumentCount, // destination start (inclusive)
- initializers.length - 1, // destination end (exclusive)
- initializers, // source list
- superIndex + 1); // source start index
- initializers[initializers.length - 1] = superCall;
-
- // Fill in the [argumentCount] reserved slots with the evaluation expressions
- // of the arguments to the super constructor call.
- int storeIndex = superIndex;
- for (int i = 0; i < arguments.positional.length; ++i) {
- var variable = new VariableDeclaration.forValue(arguments.positional[i]);
- arguments.positional[i] = new VariableGet(variable)..parent = arguments;
- initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
- }
- for (int i = 0; i < arguments.named.length; ++i) {
- NamedExpression argument = arguments.named[i];
- var variable = new VariableDeclaration.forValue(argument.value);
- arguments.named[i].value = new VariableGet(variable)..parent = argument;
- initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
- }
-}
diff --git a/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart b/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart
index e448297..d676aeb 100644
--- a/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart
+++ b/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart
@@ -80,7 +80,7 @@
: inputFile = new File(inputFilename),
outputFile = new File(outputFilename) {
// Clear the output file at start.
- outputFile.writeAsStringSync("", mode: FileMode.WRITE, flush: true);
+ outputFile.writeAsStringSync("", mode: FileMode.write, flush: true);
}
//LATEX-NEXT
@@ -133,7 +133,7 @@
outputLines.add(r"\end{verbatim}");
}
for (String line in outputLines) {
- outputFile.writeAsStringSync("$line\n", mode: FileMode.APPEND);
+ outputFile.writeAsStringSync("$line\n", mode: FileMode.append);
}
}
@@ -180,7 +180,7 @@
: endIndex;
outputFile.writeAsStringSync(
input.substring(latexBeginIndex, latexEndIndex) + "\n",
- mode: FileMode.APPEND);
+ mode: FileMode.append);
input = input.substring(endIndex);
}
}
diff --git a/pkg/kernel/lib/kernel.dart b/pkg/kernel/lib/kernel.dart
index 5ffbd41..aa2a903 100644
--- a/pkg/kernel/lib/kernel.dart
+++ b/pkg/kernel/lib/kernel.dart
@@ -33,6 +33,12 @@
return component;
}
+Component loadComponentSourceFromBytes(List<int> bytes, [Component component]) {
+ component ??= new Component();
+ new BinaryBuilder(bytes).readComponentSource(component);
+ return component;
+}
+
Future writeComponentToBinary(Component component, String path) {
var sink;
if (path == 'null' || path == 'stdout') {
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 1f49bf5..6b03c7e 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -9,8 +9,6 @@
import '../transformations/treeshaker.dart' show ProgramRoot;
import 'flutter.dart' show FlutterTarget;
import 'vm.dart' show VmTarget;
-import 'vmcc.dart' show VmClosureConvertedTarget;
-import 'vmreify.dart' show VmGenericTypesReifiedTarget;
final List<String> targetNames = targets.keys.toList();
@@ -36,8 +34,6 @@
final Map<String, _TargetBuilder> targets = <String, _TargetBuilder>{
'none': (TargetFlags flags) => new NoneTarget(flags),
'vm': (TargetFlags flags) => new VmTarget(flags),
- 'vmcc': (TargetFlags flags) => new VmClosureConvertedTarget(flags),
- 'vmreify': (TargetFlags flags) => new VmGenericTypesReifiedTarget(flags),
'flutter': (TargetFlags flags) => new FlutterTarget(flags),
};
diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart
index e79a78c..eea56a4 100644
--- a/pkg/kernel/lib/target/vm.dart
+++ b/pkg/kernel/lib/target/vm.dart
@@ -98,11 +98,12 @@
new Arguments(<Expression>[
new StringLiteral(name)..fileOffset = offset,
_fixedLengthList(
+ coreTypes,
coreTypes.typeClass.rawType,
arguments.types.map((t) => new TypeLiteral(t)).toList(),
arguments.fileOffset),
- _fixedLengthList(
- const DynamicType(), arguments.positional, arguments.fileOffset),
+ _fixedLengthList(coreTypes, const DynamicType(), arguments.positional,
+ arguments.fileOffset),
new StaticInvocation(
coreTypes.mapUnmodifiable,
new Arguments([
@@ -115,6 +116,9 @@
})), keyType: coreTypes.symbolClass.rawType)
..isConst = (arguments.named.length == 0)
..fileOffset = arguments.fileOffset
+ ], types: [
+ coreTypes.symbolClass.rawType,
+ new DynamicType()
]))
..fileOffset = arguments.fileOffset,
new BoolLiteral(isSuper)..fileOffset = arguments.fileOffset
@@ -156,11 +160,12 @@
new SymbolLiteral(name)..fileOffset = offset,
new IntLiteral(type)..fileOffset = offset,
_fixedLengthList(
+ coreTypes,
coreTypes.typeClass.rawType,
arguments.types.map((t) => new TypeLiteral(t)).toList(),
arguments.fileOffset),
- _fixedLengthList(const DynamicType(), arguments.positional,
- arguments.fileOffset),
+ _fixedLengthList(coreTypes, const DynamicType(),
+ arguments.positional, arguments.fileOffset),
new StaticInvocation(
coreTypes.mapUnmodifiable,
new Arguments([
@@ -252,8 +257,8 @@
return type;
}
- Expression _fixedLengthList(
- DartType typeArgument, List<Expression> elements, int offset) {
+ Expression _fixedLengthList(CoreTypes coreTypes, DartType typeArgument,
+ List<Expression> elements, int offset) {
// TODO(ahe): It's possible that it would be better to create a fixed-length
// list first, and then populate it. That would create fewer objects. But as
// this is currently only used in (statically resolved) no-such-method
@@ -264,12 +269,13 @@
return new ListLiteral([], typeArgument: typeArgument)..isConst = true;
}
- return new MethodInvocation(
- new ListLiteral(elements, typeArgument: typeArgument)
- ..fileOffset = offset,
- new Name("toList"),
- new Arguments(<Expression>[], named: <NamedExpression>[
- new NamedExpression("growable", new BoolLiteral(false))
+ return new StaticInvocation(
+ coreTypes.listUnmodifiableConstructor,
+ new Arguments([
+ new ListLiteral(elements, typeArgument: typeArgument)
+ ..fileOffset = offset
+ ], types: [
+ new DynamicType()
]));
}
diff --git a/pkg/kernel/lib/target/vmcc.dart b/pkg/kernel/lib/target/vmcc.dart
deleted file mode 100644
index a5f6a14..0000000
--- a/pkg/kernel/lib/target/vmcc.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library kernel.target.vmcc;
-
-import '../ast.dart' show Component, Library;
-import '../core_types.dart' show CoreTypes;
-import '../class_hierarchy.dart';
-import '../transformations/continuation.dart' as cont;
-import '../transformations/mixin_full_resolution.dart' as mix;
-import '../transformations/sanitize_for_vm.dart';
-import '../transformations/treeshaker.dart';
-import '../transformations/closure_conversion.dart' as cc
- show transformComponent;
-import 'targets.dart' show TargetFlags;
-import 'vm.dart' as vm_target;
-
-// VmClosureConvertedTarget used legacy VmTarget which was superseded by
-// VmFastaTarget. Legacy transformations pipeline was pulled from VmTarget
-// into this class when VmTarget was merged with new VmFastaTarget.
-// TODO(alexmarkov): Figure out if this target is still used, and either remove
-// it or unify its transformation pipeline with new VmTarget.
-class VmClosureConvertedTarget extends vm_target.VmTarget {
- VmClosureConvertedTarget(TargetFlags flags) : super(flags);
-
- @override
- String get name => "vmcc";
-
- ClassHierarchy _hierarchy;
-
- @override
- void performModularTransformationsOnLibraries(
- CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
- {void logger(String msg)}) {
- var mixins = new mix.MixinFullResolution(this, coreTypes, hierarchy)
- ..transform(libraries);
-
- _hierarchy = mixins.hierarchy;
- }
-
- @override
- void performGlobalTransformations(CoreTypes coreTypes, Component component,
- {void logger(String msg)}) {
- if (flags.treeShake) {
- performTreeShaking(coreTypes, component);
- }
-
- cont.transformComponent(coreTypes, component, flags.syncAsync);
-
- new SanitizeForVM().transform(component);
-
- cc.transformComponent(coreTypes, component);
- }
-
- void performTreeShaking(CoreTypes coreTypes, Component component) {
- new TreeShaker(coreTypes, _hierarchy, component,
- strongMode: strongMode, programRoots: flags.programRoots)
- .transform(component);
- _hierarchy = null; // Hierarchy must be recomputed.
- }
-}
diff --git a/pkg/kernel/lib/target/vmreify.dart b/pkg/kernel/lib/target/vmreify.dart
deleted file mode 100644
index 681c760..0000000
--- a/pkg/kernel/lib/target/vmreify.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library kernel.target.vmreify;
-
-import '../ast.dart' show Component;
-import '../core_types.dart' show CoreTypes;
-import '../transformations/generic_types_reification.dart' as reify
- show transformComponent;
-import 'targets.dart' show TargetFlags;
-import 'vmcc.dart' as vmcc_target;
-
-/// Specializes the kernel IR to the Dart VM with reified generic types.
-class VmGenericTypesReifiedTarget extends vmcc_target.VmClosureConvertedTarget {
- VmGenericTypesReifiedTarget(TargetFlags flags) : super(flags);
-
- @override
- String get name => "vmreify";
-
- // This is the order that bootstrap libraries are loaded according to
- // `runtime/vm/object_store.h`.
- List<String> get extraRequiredLibraries {
- return new List<String>.from(super.extraRequiredLibraries)
- ..add("${flags.kernelRuntime.resolve('reify/types.dart')}")
- ..add("${flags.kernelRuntime.resolve('reify/declarations.dart')}")
- ..add("${flags.kernelRuntime.resolve('reify/interceptors.dart')}");
- }
-
- @override
- void performGlobalTransformations(CoreTypes coreTypes, Component component,
- {void logger(String msg)}) {
- super.performGlobalTransformations(coreTypes, component);
- // TODO(dmitryas) this transformation should be made modular
- reify.transformComponent(coreTypes, component);
- }
-
- // Disable tree shaking for Generic Types Reification. There are some runtime
- // libraries that are required for the transformation and are shaken off,
- // because they aren't invoked from the component being transformed prior to
- // the transformation.
- // TODO(dmitryas): remove this when the libraries are in dart:_internal
- @override
- void performTreeShaking(CoreTypes coreTypes, Component component) {}
-}
diff --git a/pkg/kernel/lib/transformations/closure/clone_without_body.dart b/pkg/kernel/lib/transformations/closure/clone_without_body.dart
deleted file mode 100644
index 1e4b344..0000000
--- a/pkg/kernel/lib/transformations/closure/clone_without_body.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.closure.converter;
-
-export '../../clone.dart' show CloneWithoutBody;
diff --git a/pkg/kernel/lib/transformations/closure/context.dart b/pkg/kernel/lib/transformations/closure/context.dart
deleted file mode 100644
index ee8fc67..0000000
--- a/pkg/kernel/lib/transformations/closure/context.dart
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.closure.context;
-
-import '../../ast.dart'
- show
- Expression,
- FunctionNode,
- NullLiteral,
- StringLiteral,
- Throw,
- TreeNode,
- VariableDeclaration,
- VariableGet,
- VariableSet,
- VectorCreation,
- VectorGet,
- VectorSet,
- VectorCopy;
-
-import '../../frontend/accessors.dart' show Accessor, VariableAccessor;
-
-import 'converter.dart' show ClosureConverter;
-
-abstract class Context {
- /// Returns a new expression for accessing this context.
- Expression get expression;
-
- /// Returns an accessor (or null) for accessing this context.
- Accessor get accessor;
-
- /// Extend the context to include [variable] initialized to [value]. For
- /// example, this replaces the [VariableDeclaration] node of a captured local
- /// variable.
- ///
- /// This may create a new context and update the `context` field of the
- /// current [ClosureConverter].
- // TODO(ahe): Return context instead?
- void extend(VariableDeclaration variable, Expression value);
-
- /// Update the initializer [value] of [variable] which was previously added
- /// with [extend]. This is used when [value] isn't available when the context
- /// was extended.
- void update(VariableDeclaration variable, Expression value) {
- throw "not supported $runtimeType";
- }
-
- /// Returns a new expression for reading the value of [variable] from this
- /// context. For example, for replacing a [VariableGet] of a captured local
- /// variable.
- Expression lookup(VariableDeclaration variable);
-
- /// Returns a new expression which stores [value] in [variable] in this
- /// context. For example, for replacing a [VariableSet] of a captured local
- /// variable.
- Expression assign(VariableDeclaration variable, Expression value,
- {bool voidContext: false});
-
- /// Returns a new context whose parent is this context. The optional argument
- /// [accessor] controls how the nested context access this context. This is
- /// used, for example, when hoisting a local function. In this case, access
- /// to this context can't be accessed directly via [expression]. In other
- /// cases, for example, a for-loop, this context is still in scope and can be
- /// accessed directly (with [accessor]).
- Context toNestedContext([Accessor accessor]);
-
- /// Returns a new expression which will copy this context and store the copy
- /// in the local variable currently holding this context.
- Expression clone() {
- return new Throw(
- new StringLiteral("Context clone not implemented for ${runtimeType}"));
- }
-}
-
-class NoContext extends Context {
- final ClosureConverter converter;
-
- NoContext(this.converter);
-
- Expression get expression => new NullLiteral();
-
- Accessor get accessor => null;
-
- void extend(VariableDeclaration variable, Expression value) {
- converter.context = new LocalContext(converter, this)
- ..extend(variable, value);
- }
-
- Expression lookup(VariableDeclaration variable) {
- throw 'Unbound NoContext.lookup($variable)';
- }
-
- Expression assign(VariableDeclaration variable, Expression value,
- {bool voidContext: false}) {
- throw 'Unbound NoContext.assign($variable, ...)';
- }
-
- Context toNestedContext([Accessor accessor]) {
- return new NestedContext(
- converter, accessor, <List<VariableDeclaration>>[]);
- }
-}
-
-class LocalContext extends Context {
- final ClosureConverter converter;
- final Context parent;
- final VariableDeclaration self;
- final VectorCreation vectorCreation;
- final List<VariableDeclaration> variables = <VariableDeclaration>[];
- final Map<VariableDeclaration, VectorSet> initializers =
- <VariableDeclaration, VectorSet>{};
-
- LocalContext._internal(
- this.converter, this.parent, this.self, this.vectorCreation);
-
- factory LocalContext(ClosureConverter converter, Context parent) {
- converter.rewriter.insertContextDeclaration(parent.expression);
-
- return new LocalContext._internal(
- converter,
- parent,
- converter.rewriter.contextDeclaration,
- converter.rewriter.vectorCreation);
- }
-
- Expression get expression => accessor.buildSimpleRead();
-
- Accessor get accessor => new VariableAccessor(self, null, TreeNode.noOffset);
-
- void extend(VariableDeclaration variable, Expression value) {
- // Increase index by 2, because the type arguments vector occupies position
- // 0, the parent occupies position 1, and all other variables are therefore
- // shifted by 2.
- VectorSet initializer =
- new VectorSet(expression, variables.length + 2, value);
- value.parent = initializer;
-
- converter.rewriter.insertExtendContext(initializer);
- if (variable.parent is FunctionNode) {
- converter.rewriter.insertZeroOutParameter(variable);
- }
-
- ++vectorCreation.length;
- variables.add(variable);
- initializers[variable] = initializer;
- }
-
- void update(VariableDeclaration variable, Expression value) {
- VectorSet initializer = initializers[variable];
- initializer.value = value;
- value.parent = initializer;
- }
-
- Expression lookup(VariableDeclaration variable) {
- var index = variables.indexOf(variable);
- // Increase index by 2 in case of success, because the type arguments vector
- // occupies position 0, the parent occupies position 1, and all other
- // variables are therefore shifted by 2.
- return index == -1
- ? parent.lookup(variable)
- : new VectorGet(expression, index + 2);
- }
-
- Expression assign(VariableDeclaration variable, Expression value,
- {bool voidContext: false}) {
- var index = variables.indexOf(variable);
- // Increase index by 2 in case of success, because the type arguments vector
- // occupies position 0, the parent occupies position 1, and all other
- // variables are therefore shifted by 2.
- return index == -1
- ? parent.assign(variable, value, voidContext: voidContext)
- : new VectorSet(expression, index + 2, value);
- }
-
- Context toNestedContext([Accessor accessor]) {
- accessor ??= this.accessor;
- List<List<VariableDeclaration>> variabless = <List<VariableDeclaration>>[];
- var current = this;
- while (current != null && current is! NoContext) {
- if (current is LocalContext) {
- variabless.add(current.variables);
- current = current.parent;
- } else if (current is NestedContext) {
- variabless.addAll((current as NestedContext).variabless);
- current = null;
- }
- }
- return new NestedContext(converter, accessor, variabless);
- }
-
- Expression clone() {
- self.isFinal = false;
- return new VariableSet(self, new VectorCopy(new VariableGet(self)));
- }
-}
-
-class NestedContext extends Context {
- final ClosureConverter converter;
- final Accessor accessor;
- final List<List<VariableDeclaration>> variabless;
-
- NestedContext(this.converter, this.accessor, this.variabless);
-
- Expression get expression {
- return accessor?.buildSimpleRead() ?? new NullLiteral();
- }
-
- void extend(VariableDeclaration variable, Expression value) {
- converter.context = new LocalContext(converter, this)
- ..extend(variable, value);
- }
-
- Expression lookup(VariableDeclaration variable) {
- Expression context = expression;
- for (var variables in variabless) {
- var index = variables.indexOf(variable);
- if (index != -1) {
- // Increase index by 2 in case of success, because the type arguments
- // vector occupies position 0, the parent occupies item 1, and all other
- // variables are therefore shifted by 2.
- return new VectorGet(context, index + 2);
- }
- // Item 1 of a context always points to its parent.
- context = new VectorGet(context, 1);
- }
- throw 'Unbound NestedContext.lookup($variable)';
- }
-
- Expression assign(VariableDeclaration variable, Expression value,
- {bool voidContext: false}) {
- Expression context = expression;
- for (List<VariableDeclaration> variables in variabless) {
- var index = variables.indexOf(variable);
- if (index != -1) {
- // Increase index by 2 in case of success, because the type arguments
- // vector occupies position 0, the parent occupies item 1, and all other
- // variables are therefore shifted by 2.
- return new VectorSet(context, index + 2, value);
- }
- // Item 1 of a context always points to its parent.
- context = new VectorGet(context, 1);
- }
- throw 'Unbound NestedContext.lookup($variable)';
- }
-
- Context toNestedContext([Accessor accessor]) {
- return new NestedContext(converter, accessor ?? this.accessor, variabless);
- }
-}
diff --git a/pkg/kernel/lib/transformations/closure/converter.dart b/pkg/kernel/lib/transformations/closure/converter.dart
deleted file mode 100644
index dcc7af9..0000000
--- a/pkg/kernel/lib/transformations/closure/converter.dart
+++ /dev/null
@@ -1,848 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.closure.converter;
-
-import '../../ast.dart'
- show
- AsyncMarker,
- Arguments,
- Block,
- Catch,
- Class,
- ClosureCreation,
- Constructor,
- DartType,
- DoStatement,
- DynamicType,
- EmptyStatement,
- Expression,
- ExpressionStatement,
- Field,
- ForInStatement,
- ForStatement,
- FunctionDeclaration,
- FunctionExpression,
- FunctionNode,
- FunctionType,
- Initializer,
- InterfaceType,
- InvalidExpression,
- InvocationExpression,
- Library,
- LocalInitializer,
- RedirectingInitializer,
- Member,
- MethodInvocation,
- Name,
- NamedExpression,
- NamedType,
- NullLiteral,
- Procedure,
- ProcedureKind,
- PropertyGet,
- ReturnStatement,
- Statement,
- StaticInvocation,
- ThisExpression,
- Transformer,
- TreeNode,
- TypeParameter,
- TypeParameterType,
- VariableDeclaration,
- VariableGet,
- VariableSet,
- VectorCreation,
- WhileStatement,
- transformList;
-
-import '../../frontend/accessors.dart' show VariableAccessor;
-
-import '../../clone.dart' show CloneVisitor;
-
-import '../../core_types.dart' show CoreTypes;
-
-import '../../type_algebra.dart' show substitute;
-
-import 'clone_without_body.dart' show CloneWithoutBody;
-
-import 'context.dart' show Context, NoContext, LocalContext;
-
-import 'info.dart' show ClosureInfo;
-
-import 'rewriter.dart' show AstRewriter, BlockRewriter, InitializerListRewriter;
-
-bool isLoop(TreeNode node) {
- return node is WhileStatement ||
- node is DoStatement ||
- node is ForStatement ||
- node is ForInStatement;
-}
-
-class ClosureConverter extends Transformer {
- final CoreTypes coreTypes;
-
- final Set<VariableDeclaration> capturedVariables;
-
- // This map pairs variables that are captured with flags indicating whether
- // they are used inside or outside an initializer. See
- // [ClosureInfo.parameterUses].
- final Map<VariableDeclaration, int> parameterUses;
-
- final Map<FunctionNode, Set<TypeParameter>> capturedTypeVariables;
- final Map<FunctionNode, VariableDeclaration> thisAccess;
- final Map<FunctionNode, String> localNames;
-
- /// Records place-holders for cloning contexts. See [visitForStatement].
- final Set<InvalidExpression> contextClonePlaceHolders =
- new Set<InvalidExpression>();
-
- final CloneVisitor cloner = new CloneWithoutBody();
-
- /// New members to add to [currentLibrary] after it has been
- /// transformed. These members will not be transformed themselves.
- final List<TreeNode> newLibraryMembers = <TreeNode>[];
-
- /// New members to add to [currentClass] after it has been transformed. These
- /// members will not be transformed themselves.
- final List<Member> newClassMembers = <Member>[];
-
- Library currentLibrary;
-
- Class currentClass;
-
- Member currentMember;
-
- FunctionNode currentMemberFunction;
-
- FunctionNode currentFunction;
-
- Context context;
-
- AstRewriter rewriter;
-
- /// TODO(29181): update this comment when the type variables are restored.
- /// Maps original type variable (aka type parameter) to a hoisted type
- /// variable type.
- ///
- /// For example, consider:
- ///
- /// class C<T> {
- /// f() => (x) => x is T;
- /// }
- ///
- /// This is currently converted to:
- ///
- /// class C<T> {
- /// f() => new Closure#0<T>();
- /// }
- /// class Closure#0<T_> implements Function {
- /// call(x) => x is T_;
- /// }
- ///
- /// In this example, `typeSubstitution[T].parameter == T_` when transforming
- /// the closure in `f`.
- Map<TypeParameter, DartType> typeSubstitution =
- const <TypeParameter, DartType>{};
-
- ClosureConverter(this.coreTypes, ClosureInfo info)
- : this.capturedVariables = info.variables,
- this.parameterUses = info.parameterUses,
- this.capturedTypeVariables = info.typeVariables,
- this.thisAccess = info.thisAccess,
- this.localNames = info.localNames;
-
- bool get isOuterMostContext {
- return currentFunction == null || currentMemberFunction == currentFunction;
- }
-
- Uri get currentFileUri {
- if (currentMember is Constructor) return currentClass.fileUri;
- if (currentMember is Field) return (currentMember as Field).fileUri;
- if (currentMember is Procedure) return (currentMember as Procedure).fileUri;
- throw "No file uri for ${currentMember.runtimeType}";
- }
-
- TreeNode saveContext(TreeNode f()) {
- AstRewriter old = rewriter;
- Context savedContext = context;
- try {
- return f();
- } finally {
- rewriter = old;
- context = savedContext;
- }
- }
-
- TreeNode visitLibrary(Library node) {
- assert(newLibraryMembers.isEmpty);
-
- currentLibrary = node;
- node = super.visitLibrary(node);
- for (TreeNode member in newLibraryMembers) {
- if (member is Class) {
- node.addClass(member);
- } else {
- node.addMember(member);
- }
- }
- newLibraryMembers.clear();
- currentLibrary = null;
- return node;
- }
-
- TreeNode visitClass(Class node) {
- assert(newClassMembers.isEmpty);
- currentClass = node;
- node = super.visitClass(node);
- newClassMembers.forEach(node.addMember);
- newClassMembers.clear();
- currentClass = null;
- return node;
- }
-
- extendContextConditionally({bool inInitializer}) {
- return (VariableDeclaration parameter) {
- if (!capturedVariables.contains(parameter)) return 0;
-
- int flags = parameterUses[parameter];
- if (flags == null) {
- context.extend(parameter, new VariableGet(parameter));
- return 0;
- }
-
- // When moving variables into the context while scanning initializers,
- // we need to add the variable if it's captured in an initializer,
- // whether or not it's used/captured in the body. However, in the body,
- // we only need to add the variable into the context if it's *not*
- // captured in an initializer.
- if (inInitializer
- ? (flags & ClosureInfo.INSIDE_INITIALIZER) > 0
- : flags == ClosureInfo.OUTSIDE_INITIALIZER) {
- context.extend(parameter, new VariableGet(parameter));
- }
-
- return flags;
- };
- }
-
- TreeNode visitConstructor(Constructor node) {
- assert(isEmptyContext);
- currentMember = node;
-
- // If we created a context for the initializers, we need to re-use that
- // context in the body of the function. Unfortunately, the context is
- // declared in a local initializer and local initializers aren't visible
- // in the body of the constructor. To work around this issue, we move the
- // body into a new constructor and make this constructor redirect to that
- // one, passing the context as an argument to the new constructor.
- var movingCtor = false;
-
- // Transform initializers.
- if (node.initializers.length > 0) {
- var initRewriter = new InitializerListRewriter(node);
- rewriter = initRewriter;
- context = new NoContext(this);
-
- final int capturedBoth =
- ClosureInfo.OUTSIDE_INITIALIZER | ClosureInfo.INSIDE_INITIALIZER;
-
- // TODO(karlklose): add a fine-grained analysis of captured parameters.
- handleParam(decl) {
- if (extendContextConditionally(inInitializer: true)(decl) ==
- capturedBoth) {
- movingCtor = true;
- }
- }
-
- node.function.positionalParameters.forEach(handleParam);
- node.function.namedParameters.forEach(handleParam);
-
- transformList(node.initializers, this, node);
- node.initializers.insertAll(0, initRewriter.prefix);
- rewriter = null;
- }
-
- // Transform constructor body.
- FunctionNode function = node.function;
- if (function.body != null && function.body is! EmptyStatement) {
- setupRewriterForFunctionBody(function);
- if (!movingCtor) context = new NoContext(this);
- VariableDeclaration self = thisAccess[currentMemberFunction];
- if (self != null) {
- context.extend(self, new ThisExpression());
- }
- node.function.accept(this);
-
- if (movingCtor) {
- var contextDecl = (context as LocalContext).self;
- var newCtorName = new Name("${node.name.name}#redir");
- var newCtor = new Constructor(node.function, name: newCtorName);
- newClassMembers.add(newCtor);
-
- LocalInitializer contextDeclInit = null;
- for (var init in node.initializers) {
- if (init is LocalInitializer && init.variable == contextDecl) {
- contextDeclInit = init;
- } else {
- newCtor.initializers.add(init);
- }
- }
-
- node.initializers = <Initializer>[contextDeclInit];
-
- var cv = new CloneVisitor();
- var oldCtorParams = function.positionalParameters
- .map(cv.visitVariableDeclaration)
- .toList();
- var oldCtorNamedParams =
- function.namedParameters.map(cv.visitVariableDeclaration).toList();
-
- function.positionalParameters.addAll(function.namedParameters);
- function.namedParameters = [];
-
- var args = <Expression>[];
- args.addAll(oldCtorParams.map((decl) => new VariableGet(decl)));
- args.addAll(oldCtorNamedParams.map((decl) => new VariableGet(decl)));
-
- node.function = new FunctionNode(new EmptyStatement(),
- typeParameters: [],
- positionalParameters: oldCtorParams,
- namedParameters: oldCtorNamedParams,
- requiredParameterCount: function.requiredParameterCount,
- returnType: function.returnType,
- asyncMarker: function.asyncMarker,
- dartAsyncMarker: function.dartAsyncMarker);
- node.function.parent = node;
-
- var oldCtorDecl = cv.visitVariableDeclaration(contextDecl);
- contextDecl.initializer = null;
- function.positionalParameters.add(contextDecl);
- function.requiredParameterCount++;
-
- contextDeclInit.variable = oldCtorDecl;
- oldCtorDecl.parent = contextDeclInit;
-
- args.add(new VariableGet(oldCtorDecl));
- var redirInit =
- new RedirectingInitializer(newCtor, new Arguments(args));
- node.initializers.add(redirInit);
- }
- }
- resetContext();
- return node;
- }
-
- AstRewriter makeRewriterForBody(FunctionNode function) {
- Statement body = function.body;
- if (body is! Block) {
- body = new Block(<Statement>[body]);
- function.body = function.body.parent = body;
- }
- return new BlockRewriter(body);
- }
-
- bool isObject(DartType type) {
- return type is InterfaceType && type.classNode.supertype == null;
- }
-
- TreeNode visitField(Field node) {
- currentMember = node;
- context = new NoContext(this);
- node = super.visitField(node);
- context = null;
- currentMember = null;
- return node;
- }
-
- Expression handleLocalFunction(FunctionNode function) {
- if (function.asyncMarker == AsyncMarker.SyncYielding) {
- function.transformChildren(this);
- return new FunctionExpression(function);
- }
- FunctionNode enclosingFunction = currentFunction;
- Map<TypeParameter, DartType> enclosingTypeSubstitution = typeSubstitution;
- currentFunction = function;
- Statement body = function.body;
- assert(body != null);
-
- rewriter = makeRewriterForBody(function);
-
- VariableDeclaration contextVariable =
- new VariableDeclaration("#contextParameter", type: const DynamicType());
- Context parent = context;
- context = context.toNestedContext(
- new VariableAccessor(contextVariable, null, TreeNode.noOffset));
-
- Set<TypeParameter> captured =
- capturedTypeVariables[currentFunction] ?? new Set<TypeParameter>();
- typeSubstitution = copyTypeVariables(captured);
-
- function.transformChildren(this);
-
- Expression result = addClosure(function, contextVariable, parent.expression,
- typeSubstitution, enclosingTypeSubstitution);
- currentFunction = enclosingFunction;
- typeSubstitution = enclosingTypeSubstitution;
- return result;
- }
-
- TreeNode visitFunctionDeclaration(FunctionDeclaration node) {
- /// Is this closure itself captured by a closure?
- bool isCaptured = capturedVariables.contains(node.variable);
- if (isCaptured) {
- context.extend(node.variable, new InvalidExpression(null));
- }
- Context parent = context;
- return saveContext(() {
- Expression expression = handleLocalFunction(node.function);
-
- if (isCaptured) {
- parent.update(node.variable, expression);
- return null;
- } else {
- node.variable.initializer = expression;
- expression.parent = node.variable;
- return node.variable;
- }
- });
- }
-
- TreeNode visitFunctionExpression(FunctionExpression node) {
- return saveContext(() => handleLocalFunction(node.function));
- }
-
- /// Add a new procedure to the current library that looks like this:
- ///
- /// static method closure#0(Vector #c, /* Parameters of [function]. */)
- /// → dynamic {
- ///
- /// /* Context is represented by #c. */
- ///
- /// /* Body of [function]. */
- ///
- /// }
- ///
- /// Returns an invocation of the closure creation primitive that binds the
- /// above top-level function to a context represented as Vector.
- Expression addClosure(
- FunctionNode function,
- VariableDeclaration contextVariable,
- Expression accessContext,
- Map<TypeParameter, DartType> substitution,
- Map<TypeParameter, DartType> enclosingTypeSubstitution) {
- var fnTypeParams = <TypeParameter>[];
- var fnTypeArgs = <TypeParameterType>[];
- for (TypeParameter t in substitution.keys) {
- var fnTypeParam = (substitution[t] as TypeParameterType).parameter;
- fnTypeParams.add(fnTypeParam);
- fnTypeArgs
- .add(substitute(new TypeParameterType(t), enclosingTypeSubstitution));
- }
-
- function.typeParameters.insertAll(0, fnTypeParams);
- function.positionalParameters.insert(0, contextVariable);
- ++function.requiredParameterCount;
- Procedure closedTopLevelFunction = new Procedure(
- new Name(createNameForClosedTopLevelFunction(function)),
- ProcedureKind.Method,
- function,
- isStatic: true,
- fileUri: currentFileUri);
- newLibraryMembers.add(closedTopLevelFunction);
-
- // We need to again make new type parameters for the function's function
- // type, and substitute them into the function type's arguments' types.
- var closureTypeParams = <TypeParameter>[];
- var closureTypeSubstitutionMap = copyTypeVariables(function.typeParameters);
- for (DartType d in closureTypeSubstitutionMap.values)
- closureTypeParams.add((d as TypeParameterType).parameter);
-
- FunctionType closureType = new FunctionType(
- function.positionalParameters
- .skip(1)
- .map((VariableDeclaration decl) =>
- substitute(decl.type, closureTypeSubstitutionMap))
- .toList(),
- substitute(function.returnType, closureTypeSubstitutionMap),
- namedParameters: function.namedParameters
- .map((VariableDeclaration decl) => new NamedType(
- decl.name, substitute(decl.type, closureTypeSubstitutionMap)))
- .toList(),
- typeParameters: closureTypeParams,
- requiredParameterCount: function.requiredParameterCount - 1);
-
- // If we capture type parameters but not regular variables, we still need to
- // make a context.
- if (capturedTypeVariables[function] != null &&
- accessContext is NullLiteral) {
- accessContext = new VectorCreation(1);
- }
-
- return new ClosureCreation(
- closedTopLevelFunction, accessContext, closureType, fnTypeArgs);
- }
-
- TreeNode visitProcedure(Procedure node) {
- assert(isEmptyContext);
-
- currentMember = node;
-
- FunctionNode function = node.function;
- if (function.body != null) {
- bool hadSingleStatementBody = function.body is! Block;
-
- setupRewriterForFunctionBody(function);
- // Start with no context. This happens after setting up _currentBlock
- // so statements can be emitted into _currentBlock if necessary.
- context = new NoContext(this);
-
- VariableDeclaration self = thisAccess[currentMemberFunction];
- if (self != null) {
- context.extend(self, new ThisExpression());
- }
- node.transformChildren(this);
- resetContext();
-
- // Here a special case is handled: the body of the procedure was a single
- // statement and after the transformation it is a block with a single
- // statement inside. In this case we make this statement the body of the
- // procedure again. It is required to follow the conventions imposed by
- // [addClass] in [DillLibraryBuilder].
- // See [dill_library_builder.dart]
- // (../../../../front_end/lib/src/fasta/dill/dill_library_builder.dart)
- // for details.
- if (hadSingleStatementBody && function.body is Block) {
- Block body = function.body;
- if (body.statements.length == 1) {
- function.body = body.statements[0];
- function.body.parent = function;
- }
- }
- }
-
- return node;
- }
-
- void setupRewriterForFunctionBody(FunctionNode function) {
- Statement body = function.body;
- assert(body != null);
- currentMemberFunction = function;
- // Ensure that the body is a block which becomes the current block.
- rewriter = makeRewriterForBody(function);
- }
-
- void resetContext() {
- rewriter = null;
- context = null;
- currentMemberFunction = null;
- currentMember = null;
- }
-
- bool get isEmptyContext {
- return rewriter == null && context == null;
- }
-
- TreeNode visitLocalInitializer(LocalInitializer node) {
- assert(!capturedVariables.contains(node.variable));
- node.transformChildren(this);
- return node;
- }
-
- TreeNode visitFunctionNode(FunctionNode node) {
- transformList(node.typeParameters, this, node);
- // Initializers for optional parameters must be compile-time constants,
- // which excludes closures. Therefore, we can avoid looking for closures in
- // initializers of the parameters.
- node.positionalParameters
- .forEach(extendContextConditionally(inInitializer: false));
- node.namedParameters
- .forEach(extendContextConditionally(inInitializer: false));
- assert(node.body != null);
- node.body = node.body.accept(this);
- node.body.parent = node;
- return node;
- }
-
- TreeNode visitBlock(Block node) {
- return saveContext(() {
- BlockRewriter blockRewriter = rewriter = rewriter.forNestedBlock(node);
- if (node.parent is Statement &&
- isLoop(node.parent) &&
- context is! NoContext) {
- context = context.toNestedContext();
- }
- blockRewriter.transformStatements(this);
- return node;
- });
- }
-
- TreeNode visitVariableDeclaration(VariableDeclaration node) {
- node.transformChildren(this);
-
- if (!capturedVariables.contains(node)) return node;
- if (node.initializer == null && node.parent is FunctionNode) {
- // If the variable is a function parameter and doesn't have an
- // initializer, just use this variable name to put it into the context.
- context.extend(node, new VariableGet(node));
- } else {
- context.extend(node, node.initializer ?? new NullLiteral());
- }
-
- if (node.parent == currentFunction) {
- return node;
- } else {
- assert(node.parent is Block);
- // When returning null, the parent block will remove
- // this node from its list of statements.
- return null;
- }
- }
-
- TreeNode visitVariableGet(VariableGet node) {
- return capturedVariables.contains(node.variable)
- ? context.lookup(node.variable)
- : node;
- }
-
- TreeNode visitVariableSet(VariableSet node) {
- node.transformChildren(this);
-
- return capturedVariables.contains(node.variable)
- ? context.assign(node.variable, node.value,
- voidContext: isInVoidContext(node))
- : node;
- }
-
- bool isInVoidContext(Expression node) {
- TreeNode parent = node.parent;
- return parent is ExpressionStatement ||
- parent is ForStatement && parent.condition != node;
- }
-
- DartType visitDartType(DartType node) {
- return substitute(node, typeSubstitution);
- }
-
- VariableDeclaration getReplacementLoopVariable(VariableDeclaration variable) {
- VariableDeclaration newVariable = new VariableDeclaration(variable.name,
- initializer: variable.initializer, type: variable.type)
- ..flags = variable.flags;
- variable.initializer = new VariableGet(newVariable);
- variable.initializer.parent = variable;
- return newVariable;
- }
-
- Expression cloneContext() {
- InvalidExpression placeHolder = new InvalidExpression(null);
- contextClonePlaceHolders.add(placeHolder);
- return placeHolder;
- }
-
- TreeNode visitInvalidExpression(InvalidExpression node) {
- return contextClonePlaceHolders.remove(node) ? context.clone() : node;
- }
-
- TreeNode visitForStatement(ForStatement node) {
- if (node.variables.any(capturedVariables.contains)) {
- // In Dart, loop variables are new variables on each iteration of the
- // loop. This is only observable when a loop variable is captured by a
- // closure, which is the situation we're in here. So we transform the
- // loop.
- //
- // Consider the following example, where `x` is `node.variables.first`,
- // and `#t1` is a temporary variable:
- //
- // for (var x = 0; x < 10; x++) body;
- //
- // This is transformed to:
- //
- // {
- // var x = 0;
- // for (; x < 10; clone-context, x++) body;
- // }
- //
- // `clone-context` is a place-holder that will later be replaced by an
- // expression that clones the current closure context (see
- // [visitInvalidExpression]).
- return saveContext(() {
- context = context.toNestedContext();
- List<Statement> statements = <Statement>[];
- statements.addAll(node.variables);
- statements.add(node);
- node.variables.clear();
- node.updates.insert(0, cloneContext());
- Block block = new Block(statements);
- rewriter = new BlockRewriter(block);
- return block.accept(this);
- });
- }
- return super.visitForStatement(node);
- }
-
- TreeNode visitForInStatement(ForInStatement node) {
- if (capturedVariables.contains(node.variable)) {
- // In Dart, loop variables are new variables on each iteration of the
- // loop. This is only observable when the loop variable is captured by a
- // closure, so we need to transform the for-in loop when `node.variable`
- // is captured.
- //
- // Consider the following example, where `x` is `node.variable`, and
- // `#t1` is a temporary variable:
- //
- // for (var x in expr) body;
- //
- // Notice that we can assume that `x` doesn't have an initializer based
- // on invariants in the Kernel AST. This is transformed to:
- //
- // for (var #t1 in expr) { var x = #t1; body; }
- //
- // After this, we call super to apply the normal closure conversion to
- // the transformed for-in loop.
- VariableDeclaration variable = node.variable;
- VariableDeclaration newVariable = getReplacementLoopVariable(variable);
- node.variable = newVariable;
- newVariable.parent = node;
- node.body = new Block(<Statement>[variable, node.body]);
- node.body.parent = node;
- }
- return super.visitForInStatement(node);
- }
-
- TreeNode visitThisExpression(ThisExpression node) {
- return isOuterMostContext
- ? node
- : context.lookup(thisAccess[currentMemberFunction]);
- }
-
- TreeNode visitCatch(Catch node) {
- VariableDeclaration exception = node.exception;
- VariableDeclaration stackTrace = node.stackTrace;
- if (stackTrace != null && capturedVariables.contains(stackTrace)) {
- Block block = node.body = ensureBlock(node.body);
- block.parent = node;
- node.stackTrace = new VariableDeclaration(null);
- node.stackTrace.parent = node;
- stackTrace.initializer = new VariableGet(node.stackTrace);
- block.statements.insert(0, stackTrace);
- stackTrace.parent = block;
- }
- if (exception != null && capturedVariables.contains(exception)) {
- Block block = node.body = ensureBlock(node.body);
- block.parent = node;
- node.exception = new VariableDeclaration(null);
- node.exception.parent = node;
- exception.initializer = new VariableGet(node.exception);
- block.statements.insert(0, exception);
- exception.parent = block;
- }
- return super.visitCatch(node);
- }
-
- Block ensureBlock(Statement statement) {
- return statement is Block ? statement : new Block(<Statement>[statement]);
- }
-
- /// Creates a function that has the same signature as `procedure.function`
- /// and which forwards all arguments to `procedure`.
- FunctionNode forwardFunction(
- Procedure procedure,
- VariableDeclaration receiver,
- VariableDeclaration contextVariable,
- Map<TypeParameter, DartType> substitution) {
- CloneVisitor cloner = substitution.isEmpty
- ? this.cloner
- : new CloneWithoutBody(typeSubstitution: substitution);
- FunctionNode function = procedure.function;
- List<TypeParameter> typeParameters =
- function.typeParameters.map(cloner.clone).toList();
- List<VariableDeclaration> positionalParameters =
- function.positionalParameters.map(cloner.clone).toList();
- if (contextVariable != null) {
- positionalParameters.insert(0, contextVariable);
- }
- List<VariableDeclaration> namedParameters =
- function.namedParameters.map(cloner.clone).toList();
-
- List<DartType> types = typeParameters
- .map((TypeParameter parameter) => new TypeParameterType(parameter))
- .toList();
- List<Expression> positional = positionalParameters
- .map((VariableDeclaration parameter) => new VariableGet(parameter))
- .toList();
- if (contextVariable != null) {
- positional.removeAt(0);
- }
- List<NamedExpression> named =
- namedParameters.map((VariableDeclaration parameter) {
- return new NamedExpression(parameter.name, new VariableGet(parameter));
- }).toList();
-
- Arguments arguments = new Arguments(positional, types: types, named: named);
- InvocationExpression invocation = procedure.isInstanceMember
- ? new MethodInvocation(
- context.lookup(receiver), procedure.name, arguments, procedure)
- : new StaticInvocation(procedure, arguments);
- int requiredParameterCount = function.requiredParameterCount;
- if (contextVariable != null) {
- ++requiredParameterCount;
- }
- return new FunctionNode(new ReturnStatement(invocation),
- typeParameters: typeParameters,
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- requiredParameterCount: requiredParameterCount,
- returnType: substitute(function.returnType, cloner.typeSubstitution));
- }
-
- /// Creates copies of the type variables in [original] and returns a
- /// substitution that can be passed to [substitute] to substitute all uses of
- /// [original] with their copies.
- ///
- Map<TypeParameter, DartType> copyTypeVariables(
- Iterable<TypeParameter> original) {
- if (original.isEmpty) return const <TypeParameter, DartType>{};
-
- Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
- for (TypeParameter t in original) {
- substitution[t] = new TypeParameterType(new TypeParameter(t.name));
- }
-
- substitution.forEach((TypeParameter t, DartType copy) {
- if (copy is TypeParameterType) {
- copy.parameter.bound = substitute(t.bound, substitution);
- }
- });
- return substitution;
- }
-
- String createNameForClosedTopLevelFunction(FunctionNode function) {
- return 'closure#${localNames[function]}';
- }
-
- Statement forwardToThisProperty(Member node) {
- assert(node is Field || (node is Procedure && node.isGetter));
- return new ReturnStatement(
- new PropertyGet(new ThisExpression(), node.name, node));
- }
-
- void addFieldForwarder(Name name, Field field) {
- newClassMembers.add(new Procedure(name, ProcedureKind.Getter,
- new FunctionNode(forwardToThisProperty(field)),
- fileUri: currentFileUri));
- }
-
- Procedure copyWithBody(Procedure procedure, Statement body) {
- Procedure copy = cloner.clone(procedure);
- copy.function.body = body;
- copy.function.body.parent = copy.function;
- return copy;
- }
-
- void addGetterForwarder(Name name, Procedure getter) {
- assert(getter.isGetter);
- newClassMembers
- .add(copyWithBody(getter, forwardToThisProperty(getter))..name = name);
- }
-}
diff --git a/pkg/kernel/lib/transformations/closure/info.dart b/pkg/kernel/lib/transformations/closure/info.dart
deleted file mode 100644
index ffa5fd7..0000000
--- a/pkg/kernel/lib/transformations/closure/info.dart
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.closure.info;
-
-import '../../ast.dart'
- show
- Class,
- Constructor,
- Field,
- FunctionDeclaration,
- FunctionNode,
- Member,
- Procedure,
- ThisExpression,
- TypeParameter,
- TypeParameterType,
- VariableDeclaration,
- VariableGet,
- VariableSet,
- visitList;
-
-import '../../visitor.dart' show RecursiveVisitor;
-
-class ClosureInfo extends RecursiveVisitor {
- FunctionNode currentFunction;
-
- final Set<VariableDeclaration> variables = new Set<VariableDeclaration>();
-
- // For captured constructor parameters, we need to distinquish the following
- // states:
- //
- // - only used inside initializers (INSIDE_INITIALIZER)
- // - only used in body (OUTSIDE_INITIALIZER)
- // - used in body and initializers (OUTSIDE_INITIALIZER | INSIDE_INITIALIZER)
- static const int OUTSIDE_INITIALIZER = 1;
- static const int INSIDE_INITIALIZER = 2;
- int captureFlags = OUTSIDE_INITIALIZER;
- final Map<VariableDeclaration, int> parameterUses =
- <VariableDeclaration, int>{};
-
- final Map<VariableDeclaration, FunctionNode> function =
- <VariableDeclaration, FunctionNode>{};
-
- /// Map from functions to set of type variables captured within them.
- final Map<FunctionNode, Set<TypeParameter>> typeVariables =
- <FunctionNode, Set<TypeParameter>>{};
-
- /// Map from members to synthetic variables for accessing `this` in a local
- /// function.
- final Map<FunctionNode, VariableDeclaration> thisAccess =
- <FunctionNode, VariableDeclaration>{};
-
- final Set<String> currentMemberLocalNames = new Set<String>();
-
- final Map<FunctionNode, String> localNames = <FunctionNode, String>{};
-
- Class currentClass;
-
- Member currentMember;
-
- FunctionNode currentMemberFunction;
-
- bool get isOuterMostContext {
- return currentFunction == null || currentMemberFunction == currentFunction;
- }
-
- void beginMember(Member member, [FunctionNode function]) {
- currentMemberLocalNames.clear();
- if (function != null) {
- localNames[function] = computeUniqueLocalName(member.name.name);
- }
- currentMember = member;
- currentMemberFunction = function;
- }
-
- void endMember() {
- currentMember = null;
- currentMemberFunction = null;
- }
-
- visitClass(Class node) {
- currentClass = node;
- super.visitClass(node);
- currentClass = null;
- }
-
- visitConstructor(Constructor node) {
- /// [currentFunction] should be set to [currentMemberFunction] before
- /// visiting the [FunctionNode] of the constructor, because initializers may
- /// use constructor parameters and it shouldn't be treated as capturing
- /// them. Consider the following code:
- ///
- /// class A {
- /// int x;
- /// A(int x) /* [x] is visible in initializers and body. */
- /// : this.x = x { /* Initializer. */
- /// /* Constructor body. */
- /// }
- /// }
- ///
- /// Here the parameter shouldn't be captured into a context in the
- /// initializer. However, [currentFunction] is `null` if not set, and
- /// `function[node.variable]` in this case points to the [FunctionNode] of
- /// the constructor (which is not `null`). It leads to `x` being treated as
- /// captured, because it's seen as used outside of the function where it is
- /// declared. In turn, it leads to unnecessary context creation and usage.
- ///
- /// Another consideration is the order of visiting children of the
- /// constructor: [node.function] should be visited before
- /// [node.initializers], because [node.function] contains declarations of
- /// the parameters that may be used in the initializers. If the nodes are
- /// visited in another order, the encountered parameters in initializers
- /// are treated as captured, because they are not yet associated with the
- /// function.
- beginMember(node, node.function);
- saveCurrentFunction(() {
- currentFunction = currentMemberFunction;
-
- visitList(node.annotations, this);
- node.name?.accept(this);
-
- visitList(node.function.typeParameters, this);
- visitList(node.function.positionalParameters, this);
- visitList(node.function.namedParameters, this);
-
- assert(captureFlags == OUTSIDE_INITIALIZER);
- captureFlags = INSIDE_INITIALIZER;
- visitList(node.initializers, this);
- captureFlags = OUTSIDE_INITIALIZER;
-
- for (var decl in node.function.positionalParameters) {
- var use = parameterUses[decl];
- if (use == 0) parameterUses.remove(decl);
- }
- for (var decl in node.function.namedParameters) {
- var use = parameterUses[decl];
- if (use == 0) parameterUses.remove(decl);
- }
-
- node.function.accept(this);
- });
- endMember();
- }
-
- visitProcedure(Procedure node) {
- beginMember(node, node.function);
- super.visitProcedure(node);
- endMember();
- }
-
- visitField(Field node) {
- beginMember(node);
- super.visitField(node);
- endMember();
- }
-
- String computeUniqueLocalName([String name]) {
- if (name == null || name.isEmpty) {
- name = "function";
- }
- if (currentFunction == null) {
- if (currentMember != null) {
- name = "${currentMember.name.name}#$name";
- }
- if (currentClass != null) {
- name = "${currentClass.name}#$name";
- }
- } else {
- name = "${localNames[currentFunction]}#$name";
- }
- int count = 1;
- String candidate = name;
- while (currentMemberLocalNames.contains(candidate)) {
- candidate = "$name#${count++}";
- }
- currentMemberLocalNames.add(candidate);
- return candidate;
- }
-
- visitFunctionDeclaration(FunctionDeclaration node) {
- assert(!localNames.containsKey(node));
- localNames[node.function] = computeUniqueLocalName(node.variable.name);
- return super.visitFunctionDeclaration(node);
- }
-
- visitFunctionNode(FunctionNode node) {
- localNames.putIfAbsent(node, computeUniqueLocalName);
-
- saveCurrentFunction(() {
- currentFunction = node;
- node.visitChildren(this);
- });
-
- Set<TypeParameter> capturedTypeVariables = typeVariables[node];
- if (capturedTypeVariables != null && !isOuterMostContext) {
- // Propagate captured type variables to enclosing function.
- typeVariables
- .putIfAbsent(currentFunction, () => new Set<TypeParameter>())
- .addAll(
- // 't.parent == currentFunction' will be true if the type variable
- // is defined by one of our type parameters.
- capturedTypeVariables.where((t) => t.parent != currentFunction));
- }
- }
-
- visitVariableDeclaration(VariableDeclaration node) {
- function[node] = currentFunction;
- node.visitChildren(this);
- }
-
- visitVariableGet(VariableGet node) {
- if (function[node.variable] != currentFunction) {
- variables.add(node.variable);
- }
- if (node.variable.parent.parent is Constructor) {
- parameterUses.putIfAbsent(node.variable, () => 0);
- parameterUses[node.variable] |= captureFlags;
- }
- node.visitChildren(this);
- }
-
- visitVariableSet(VariableSet node) {
- if (function[node.variable] != currentFunction) {
- variables.add(node.variable);
- }
- if (node.variable.parent.parent is Constructor) {
- parameterUses.putIfAbsent(node.variable, () => 0);
- parameterUses[node.variable] |= captureFlags;
- }
- node.visitChildren(this);
- }
-
- visitTypeParameterType(TypeParameterType node) {
- if (!isOuterMostContext &&
- node.parameter.parent != currentFunction &&
- !node.parameter.isFunctionTypeTypeParameter) {
- typeVariables
- .putIfAbsent(currentFunction, () => new Set<TypeParameter>())
- .add(node.parameter);
- }
- }
-
- visitThisExpression(ThisExpression node) {
- if (!isOuterMostContext) {
- thisAccess.putIfAbsent(
- currentMemberFunction, () => new VariableDeclaration("#self"));
- }
- }
-
- saveCurrentFunction(void f()) {
- var saved = currentFunction;
- try {
- f();
- } finally {
- currentFunction = saved;
- }
- }
-}
diff --git a/pkg/kernel/lib/transformations/closure/invalidate_closures.dart b/pkg/kernel/lib/transformations/closure/invalidate_closures.dart
deleted file mode 100644
index 6cbbf76..0000000
--- a/pkg/kernel/lib/transformations/closure/invalidate_closures.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.closure.invalidate;
-
-import '../../ast.dart';
-
-class InvalidateClosures extends Transformer {
- FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) {
- invalidate(node.function);
- return node;
- }
-
- FunctionExpression visitFunctionExpression(FunctionExpression node) {
- invalidate(node.function);
- return node;
- }
-
- void invalidate(FunctionNode function) {
- if (function.asyncMarker != AsyncMarker.Sync) return;
- var position = function.location;
- function.body = new ExpressionStatement(new Throw(
- new StringLiteral("Calling unconverted closure at $position")))
- ..parent = function;
- }
-}
diff --git a/pkg/kernel/lib/transformations/closure/rewriter.dart b/pkg/kernel/lib/transformations/closure/rewriter.dart
deleted file mode 100644
index d3ae56e..0000000
--- a/pkg/kernel/lib/transformations/closure/rewriter.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.closure.rewriter;
-
-import '../../ast.dart';
-import 'converter.dart' show ClosureConverter;
-
-/// Used by the [Context] to initialize and update the context variable
-/// used to capture the variables closed over by functions.
-abstract class AstRewriter {
- /// The declared variable that holds the context.
- VariableDeclaration contextDeclaration;
-
- /// Expression that is used to initialize the vector representing the context.
- /// It's [length] field is modified by the [extend] operation
- VectorCreation vectorCreation;
-
- /// Creates a new [AstRewriter] for a (nested) [Block].
- BlockRewriter forNestedBlock(Block block);
-
- /// Inserts an allocation of a context and initializes [contextDeclaration]
- /// and [vectorCreation].
- void insertContextDeclaration(Expression accessParent);
-
- /// Inserts an expression or statement that extends the context.
- void insertExtendContext(VectorSet extender);
-
- /// Inserts an expression that sets a parameter to NULL, so we don't have
- /// unnecessary references to it.
- void insertZeroOutParameter(VariableDeclaration parameter);
-
- void _createDeclaration() {
- assert(contextDeclaration == null && vectorCreation == null);
-
- // Context size is set to 2 initially, because the 0-th element of it holds
- // the vector of type arguments that the VM creates, and the 1-st element
- // works as a link to the parent context.
- vectorCreation = new VectorCreation(2);
- contextDeclaration = new VariableDeclaration.forValue(vectorCreation,
- type: const DynamicType());
- contextDeclaration.name = "#context";
- }
-}
-
-/// Adds a local variable for the context and adds update [Statement]s to the
-/// current block.
-class BlockRewriter extends AstRewriter {
- Block _currentBlock;
- int _insertionIndex;
-
- BlockRewriter(this._currentBlock) : _insertionIndex = 0;
-
- BlockRewriter forNestedBlock(Block block) {
- return _currentBlock != block ? new BlockRewriter(block) : this;
- }
-
- void transformStatements(ClosureConverter converter) {
- while (_insertionIndex < _currentBlock.statements.length) {
- var original = _currentBlock.statements[_insertionIndex];
- var transformed = original.accept(converter);
- assert(_currentBlock.statements[_insertionIndex] == original);
- if (transformed == null) {
- _currentBlock.statements.removeAt(_insertionIndex);
- } else {
- _currentBlock.statements[_insertionIndex++] = transformed;
- transformed.parent = _currentBlock;
- }
- }
- }
-
- void _insertStatement(Statement statement) {
- _currentBlock.statements.insert(_insertionIndex++, statement);
- statement.parent = _currentBlock;
- }
-
- void insertContextDeclaration(Expression accessParent) {
- _createDeclaration();
- _insertStatement(contextDeclaration);
- if (accessParent is! NullLiteral) {
- // Index 1 of a context always points to the parent.
- _insertStatement(new ExpressionStatement(
- new VectorSet(new VariableGet(contextDeclaration), 1, accessParent)));
- }
- }
-
- void insertExtendContext(VectorSet extender) {
- _insertStatement(new ExpressionStatement(extender));
- }
-
- void insertZeroOutParameter(VariableDeclaration parameter) {
- _insertStatement(
- new ExpressionStatement(new VariableSet(parameter, new NullLiteral())));
- }
-}
-
-class InitializerListRewriter extends AstRewriter {
- final Constructor parentConstructor;
- final List<Initializer> prefix = [];
-
- InitializerListRewriter(this.parentConstructor);
-
- @override
- BlockRewriter forNestedBlock(Block block) {
- return new BlockRewriter(block);
- }
-
- @override
- void insertContextDeclaration(Expression accessParent) {
- _createDeclaration();
- var init = new LocalInitializer(contextDeclaration);
- init.parent = parentConstructor;
- prefix.add(init);
- }
-
- @override
- void insertExtendContext(VectorSet extender) {
- var init = new LocalInitializer(
- new VariableDeclaration(null, initializer: extender));
- init.parent = parentConstructor;
- prefix.add(init);
- }
-
- @override
- void insertZeroOutParameter(VariableDeclaration parameter) {
- var init = new LocalInitializer(new VariableDeclaration(null,
- initializer: new VariableSet(parameter, new NullLiteral())));
- init.parent = parentConstructor;
- prefix.add(init);
- }
-}
diff --git a/pkg/kernel/lib/transformations/closure_conversion.dart b/pkg/kernel/lib/transformations/closure_conversion.dart
deleted file mode 100644
index d1471aa..0000000
--- a/pkg/kernel/lib/transformations/closure_conversion.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.closure_conversion;
-
-import '../ast.dart' show Component, Library;
-
-import '../core_types.dart' show CoreTypes;
-
-import 'closure/converter.dart' show ClosureConverter;
-
-import 'closure/info.dart' show ClosureInfo;
-
-import 'closure/invalidate_closures.dart';
-
-Component transformComponent(CoreTypes coreTypes, Component component) {
- var info = new ClosureInfo();
- info.visitComponent(component);
-
- var convert = new ClosureConverter(coreTypes, info);
- component = convert.visitComponent(component);
- return new InvalidateClosures().visitComponent(component);
-}
-
-void transformLibraries(CoreTypes coreTypes, List<Library> libraries) {
- var info = new ClosureInfo();
- for (var library in libraries) {
- info.visitLibrary(library);
- }
-
- var convert = new ClosureConverter(coreTypes, info);
- for (int i = 0; i < libraries.length; i++) {
- libraries[i] = convert.visitLibrary(libraries[i]);
- }
- var invalidator = new InvalidateClosures();
- for (int i = 0; i < libraries.length; i++) {
- invalidator.visitLibrary(libraries[i]);
- }
-}
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index 2c55885..de851c6 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -185,15 +185,19 @@
void transformAnnotations(List<Expression> nodes, TreeNode parent) {
if (evaluateAnnotations && nodes.length > 0) {
- constantEvaluator.withNewEnvironment(() {
- for (int i = 0; i < nodes.length; ++i) {
- nodes[i] = tryEvaluateAndTransformWithContext(parent, nodes[i])
- ..parent = parent;
- }
- });
+ transformExpressions(nodes, parent);
}
}
+ void transformExpressions(List<Expression> nodes, TreeNode parent) {
+ constantEvaluator.withNewEnvironment(() {
+ for (int i = 0; i < nodes.length; ++i) {
+ nodes[i] = tryEvaluateAndTransformWithContext(parent, nodes[i])
+ ..parent = parent;
+ }
+ });
+ }
+
// Handle definition of constants:
visitFunctionNode(FunctionNode node) {
@@ -248,7 +252,10 @@
return null;
}
}
- return super.visitVariableDeclaration(node);
+ if (node.initializer != null) {
+ node.initializer = node.initializer.accept(this)..parent = node;
+ }
+ return node;
}
visitField(Field node) {
@@ -292,6 +299,11 @@
return super.visitStaticGet(node);
}
+ visitSwitchCase(SwitchCase node) {
+ transformExpressions(node.expressions, node);
+ return super.visitSwitchCase(node);
+ }
+
visitVariableGet(VariableGet node) {
if (node.variable.isConst) {
return tryEvaluateAndTransformWithContext(node, node);
@@ -409,9 +421,7 @@
defaultTreeNode(Node node) {
// Only a subset of the expression language is valid for constant
// evaluation.
- errorReporter.unimplemented(contextChain, node,
- 'Constant evaluation has no support for ${node.runtimeType} yet!');
- throw const _AbortCurrentEvaluation();
+ throw 'Constant evaluation has no support for ${node.runtimeType} yet!';
}
visitNullLiteral(NullLiteral node) => nullConstant;
@@ -449,7 +459,7 @@
visitListLiteral(ListLiteral node) {
if (!node.isConst) {
- errorReporter.nonConstantLiteral(contextChain, node, 'List');
+ errorReporter.nonConstLiteral(contextChain, node, 'List');
throw const _AbortCurrentEvaluation();
}
final List<Constant> entries = new List<Constant>(node.expressions.length);
@@ -463,7 +473,7 @@
visitMapLiteral(MapLiteral node) {
if (!node.isConst) {
- errorReporter.nonConstantLiteral(contextChain, node, 'Map');
+ errorReporter.nonConstLiteral(contextChain, node, 'Map');
throw const _AbortCurrentEvaluation();
}
final Set<Constant> usedKeys = new Set<Constant>();
@@ -473,6 +483,9 @@
final key = node.entries[i].key.accept(this);
final value = node.entries[i].value.accept(this);
if (!usedKeys.add(key)) {
+ // TODO(kustermann): We should change the context handling from just
+ // capturing the `TreeNode`s to a `(TreeNode, String message)` tuple and
+ // report where the first key with the same value was.
errorReporter.duplicateKey(contextChain, node.entries[i], key);
throw const _AbortCurrentEvaluation();
}
@@ -485,23 +498,24 @@
return canonicalize(backend.lowerMapConstant(mapConstant));
}
+ visitFunctionExpression(FunctionExpression node) {
+ errorReporter.nonConstLiteral(contextChain, node, 'Function');
+ throw const _AbortCurrentEvaluation();
+ }
+
visitConstructorInvocation(ConstructorInvocation node) {
final Constructor constructor = node.target;
final Class klass = constructor.enclosingClass;
if (!constructor.isConst) {
- errorReporter.nonConstConstructorInvocation(
- contextChain, node, constructor);
- throw const _AbortCurrentEvaluation();
+ throw 'The front-end should ensure we do not encounter a '
+ 'constructor invocation of a non-const constructor.';
}
- if (constructor.function.body is! EmptyStatement) {
- errorReporter.unreachable(contextChain, node,
- 'Constructor "$node" has non-trivial body "${constructor.function.body.runtimeType}".');
- throw const _AbortCurrentEvaluation();
+ if (constructor.function.body != null &&
+ constructor.function.body is! EmptyStatement) {
+ throw 'Constructor "$node" has non-trivial body "${constructor.function.body.runtimeType}".';
}
if (klass.isAbstract) {
- errorReporter.unreachable(contextChain, node,
- 'Constructor "$node" belongs to abstract class "${klass}".');
- throw const _AbortCurrentEvaluation();
+ throw 'Constructor "$node" belongs to abstract class "${klass}".';
}
final typeArguments = evaluateTypeArguments(node.arguments);
@@ -587,20 +601,34 @@
if (condition is BoolConstant) {
if (!condition.value) {
final Constant message = init.statement.message?.accept(this);
- errorReporter.failedAssertion(
- contextChain, init.statement.condition, message);
+ if (message == null) {
+ errorReporter.failedAssertion(
+ contextChain, init.statement.condition, null);
+ throw const _AbortCurrentEvaluation();
+ } else if (message is StringConstant) {
+ errorReporter.failedAssertion(
+ contextChain, init.statement.condition, message.value);
+ throw const _AbortCurrentEvaluation();
+ }
+ errorReporter.invalidDartType(
+ contextChain,
+ init.statement.message,
+ message,
+ typeEnvironment.stringType);
throw const _AbortCurrentEvaluation();
}
} else {
- errorReporter.invalidType(
- contextChain, init.statement.condition, condition, 'bool');
+ errorReporter.invalidDartType(
+ contextChain,
+ init.statement.condition,
+ condition,
+ typeEnvironment.boolType);
throw const _AbortCurrentEvaluation();
}
}
} else {
- errorReporter.unimplemented(contextChain, init,
+ throw new Exception(
'No support for handling initializer of type "${init.runtimeType}".');
- throw const _AbortCurrentEvaluation();
}
}
});
@@ -615,21 +643,16 @@
final List<Constant> arguments =
evaluatePositionalArguments(node.arguments);
+ // TODO(http://dartbug.com/31799): Ensure we only invoke ==/!= on
+ // null/bool/int/double/String objects.
+
// Handle == and != first (it's common between all types).
if (arguments.length == 1 && node.name.name == '==') {
- // TODO(http://dartbug.com/31799): Re-enable these checks.
- //ensurePrimitiveConstant(receiver);
final right = arguments[0];
- // TODO(http://dartbug.com/31799): Re-enable these checks.
- //ensurePrimitiveConstant(right);
return receiver == right ? trueConstant : falseConstant;
}
if (arguments.length == 1 && node.name.name == '!=') {
- // TODO(http://dartbug.com/31799): Re-enable these checks.
- //ensurePrimitiveConstant(receiver);
final right = arguments[0];
- // TODO(http://dartbug.com/31799): Re-enable these checks.
- //ensurePrimitiveConstant(right);
return receiver != right ? trueConstant : falseConstant;
}
@@ -644,7 +667,12 @@
new StringConstant(receiver.value + other.value));
}
errorReporter.invalidBinaryOperandType(
- contextChain, node, 'String', '+', 'String', '$other');
+ contextChain,
+ node,
+ receiver,
+ '+',
+ typeEnvironment.stringType,
+ other.getType(typeEnvironment));
throw const _AbortCurrentEvaluation();
}
}
@@ -669,7 +697,12 @@
}
}
errorReporter.invalidBinaryOperandType(
- contextChain, node, 'bool', '${node.name.name}', 'bool', '$right');
+ contextChain,
+ node,
+ receiver,
+ '${node.name.name}',
+ typeEnvironment.boolType,
+ right.getType(typeEnvironment));
throw const _AbortCurrentEvaluation();
}
} else if (receiver is IntConstant) {
@@ -710,8 +743,13 @@
node.name.name, receiver.value, value, node);
}
- errorReporter.invalidBinaryOperandType(contextChain, node, 'int',
- '${node.name.name}', 'int/double', '$other');
+ errorReporter.invalidBinaryOperandType(
+ contextChain,
+ node,
+ receiver,
+ '${node.name.name}',
+ typeEnvironment.numType,
+ other.getType(typeEnvironment));
throw const _AbortCurrentEvaluation();
}
} else if (receiver is DoubleConstant) {
@@ -730,8 +768,13 @@
return evaluateBinaryNumericOperation(
node.name.name, receiver.value, value, node);
}
- errorReporter.invalidBinaryOperandType(contextChain, node, 'double',
- '${node.name.name}', 'int/double', '$other');
+ errorReporter.invalidBinaryOperandType(
+ contextChain,
+ node,
+ receiver,
+ '${node.name.name}',
+ typeEnvironment.numType,
+ other.getType(typeEnvironment));
throw const _AbortCurrentEvaluation();
}
}
@@ -752,7 +795,12 @@
return right;
}
errorReporter.invalidBinaryOperandType(
- contextChain, node, 'bool', '${node.operator}', 'bool', '$right');
+ contextChain,
+ node,
+ left,
+ '${node.operator}',
+ typeEnvironment.boolType,
+ right.getType(typeEnvironment));
throw const _AbortCurrentEvaluation();
}
errorReporter.invalidMethodInvocation(
@@ -767,7 +815,12 @@
return right;
}
errorReporter.invalidBinaryOperandType(
- contextChain, node, 'bool', '${node.operator}', 'bool', '$right');
+ contextChain,
+ node,
+ left,
+ '${node.operator}',
+ typeEnvironment.boolType,
+ right.getType(typeEnvironment));
throw const _AbortCurrentEvaluation();
}
errorReporter.invalidMethodInvocation(
@@ -789,7 +842,8 @@
} else if (constant == falseConstant) {
return evaluate(node.otherwise);
} else {
- errorReporter.invalidType(contextChain, node, constant, 'bool');
+ errorReporter.invalidDartType(
+ contextChain, node, constant, typeEnvironment.boolType);
throw const _AbortCurrentEvaluation();
}
}
@@ -834,8 +888,8 @@
if (!variable.isConst &&
!_isFormalParameter(variable) &&
variable.parent is! Let) {
- errorReporter.nonConstantVariableGet(contextChain, node);
- throw const _AbortCurrentEvaluation();
+ throw new Exception('The front-end should ensure we do not encounter a '
+ 'variable get of a non-const variable.');
}
return env.lookupVariable(node.variable);
}
@@ -854,9 +908,8 @@
errorReporter.invalidStaticInvocation(contextChain, node, target);
throw const _AbortCurrentEvaluation();
} else {
- errorReporter.unreachable(contextChain, node,
+ throw new Exception(
'No support for ${target.runtimeType} in a static-get.');
- throw const _AbortCurrentEvaluation();
}
});
}
@@ -903,11 +956,7 @@
if (parent is Library && parent == coreTypes.coreLibrary) {
final positionalArguments = evaluatePositionalArguments(node.arguments);
final Constant left = positionalArguments[0];
- // TODO(http://dartbug.com/31799): Re-enable these checks.
- //ensurePrimitiveConstant(left, node);
final Constant right = positionalArguments[1];
- // TODO(http://dartbug.com/31799): Re-enable these checks.
- //ensurePrimitiveConstant(right, node);
// Since we canonicalize constants during the evaluation, we can use
// identical here.
assert(left == right);
@@ -929,7 +978,8 @@
if (constant is BoolConstant) {
return constant == trueConstant ? falseConstant : trueConstant;
}
- errorReporter.invalidType(contextChain, node, constant, 'bool');
+ errorReporter.invalidDartType(
+ contextChain, node, constant, typeEnvironment.boolType);
throw const _AbortCurrentEvaluation();
}
@@ -946,16 +996,12 @@
return canonicalize(
new PartialInstantiationConstant(constant, node.typeArguments));
}
- errorReporter.unreachable(
- contextChain,
- node,
+ throw new Exception(
'The number of type arguments supplied in the partial instantiation '
'does not match the number of type arguments of the $constant.');
- throw const _AbortCurrentEvaluation();
}
- errorReporter.unreachable(contextChain, node,
+ throw new Exception(
'Only tear-off constants can be partially instantiated.');
- throw const _AbortCurrentEvaluation();
}
// Helper methods:
@@ -985,13 +1031,11 @@
} else if (constant is TypeLiteralConstant) {
constantType = new InterfaceType(coreTypes.typeClass);
} else {
- errorReporter.unreachable(contextChain, node,
- 'No support for ${constant.runtimeType}.runtimeType');
- throw const _AbortCurrentEvaluation();
+ throw new Exception('No support for ${constant.runtimeType}.runtimeType');
}
if (!typeEnvironment.isSubtypeOf(constantType, type)) {
- errorReporter.invalidType(contextChain, node, constant, '$type');
+ errorReporter.invalidDartType(contextChain, node, constant, type);
throw const _AbortCurrentEvaluation();
}
}
@@ -1015,7 +1059,7 @@
List<Constant> evaluatePositionalArguments(Arguments arguments) {
return arguments.positional.map((Expression node) {
- return node.accept(this);
+ return node.accept(this) as Constant;
}).toList();
}
@@ -1053,18 +1097,6 @@
}
}
- ensurePrimitiveConstant(Constant value, TreeNode node) {
- if (value is! NullConstant &&
- value is! BoolConstant &&
- value is! IntConstant &&
- value is! DoubleConstant &&
- value is! StringConstant) {
- errorReporter.invalidType(
- contextChain, node, value, 'bool/int/double/Null/String');
- throw const _AbortCurrentEvaluation();
- }
- }
-
evaluateBinaryNumericOperation(String op, num a, num b, TreeNode node) {
num result;
switch (op) {
@@ -1105,8 +1137,7 @@
return a > b ? trueConstant : falseConstant;
}
- errorReporter.invalidBinaryMethodInvocation(contextChain, node, op);
- throw const _AbortCurrentEvaluation();
+ throw new Exception("Unexpected binary numeric operation '$op'.");
}
int _wrapAroundInteger(int value) {
@@ -1211,26 +1242,19 @@
abstract class ErrorReporter {
const ErrorReporter();
- invalidType(List<TreeNode> context, TreeNode node, Constant receiver,
- String expectedType);
+ invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
+ DartType expectedType);
invalidBinaryOperandType(List<TreeNode> context, TreeNode node,
- String receiverType, String op, String expectedType, String actualType);
- invalidBinaryMethodInvocation(
- List<TreeNode> context, TreeNode node, String op);
+ Constant receiver, String op, DartType expectedType, DartType actualType);
invalidMethodInvocation(
List<TreeNode> context, TreeNode node, Constant receiver, String op);
invalidStaticInvocation(
List<TreeNode> context, TreeNode node, Procedure target);
invalidStringInterpolationOperand(
List<TreeNode> context, TreeNode node, Constant constant);
+ nonConstLiteral(List<TreeNode> context, TreeNode node, String klass);
duplicateKey(List<TreeNode> context, TreeNode node, Constant key);
- nonConstantLiteral(List<TreeNode> context, TreeNode node, String literalType);
- nonConstantVariableGet(List<TreeNode> context, VariableGet node);
- nonConstConstructorInvocation(
- List<TreeNode> context, TreeNode node, Constructor target);
- failedAssertion(List<TreeNode> context, TreeNode node, Constant message);
- unimplemented(List<TreeNode> context, TreeNode node, String message);
- unreachable(List<TreeNode> context, TreeNode node, String message);
+ failedAssertion(List<TreeNode> context, TreeNode node, String message);
}
abstract class ErrorReporterBase implements ErrorReporter {
@@ -1252,28 +1276,28 @@
return node == null ? TreeNode.noOffset : node.fileOffset;
}
- invalidType(List<TreeNode> context, TreeNode node, Constant receiver,
- String expectedType) {
+ invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
+ DartType expectedType) {
report(
context,
'Expected expression to evaluate to "$expectedType" but got "$receiver.',
node);
}
- invalidBinaryOperandType(List<TreeNode> context, TreeNode node,
- String receiverType, String op, String expectedType, String actualType) {
+ invalidBinaryOperandType(
+ List<TreeNode> context,
+ TreeNode node,
+ Constant receiver,
+ String op,
+ DartType expectedType,
+ DartType actualType) {
report(
context,
- 'Calling "$op" on "$receiverType" needs operand of type '
+ 'Calling "$op" on "$receiver" needs operand of type '
'"$expectedType" (but got "$actualType")',
node);
}
- invalidBinaryMethodInvocation(
- List<TreeNode> context, TreeNode node, String op) {
- report(context, 'Cannot call "$op" on a numeric constant receiver', node);
- }
-
invalidMethodInvocation(
List<TreeNode> context, TreeNode node, Constant receiver, String op) {
report(context, 'Cannot call "$op" on "$receiver" in constant expression',
@@ -1295,6 +1319,13 @@
node);
}
+ nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+ report(
+ context,
+ 'Cannot have a non-constant $klass literal within a const context.',
+ node);
+ }
+
duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
report(
context,
@@ -1302,47 +1333,12 @@
node);
}
- nonConstantLiteral(
- List<TreeNode> context, TreeNode node, String literalType) {
- report(
- context,
- '"$literalType" literals inside constant expressions are required to '
- 'be constant.',
- node);
- }
-
- nonConstantVariableGet(List<TreeNode> context, VariableGet node) {
- report(
- context,
- 'The variable "${node.variable.name}" is non-const and '
- 'can therefore not be used inside a constant expression.'
- ' (${node}, ${node.parent.parent}, )',
- node);
- }
-
- nonConstConstructorInvocation(
- List<TreeNode> context, TreeNode node, Constructor target) {
- report(
- context,
- 'The non-const constructor "$target" cannot be called inside a '
- 'constant expression',
- node);
- }
-
- failedAssertion(List<TreeNode> context, TreeNode node, Constant message) {
+ failedAssertion(List<TreeNode> context, TreeNode node, String message) {
report(
context,
'The assertion condition evaluated to "false" with message "$message"',
node);
}
-
- unimplemented(List<TreeNode> context, TreeNode node, String message) {
- report(context, 'Unimplemented: $message', node);
- }
-
- unreachable(List<TreeNode> context, TreeNode node, String message) {
- report(context, 'Unreachable: $message', node);
- }
}
class _SimpleErrorReporter extends ErrorReporterBase {
diff --git a/pkg/kernel/lib/transformations/generic_types_reification.dart b/pkg/kernel/lib/transformations/generic_types_reification.dart
deleted file mode 100644
index d79ab68..0000000
--- a/pkg/kernel/lib/transformations/generic_types_reification.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformation.generic_types_reification;
-
-import '../ast.dart' show Component;
-import '../core_types.dart' show CoreTypes;
-import '../transformations/reify/reify_transformer.dart' as reify
- show transformComponent;
-
-Component transformComponent(CoreTypes coreTypes, Component component) {
- return reify.transformComponent(coreTypes, component);
-}
diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
index 27effdc..a2f392620 100644
--- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart
+++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
@@ -63,7 +63,8 @@
}
// We might need to update the class hierarchy.
- hierarchy = hierarchy.applyChanges(transformedClasses);
+ hierarchy =
+ hierarchy.applyMemberChanges(transformedClasses, findDescendants: true);
if (!doSuperResolution) {
return;
diff --git a/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart b/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart
deleted file mode 100644
index df259b6..0000000
--- a/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformation.reify.analysis.program_analysis;
-
-import '../asts.dart';
-import '../../../ast.dart';
-
-// TODO(karlklose): keep all predicates and derived information here and move
-// the actual data to a builder class.
-class ProgramKnowledge {
- Map<Member, Set<TypeParameter>> _usedTypeVariables =
- <Member, Set<TypeParameter>>{};
-
- Map<Member, Set<DartType>> isTests = <Member, Set<DartType>>{};
-
- Set<Class> _classTests;
-
- /// Contains all classes that are used as the declaration of a type expression
- /// in a type test.
- Set<Class> get classTests {
- if (_classTests == null) {
- _classTests = isTests.values
- .expand((set) => set)
- .where((DartType type) => type is InterfaceType)
- .map((DartType type) => (type as InterfaceType).classNode)
- .toSet();
- }
- return _classTests;
- }
-
- recordTypeVariableUse(Expression expression, TypeParameter parameter) {
- // TODO(karlklose): also record expression.
- add(_usedTypeVariables, getEnclosingMember(expression), parameter);
- }
-
- Set<TypeParameter> usedParameters(Member member) {
- return _usedTypeVariables[member] ?? new Set<TypeParameter>();
- }
-
- void recordIsTest(IsExpression node, DartType type) {
- add(isTests, getEnclosingMember(node), type);
- }
-
- add(Map<dynamic, Set> map, key, value) {
- map.putIfAbsent(key, () => new Set()).add(value);
- }
-}
-
-typedef bool LibraryFilter(Library library);
-
-class ProgramAnalysis extends Visitor {
- final ProgramKnowledge knowledge;
- final LibraryFilter analyzeLibrary;
-
- ProgramAnalysis(this.knowledge, this.analyzeLibrary);
-
- defaultTreeNode(TreeNode node) => node.visitChildren(this);
-
- visitLibrary(Library library) {
- if (!analyzeLibrary(library)) {
- return;
- }
- super.visitLibrary(library);
- }
-
- handleTypeReference(TreeNode node, DartType type) {
- typeVariables(type).forEach((TypeParameter parameter) {
- knowledge.recordTypeVariableUse(node, parameter);
- });
- }
-
- handleInstantiation(InvocationExpression node) {
- node.arguments.types.forEach((DartType type) {
- handleTypeReference(node, type);
- });
- }
-
- visitIsExpression(IsExpression node) {
- knowledge.recordIsTest(node, node.type);
- handleTypeReference(node, node.type);
- node.visitChildren(this);
- }
-
- visitConstructorInvocation(ConstructorInvocation node) {
- handleInstantiation(node);
- node.visitChildren(this);
- }
-
- visitStaticInvocation(StaticInvocation node) {
- if (node.target.kind == ProcedureKind.Factory) {
- handleInstantiation(node);
- }
- node.visitChildren(this);
- }
-}
-
-bool _analyzeAll(Library library) => true;
-
-ProgramKnowledge analyze(Component component,
- {LibraryFilter analyzeLibrary: _analyzeAll}) {
- ProgramKnowledge knowledge = new ProgramKnowledge();
- component.accept(new ProgramAnalysis(knowledge, analyzeLibrary));
- return knowledge;
-}
diff --git a/pkg/kernel/lib/transformations/reify/asts.dart b/pkg/kernel/lib/transformations/reify/asts.dart
deleted file mode 100644
index a96225f..0000000
--- a/pkg/kernel/lib/transformations/reify/asts.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.reify.ast_helpers;
-
-import '../../ast.dart';
-
-Class getEnclosingClass(TreeNode node) {
- TreeNode original = node;
- while (node != null && node is! Class) {
- node = node.parent;
- }
- if (node == null) {
- throw 'internal error: enclosing class not found for $original';
- }
- return node;
-}
-
-Library getEnclosingLibrary(TreeNode node) {
- TreeNode original = node;
- while (node != null && node is! Library) {
- node = node.parent;
- }
- if (node == null) {
- throw 'internal error: enclosing library not found for $original';
- }
- return node;
-}
-
-Member getEnclosingMember(TreeNode node) {
- TreeNode original = node;
- while (node != null && node is! Member) {
- node = node.parent;
- }
- if (node == null) {
- throw 'internal error: enclosing member not found for $original';
- }
- return node;
-}
-
-List<TypeParameter> typeVariables(DartType type) {
- List<TypeParameter> parameters = <TypeParameter>[];
- collect(DartType type) {
- if (type is InterfaceType) {
- type.typeArguments.map(collect);
- } else if (type is TypeParameterType) {
- parameters.add(type.parameter);
- }
- }
-
- collect(type);
- return parameters;
-}
diff --git a/pkg/kernel/lib/transformations/reify/reify_transformer.dart b/pkg/kernel/lib/transformations/reify/reify_transformer.dart
deleted file mode 100644
index 5a0f2a5..0000000
--- a/pkg/kernel/lib/transformations/reify/reify_transformer.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.reify.standalone_runner;
-
-import 'analysis/program_analysis.dart';
-import 'dart:io' show File, IOSink;
-
-import '../../binary/ast_to_binary.dart' show BinaryPrinter;
-
-import '../../ast.dart';
-
-import '../../kernel.dart';
-import '../../verifier.dart';
-import '../../text/ast_to_text.dart' show Printer;
-
-import 'transformation/remove_generics.dart';
-import 'transformation/transformer.dart'
- show ReifyVisitor, RuntimeLibrary, RuntimeTypeSupportBuilder;
-
-import '../../core_types.dart' show CoreTypes;
-
-RuntimeLibrary findRuntimeTypeLibrary(Component p) {
- Library findLibraryEndingWith(String postfix) {
- Iterable<Library> candidates = p.libraries.where((Library l) {
- return l.importUri.toString().endsWith(postfix);
- });
- if (candidates.length != 1) {
- String howMany = candidates.isEmpty ? "No" : "Multiple";
- throw new Exception(
- "$howMany candidates for runtime support library found.");
- }
- return candidates.single;
- }
-
- Library types = findLibraryEndingWith("reify/types.dart");
- Library declarations = findLibraryEndingWith("reify/declarations.dart");
- Library interceptors = findLibraryEndingWith("reify/interceptors.dart");
- return new RuntimeLibrary(types, declarations, interceptors);
-}
-
-Component transformComponentUsingLibraries(
- CoreTypes coreTypes, Component component, RuntimeLibrary runtimeLibrary,
- [Library libraryToTransform]) {
- LibraryFilter filter = libraryToTransform != null
- ? (Library library) => library == libraryToTransform
- : (_) => true;
- ProgramKnowledge knowledge = analyze(component, analyzeLibrary: filter);
- Library mainLibrary = component.mainMethod.parent;
- RuntimeTypeSupportBuilder builder =
- new RuntimeTypeSupportBuilder(runtimeLibrary, coreTypes, mainLibrary);
- ReifyVisitor transformer =
- new ReifyVisitor(runtimeLibrary, builder, knowledge, libraryToTransform);
- // Transform the main component.
- component = component.accept(transformer);
- if (!filter(runtimeLibrary.interceptorsLibrary)) {
- // We need to transform the interceptor function in any case to make sure
- // that the type literals in the interceptor function are rewritten.
- runtimeLibrary.interceptorFunction.accept(transformer);
- }
- builder.createDeclarations();
- component = component.accept(new Erasure(transformer));
- // TODO(karlklose): skip checks in debug mode
- verifyComponent(component);
- return component;
-}
-
-Component transformComponent(CoreTypes coreTypes, Component component) {
- RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(component);
- Library mainLibrary = component.mainMethod.enclosingLibrary;
- return transformComponentUsingLibraries(
- coreTypes, component, runtimeLibrary, mainLibrary);
-}
-
-main(List<String> arguments) async {
- String path = arguments.first;
- Uri output;
- if (arguments.length > 1) {
- output = Uri.base.resolve(arguments[1]);
- }
- Uri uri = Uri.base.resolve(path);
- Component component = loadComponentFromBinary(uri.toFilePath());
- CoreTypes coreTypes = new CoreTypes(component);
-
- RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(component);
- Library mainLibrary = component.mainMethod.enclosingLibrary;
- component = transformComponentUsingLibraries(
- coreTypes, component, runtimeLibrary, mainLibrary);
-
- if (output == null) {
- // Print result
- StringBuffer sb = new StringBuffer();
- Printer printer = new Printer(sb);
- printer.writeLibraryFile(mainLibrary);
- print("$sb");
- } else {
- IOSink sink = new File.fromUri(output).openWrite();
- try {
- new BinaryPrinter(sink).writeComponentFile(component);
- } finally {
- await sink.close();
- }
- try {
- // Check that we can read the binary file.
- loadComponentFromBinary(output.toFilePath());
- } catch (e) {
- print("Error when attempting to read $output.");
- rethrow;
- }
- }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/binding.dart b/pkg/kernel/lib/transformations/reify/transformation/binding.dart
deleted file mode 100644
index 62aa638..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/binding.dart
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.reify.transformation.binding;
-
-import '../../../ast.dart';
-
-class RuntimeLibrary {
- final Library typesLibrary;
- final Library declarationsLibrary;
- final Library interceptorsLibrary;
-
- final Constructor dynamicTypeConstructor;
- final Constructor interfaceTypeConstructor;
- final Constructor declarationClassConstructor;
- final Constructor functionTypeConstructor;
- final Constructor voidTypeConstructor;
-
- // The class used to mark instances that implement `$type`.
- final Class markerClass;
- final Class declarationClass;
- final Class reifiedTypeClass;
-
- DartType get typeType => reifiedTypeClass.rawType;
-
- final Name variablesFieldName = new Name("variables");
-
- /// The name of the field to create for the type information. This name is
- /// extracted from the class `HasRuntimeTypeGetter`.
- final Name runtimeTypeName;
-
- final Procedure asInstanceOfFunction;
- final Procedure isSubtypeOfFunction;
- final Procedure typeArgumentsFunction;
- final Procedure allocateDeclarationsFunction;
- final Procedure initFunction;
- final Procedure interceptorFunction;
- final Procedure reifyFunction;
- final Procedure attachTypeFunction;
-
- factory RuntimeLibrary(Library typesLibrary, Library declarationsLibrary,
- Library interceptorsLibrary) {
- Class dynamicTypeClass;
- Class interfaceTypeClass;
- Class declarationClass;
- Class functionTypeClass;
- Class voidTypeClass;
- Class markerClass;
- Class reifiedTypeClass;
-
- Procedure allocateDeclarationsFunction;
- Procedure initFunction;
- Procedure interceptorFunction;
- Procedure reifyFunction;
- Procedure attachTypeFunction;
- Procedure asInstanceOfFunction;
- Procedure isSubtypeOfFunction;
- Procedure typeArgumentsFunction;
-
- for (Procedure p in interceptorsLibrary.procedures) {
- if (p.name.name == "type") {
- interceptorFunction = p;
- } else if (p.name.name == "reify") {
- reifyFunction = p;
- } else if (p.name.name == "attachType") {
- attachTypeFunction = p;
- }
- }
- for (Class c in interceptorsLibrary.classes) {
- if (c.name == "HasRuntimeTypeGetter") {
- markerClass = c;
- }
- }
- for (Class c in typesLibrary.classes) {
- if (c.name == 'Dynamic') {
- dynamicTypeClass = c;
- } else if (c.name == 'Interface') {
- interfaceTypeClass = c;
- } else if (c.name == 'FunctionType') {
- functionTypeClass = c;
- } else if (c.name == 'Void') {
- voidTypeClass = c;
- } else if (c.name == 'ReifiedType') {
- reifiedTypeClass = c;
- }
- }
- for (Procedure p in typesLibrary.procedures) {
- if (p.name.name == "asInstanceOf") {
- asInstanceOfFunction = p;
- } else if (p.name.name == "isSubtypeOf") {
- isSubtypeOfFunction = p;
- } else if (p.name.name == "getTypeArguments") {
- typeArgumentsFunction = p;
- }
- }
- for (Procedure p in declarationsLibrary.procedures) {
- if (p.name.name == "allocateDeclarations") {
- allocateDeclarationsFunction = p;
- } else if (p.name.name == "init") {
- initFunction = p;
- }
- }
- for (Class c in declarationsLibrary.classes) {
- if (c.name == 'Class') {
- declarationClass = c;
- }
- }
-
- assert(dynamicTypeClass != null);
- assert(declarationClass != null);
- assert(interfaceTypeClass != null);
- assert(functionTypeClass != null);
- assert(voidTypeClass != null);
- assert(markerClass != null);
- assert(declarationClass != null);
- assert(reifiedTypeClass != null);
- assert(allocateDeclarationsFunction != null);
- assert(initFunction != null);
- assert(interceptorFunction != null);
- assert(reifyFunction != null);
- assert(attachTypeFunction != null);
- assert(asInstanceOfFunction != null);
- assert(isSubtypeOfFunction != null);
- assert(typeArgumentsFunction != null);
-
- return new RuntimeLibrary._(
- markerClass.procedures.single.name,
- typesLibrary,
- declarationsLibrary,
- interceptorsLibrary,
- markerClass,
- declarationClass,
- reifiedTypeClass,
- dynamicTypeClass.constructors.single,
- interfaceTypeClass.constructors.single,
- declarationClass.constructors.single,
- functionTypeClass.constructors.single,
- voidTypeClass.constructors.single,
- allocateDeclarationsFunction,
- initFunction,
- interceptorFunction,
- reifyFunction,
- attachTypeFunction,
- asInstanceOfFunction,
- isSubtypeOfFunction,
- typeArgumentsFunction);
- }
-
- RuntimeLibrary._(
- this.runtimeTypeName,
- this.typesLibrary,
- this.declarationsLibrary,
- this.interceptorsLibrary,
- this.markerClass,
- this.declarationClass,
- this.reifiedTypeClass,
- this.dynamicTypeConstructor,
- this.interfaceTypeConstructor,
- this.declarationClassConstructor,
- this.functionTypeConstructor,
- this.voidTypeConstructor,
- this.allocateDeclarationsFunction,
- this.initFunction,
- this.interceptorFunction,
- this.reifyFunction,
- this.attachTypeFunction,
- this.asInstanceOfFunction,
- this.isSubtypeOfFunction,
- this.typeArgumentsFunction);
-
- /// Returns `true` if [node] is defined in the runtime library.
- bool contains(TreeNode node) {
- while (node is! Library) {
- node = node.parent;
- if (node == null) return false;
- }
- return node == typesLibrary || node == declarationsLibrary;
- }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/builder.dart b/pkg/kernel/lib/transformations/reify/transformation/builder.dart
deleted file mode 100644
index 7f0ea0e..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/builder.dart
+++ /dev/null
@@ -1,509 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.reify.transformation.builder;
-
-import '../asts.dart';
-import '../../../ast.dart';
-import 'dart:collection' show LinkedHashMap;
-import 'binding.dart' show RuntimeLibrary;
-import '../../../core_types.dart' show CoreTypes;
-
-class Scope {
- final Map<String, TreeNode> names = <String, TreeNode>{};
-
- bool nameAlreadyTaken(String name, TreeNode node) {
- TreeNode existing = names[name];
- return existing != null && existing == node;
- }
-
- void add(String name, TreeNode node) {
- assert(!nameAlreadyTaken(name, node));
- names[name] = node;
- }
-}
-
-class Namer {
- final Scope scope;
- Namer([Scope scope]) : this.scope = scope ?? new Scope();
-
- String _getProposal(TreeNode node) {
- if (node is Class) {
- return node.name;
- }
- throw 'unsupported node: $node';
- }
-
- String getNameFor(TreeNode node) {
- String base = _getProposal(node);
- int id = 0;
- String proposal = base;
- while (scope.nameAlreadyTaken(proposal, node)) {
- proposal = "$base${++id}";
- }
- scope.add(proposal, node);
- return proposal;
- }
-}
-
-class RuntimeTypeSupportBuilder {
- // TODO(karlklose): group this together with other information about what
- // needs to be built.
- final LinkedHashMap<Class, int> reifiedClassIds =
- new LinkedHashMap<Class, int>();
-
- int currentDeclarationId = 0;
-
- final Field declarations;
-
- final RuntimeLibrary rtiLibrary;
-
- final CoreTypes coreTypes;
-
- final DartType declarationType;
-
- RuntimeTypeSupportBuilder(
- RuntimeLibrary rtiLibrary, CoreTypes coreTypes, Library mainLibrary)
- : declarations = new Field(new Name(r"$declarations"),
- isFinal: true, isStatic: true, fileUri: mainLibrary.fileUri),
- declarationType = new InterfaceType(coreTypes.listClass,
- <DartType>[rtiLibrary.declarationClass.rawType]),
- rtiLibrary = rtiLibrary,
- coreTypes = coreTypes {
- mainLibrary.addMember(declarations);
- }
-
- int addDeclaration(Class cls) {
- return reifiedClassIds.putIfAbsent(cls, () {
- return currentDeclarationId++;
- });
- }
-
- final Name indexOperatorName = new Name("[]");
-
- MethodInvocation createArrayAccess(Expression target, int index) {
- return new MethodInvocation(target, indexOperatorName,
- new Arguments(<Expression>[new IntLiteral(index)]));
- }
-
- Expression createAccessDeclaration(Class cls) {
- return createArrayAccess(new StaticGet(declarations), addDeclaration(cls));
- }
-
- Name getTypeTestTagName(Class cls) {
- return new Name('\$is\$${cls.name}');
- }
-
- Name typeVariableGetterName(TypeParameter parameter) {
- Class cls = getEnclosingClass(parameter);
- return new Name("\$${cls.name}\$${parameter.name}");
- }
-
- // A call to a constructor or factory of a class that we have not transformed
- // is wrapped in a call to `attachType`.
- Expression attachTypeToConstructorInvocation(
- InvocationExpression invocation, Member member) {
- assert(member is Procedure && member.kind == ProcedureKind.Factory ||
- member is Constructor);
- Class targetClass = member.parent;
- assert(targetClass != null);
- DartType type = new InterfaceType(targetClass, invocation.arguments.types);
- return callAttachType(invocation, type);
- }
-
- Expression callAttachType(Expression expression, DartType type) {
- return new StaticInvocation(rtiLibrary.attachTypeFunction,
- new Arguments(<Expression>[expression, createRuntimeType(type)]));
- }
-
- Expression createGetType(Expression receiver, {needsInterceptor: true}) {
- if (receiver is ThisExpression || !needsInterceptor) {
- return new PropertyGet(receiver, rtiLibrary.runtimeTypeName);
- }
- return new StaticInvocation(
- rtiLibrary.interceptorFunction, new Arguments(<Expression>[receiver]));
- }
-
- Expression createGetTypeArguments(Expression typeObject) {
- return new StaticInvocation(rtiLibrary.typeArgumentsFunction,
- new Arguments(<Expression>[typeObject]));
- }
-
- // TODO(karlklose): consider adding a unique identifier for each test site.
- /// `receiver.[subtypeTestName]([type])`
- StaticInvocation createIsSubtypeOf(
- Expression receiver, Expression typeExpression,
- {targetHasTypeProperty: false}) {
- Expression receiverType =
- createGetType(receiver, needsInterceptor: !targetHasTypeProperty);
- return new StaticInvocation(rtiLibrary.isSubtypeOfFunction,
- new Arguments(<Expression>[receiverType, typeExpression]));
- }
-
- int getTypeVariableIndex(TypeParameter variable) {
- Class c = getEnclosingClass(variable);
- List<TypeParameter> variables = c.typeParameters;
- for (int i = 0; i < variables.length; ++i) {
- if (variables[i].name == variable.name) {
- return i;
- }
- }
- throw new Exception(
- "Type variable $variable not found in enclosing class $c");
- }
-
- Expression createNewInterface(
- Expression declaration, Expression typeArgumentList) {
- List<Expression> arguments = <Expression>[declaration];
- if (typeArgumentList != null) {
- arguments.add(typeArgumentList);
- }
- return new ConstructorInvocation(
- rtiLibrary.interfaceTypeConstructor, new Arguments(arguments));
- }
-
- /// Returns `true` if [types] is a list of [TypeParameterType]s that exactly
- /// match the [TypeParameters] of the class they are defined in, i.e.,
- /// for all 0 <= i < cls.typeParameters.length.
- /// types[i].parameter == cls.typeParameters[i].
- bool matchesTypeParameters(List<DartType> types) {
- List<TypeParameter> parameters;
- for (int i = 0; i < types.length; ++i) {
- var type = types[i];
- if (type is TypeParameterType) {
- if (parameters == null) {
- Class cls = getEnclosingClass(type.parameter);
- parameters = cls.typeParameters;
- if (parameters.length != types.length) return false;
- }
- if (type.parameter != parameters[i]) {
- return false;
- }
- } else {
- return false;
- }
- }
- return true;
- }
-
- // TODO(karlklose): Refactor into visitor.
- // TODO(karlklose): split this method in different strategies.
- /// Creates an expression to represent a runtime type instance of type [type].
- Expression createRuntimeType(DartType type,
- {reifyTypeVariable: false,
- Expression createReference(Class cls),
- VariableDeclaration typeContext}) {
- Expression buildReifiedTypeVariable(TypeParameterType type) {
- Expression typeVariables = new PropertyGet(
- createReference(type.parameter.parent),
- rtiLibrary.variablesFieldName);
- return createArrayAccess(
- typeVariables, getTypeVariableIndex(type.parameter));
- }
-
- Expression buildDirectTypeVariableAccess(TypeParameterType variable) {
- Class cls = getEnclosingClass(variable.parameter);
- return extractTypeVariable(
- cls,
- variable.parameter,
- getTypeVariableIndex(variable.parameter),
- new VariableGet(typeContext));
- }
-
- Expression buildGetterTypeVariableAccess(TypeParameterType type) {
- return new PropertyGet(
- new ThisExpression(), typeVariableGetterName(type.parameter));
- }
-
- Expression buildTypeVariable(TypeParameterType type) {
- if (reifyTypeVariable) {
- assert(typeContext == null);
- return buildReifiedTypeVariable(type);
- } else if (typeContext != null) {
- return buildDirectTypeVariableAccess(type);
- } else {
- return buildGetterTypeVariableAccess(type);
- }
- }
-
- createReference ??= createAccessDeclaration;
-
- /// Helper to make recursive invocation more readable.
- Expression createPart(DartType type) {
- return createRuntimeType(type,
- reifyTypeVariable: reifyTypeVariable,
- createReference: createReference,
- typeContext: typeContext);
- }
-
- if (type is InterfaceType || type is Supertype) {
- InterfaceType interfaceType =
- (type is InterfaceType) ? type : (type as Supertype).asInterfaceType;
- Class cls = interfaceType.classNode;
- Expression declaration = createReference(cls);
- List<DartType> typeArguments = interfaceType.typeArguments;
- Expression typeArgumentList;
- if (typeArguments.isNotEmpty) {
- if (!reifyTypeVariable && matchesTypeParameters(typeArguments)) {
- // The type argument list corresponds to the list of type parameters
- // and we are not in "declaration emitter" mode, we can reuse the
- // type argument vector.
- TypeParameterType parameterType = typeArguments[0];
- Class cls = parameterType.parameter.parent;
- Expression typeObject = typeContext != null
- ? new VariableGet(typeContext)
- : createGetType(new ThisExpression());
- typeArgumentList =
- createGetTypeArguments(createCallAsInstanceOf(typeObject, cls));
- } else {
- typeArgumentList =
- new ListLiteral(typeArguments.map(createPart).toList());
- }
- }
- return createNewInterface(declaration, typeArgumentList);
- } else if (type is DynamicType) {
- return new ConstructorInvocation(
- rtiLibrary.dynamicTypeConstructor, new Arguments([]),
- isConst: true);
- } else if (type is TypeParameterType) {
- return buildTypeVariable(type);
- } else if (type is FunctionType) {
- FunctionType functionType = type;
- Expression returnType = createPart(functionType.returnType);
- List<Expression> encodedParameterTypes =
- functionType.positionalParameters.map(createPart).toList();
- List<NamedType> namedParameters = functionType.namedParameters;
- int data;
- if (namedParameters.isNotEmpty) {
- for (NamedType param in namedParameters) {
- encodedParameterTypes.add(new StringLiteral(param.name));
- encodedParameterTypes.add(createPart(param.type));
- }
- data = functionType.namedParameters.length << 1 | 1;
- } else {
- data = (functionType.positionalParameters.length -
- functionType.requiredParameterCount) <<
- 1;
- }
- Expression functionTypeExpression = new ConstructorInvocation(
- rtiLibrary.interfaceTypeConstructor,
- new Arguments(
- <Expression>[createReference(coreTypes.functionClass)]));
- Arguments arguments = new Arguments(<Expression>[
- functionTypeExpression,
- returnType,
- new IntLiteral(data),
- new ListLiteral(encodedParameterTypes)
- ]);
- return new ConstructorInvocation(
- rtiLibrary.functionTypeConstructor, arguments);
- } else if (type is VoidType) {
- return new ConstructorInvocation(
- rtiLibrary.voidTypeConstructor, new Arguments(<Expression>[]));
- }
- return new InvalidExpression(null);
- }
-
- Expression createCallAsInstanceOf(Expression receiver, Class cls) {
- return new StaticInvocation(rtiLibrary.asInstanceOfFunction,
- new Arguments(<Expression>[receiver, createAccessDeclaration(cls)]));
- }
-
- /// `get get$<variable-name> => <get-type>.arguments[<variable-index>]`
- Member createTypeVariableGetter(
- Class cls, TypeParameter variable, int index) {
- Expression type = createGetType(new ThisExpression());
- Expression argument = extractTypeVariable(cls, variable, index, type);
- return new Procedure(
- typeVariableGetterName(variable),
- ProcedureKind.Getter,
- new FunctionNode(new ReturnStatement(argument),
- returnType: rtiLibrary.typeType),
- fileUri: cls.fileUri);
- }
-
- Expression extractTypeVariable(
- Class cls, TypeParameter variable, int index, Expression typeObject) {
- Expression type = createCallAsInstanceOf(typeObject, cls);
- Expression arguments = new StaticInvocation(
- rtiLibrary.typeArgumentsFunction, new Arguments(<Expression>[type]));
- // TODO(karlklose): use the global index instead of the local one.
- return createArrayAccess(arguments, index);
- }
-
- void insertAsFirstArgument(Arguments arguments, Expression expression) {
- expression.parent = arguments;
- arguments.positional.insert(0, expression);
- }
-
- /// Creates a call to the `init` function that completes the definition of a
- /// class by setting its (direct) supertypes.
- Expression createCallInit(
- VariableDeclaration declarations,
- int index,
- InterfaceType supertype,
- List<InterfaceType> interfaces,
- FunctionType callableType) {
- /// Helper to create a reference to the declaration in the declaration
- /// list instead of the field to avoid cycles if that field's
- /// initialization depends on the class we are currently initializing.
- Expression createReference(Class declaration) {
- int id = reifiedClassIds[declaration];
- return createArrayAccess(new VariableGet(declarations), id);
- }
-
- bool isNotMarkerInterface(InterfaceType interface) {
- return interface.classNode != rtiLibrary.markerClass;
- }
-
- Expression createLocalType(DartType type) {
- if (type == null) return null;
- return createRuntimeType(type,
- reifyTypeVariable: true, createReference: createReference);
- }
-
- Expression supertypeExpression =
- supertype == null ? new NullLiteral() : createLocalType(supertype);
-
- List<Expression> interfaceTypes = interfaces
- .where(isNotMarkerInterface)
- .map(createLocalType)
- .toList(growable: false);
-
- Expression callableTypeExpression = createLocalType(callableType);
-
- List<Expression> arguments = <Expression>[
- new VariableGet(declarations),
- new IntLiteral(index),
- supertypeExpression,
- ];
-
- if (interfaceTypes.isNotEmpty || callableTypeExpression != null) {
- arguments.add(new ListLiteral(interfaceTypes));
- if (callableTypeExpression != null) {
- arguments.add(callableTypeExpression);
- }
- }
-
- return new StaticInvocation(
- rtiLibrary.initFunction, new Arguments(arguments));
- }
-
- Expression createDeclarationsInitializer() {
- List<Statement> statements = <Statement>[];
- // Call function to allocate the class declarations given the names and
- // number of type variables of the classes.
- Namer classNamer = new Namer();
- List<Expression> names = <Expression>[];
- List<Expression> parameterCount = <Expression>[];
- reifiedClassIds.keys.forEach((Class c) {
- names.add(new StringLiteral(classNamer.getNameFor(c)));
- parameterCount.add(new IntLiteral(c.typeParameters.length));
- });
- Expression namesList = new ListLiteral(names);
- Expression parameterCountList = new ListLiteral(parameterCount);
- StaticInvocation callAllocate = new StaticInvocation(
- rtiLibrary.allocateDeclarationsFunction,
- new Arguments(<Expression>[namesList, parameterCountList]));
-
- VariableDeclaration parameter =
- new VariableDeclaration("d", type: declarationType);
-
- reifiedClassIds.forEach((Class cls, int id) {
- if (cls == rtiLibrary.markerClass) return;
-
- // If the class declares a `call` method, translate the signature to a
- // reified type.
- FunctionType callableType;
- Procedure call = cls.procedures.firstWhere(
- (Procedure p) => p.name.name == "call",
- orElse: () => null);
- if (call != null) {
- FunctionNode function = call.function;
-
- final namedParameters = new List<NamedType>();
- for (VariableDeclaration v in function.namedParameters) {
- namedParameters.add(new NamedType(v.name, v.type));
- }
-
- List<DartType> positionalArguments = function.positionalParameters
- .map((VariableDeclaration v) => v.type)
- .toList();
- callableType = new FunctionType(
- positionalArguments, function.returnType,
- namedParameters: namedParameters,
- requiredParameterCount: function.requiredParameterCount);
- }
- statements.add(new ExpressionStatement(createCallInit(
- parameter,
- id,
- cls.supertype?.asInterfaceType,
- cls.implementedTypes
- .map((Supertype type) => type?.asInterfaceType)
- .toList(),
- callableType)));
- });
-
- statements.add(new ReturnStatement(new VariableGet(parameter)));
-
- Expression function = new FunctionExpression(new FunctionNode(
- new Block(statements),
- positionalParameters: <VariableDeclaration>[parameter],
- returnType: declarationType));
-
- return new MethodInvocation(
- function, new Name("call"), new Arguments(<Expression>[callAllocate]));
- }
-
- void createDeclarations() {
- /// Recursively find all referenced classes in [type].
- void collectNewReferencedClasses(DartType type, Set<Class> newClasses) {
- if (type is InterfaceType || type is Supertype) {
- InterfaceType interfaceType = null;
- if (type is InterfaceType) {
- interfaceType = type;
- } else {
- interfaceType = (type as Supertype).asInterfaceType;
- }
- Class cls = interfaceType.classNode;
- if (!reifiedClassIds.containsKey(cls) && !newClasses.contains(cls)) {
- newClasses.add(cls);
- }
-
- interfaceType.typeArguments.forEach((DartType argument) {
- collectNewReferencedClasses(argument, newClasses);
- });
- }
- // TODO(karlklose): function types
- }
-
- Iterable<Class> classes = reifiedClassIds.keys;
- while (classes.isNotEmpty) {
- Set<Class> newClasses = new Set<Class>();
- for (Class c in classes) {
- collectNewReferencedClasses(c.supertype?.asInterfaceType, newClasses);
- c.implementedTypes.forEach((Supertype supertype) {
- collectNewReferencedClasses(supertype?.asInterfaceType, newClasses);
- });
- }
- for (Class newClass in newClasses) {
- // Make sure that there is a declaration field for the class and its
- // library's declaration list is setup.
- addDeclaration(newClass);
- }
- classes = newClasses;
- }
- Expression initializer = createDeclarationsInitializer();
- initializer.parent = declarations;
- declarations.initializer = initializer;
- declarations.type = declarationType;
- }
-
- Procedure createGetter(
- Name name, Expression expression, Class cls, DartType type) {
- return new Procedure(name, ProcedureKind.Getter,
- new FunctionNode(new ReturnStatement(expression), returnType: type),
- fileUri: cls.fileUri);
- }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart b/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart
deleted file mode 100644
index 25d8fe6..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.reify.transformation.remove_generics;
-
-import '../../../ast.dart';
-import 'transformer.dart';
-
-class Erasure extends Transformer with DartTypeVisitor<DartType> {
- final ReifyVisitor reifyVisitor;
-
- Erasure(this.reifyVisitor);
-
- bool removeTypeParameters(Class cls) {
- return reifyVisitor.needsTypeInformation(cls);
- }
-
- TreeNode removeTypeArgumentsOfConstructorCall(ConstructorInvocation node) {
- Class cls = node.target.parent;
- if (removeTypeParameters(cls)) {
- node.arguments.types.clear();
- Constructor target = node.target;
- target.enclosingClass.typeParameters.clear();
- }
- return node;
- }
-
- TreeNode removeTypeArgumentsOfStaticCall(StaticInvocation node) {
- if (node.target.parent is Class) {
- Class cls = node.target.parent;
- if (!removeTypeParameters(cls)) {
- return node;
- }
- } else {
- // If parent is a Library, then a global procedure is invoked, and it may
- // be a generic function, so we need to remove type arguments anyway.
- assert(node.target.parent is Library);
- }
- node.arguments.types.clear();
- Procedure target = node.target;
- target.function.typeParameters.clear();
- return node;
- }
-
- TreeNode removeTypeArgumentOfMethodInvocation(MethodInvocation node) {
- node.arguments.types.clear();
- return node;
- }
-
- @override
- defaultDartType(DartType type) => type;
-
- @override
- InterfaceType visitInterfaceType(InterfaceType type) {
- if (removeTypeParameters(type.classNode)) {
- return new InterfaceType(type.classNode, const <DartType>[]);
- }
- return type;
- }
-
- @override
- TypedefType visitTypedefType(TypedefType type) {
- throw 'Typedef types not implemented in erasure';
- }
-
- @override
- Supertype visitSupertype(Supertype type) {
- if (removeTypeParameters(type.classNode)) {
- return new Supertype(type.classNode, const <DartType>[]);
- }
- return type;
- }
-
- @override
- FunctionType visitFunctionType(FunctionType type) {
- bool partHasChanged = false;
-
- DartType translate(DartType type) {
- DartType newType = type.accept(this);
- if (newType != type) {
- partHasChanged = true;
- return newType;
- } else {
- return type;
- }
- }
-
- DartType returnType = translate(type.returnType);
- List<DartType> positionalTypes =
- type.positionalParameters.map(translate).toList();
- List<NamedType> namedParameters = new List<NamedType>();
- for (NamedType param in type.namedParameters) {
- namedParameters.add(new NamedType(param.name, translate(param.type)));
- }
- if (partHasChanged) {
- return new FunctionType(positionalTypes, returnType,
- namedParameters: namedParameters,
- requiredParameterCount: type.requiredParameterCount);
- } else {
- return type;
- }
- }
-
- @override
- DynamicType visitTypeParameterType(_) => const DynamicType();
-
- @override
- DartType visitDartType(DartType type) {
- return type.accept(this);
- }
-
- @override
- StaticInvocation visitStaticInvocation(StaticInvocation node) {
- node.transformChildren(this);
- if (node.target.kind == ProcedureKind.Factory ||
- node.target.kind == ProcedureKind.Method) {
- node = removeTypeArgumentsOfStaticCall(node);
- }
- return node;
- }
-
- @override
- ConstructorInvocation visitConstructorInvocation(ConstructorInvocation node) {
- node.transformChildren(this);
- return removeTypeArgumentsOfConstructorCall(node);
- }
-
- @override
- Class visitClass(Class node) {
- node.transformChildren(this);
- if (removeTypeParameters(node)) {
- node.typeParameters.clear();
- }
- return node;
- }
-
- @override
- Expression visitMethodInvocation(MethodInvocation node) {
- node.transformChildren(this);
- return removeTypeArgumentOfMethodInvocation(node);
- }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/transformer.dart b/pkg/kernel/lib/transformations/reify/transformation/transformer.dart
deleted file mode 100644
index 0ca6b87..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/transformer.dart
+++ /dev/null
@@ -1,624 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library kernel.transformations.reify.transformation.transformer;
-
-import '../analysis/program_analysis.dart';
-import '../../../ast.dart';
-import 'binding.dart' show RuntimeLibrary;
-import 'builder.dart' show RuntimeTypeSupportBuilder;
-import 'dart:collection' show LinkedHashMap;
-import '../asts.dart';
-
-export 'binding.dart' show RuntimeLibrary;
-export 'builder.dart' show RuntimeTypeSupportBuilder;
-
-enum RuntimeTypeStorage {
- none,
- inheritedField,
- field,
- getter,
-}
-
-class TransformationContext {
- /// Describes how the runtime type is stored on the object.
- RuntimeTypeStorage runtimeTypeStorage;
-
- /// Field added to store the runtime type if [runtimeType] is
- /// [RuntimeTypeStorage.field].
- Field runtimeTypeField;
-
- /// The parameter for the type information introduced to the constructor or
- /// to static initializers.
- VariableDeclaration parameter;
-
- /// A ordered collection of fields together with their initializers rewritten
- /// to static initializer functions that can be used in the constructor's
- /// initializer list.
- /// The order is important because of possible side-effects in the
- /// initializers.
- LinkedHashMap<Field, Procedure> initializers;
-
- // `true` if the visitor currently is in a field initializer, a initializer
- // list of a constructor, or the body of a factory method. In these cases,
- // type argument access is different than in an instance context, since `this`
- // is not available.
- bool inInitializer = false;
-
- String toString() => "s: ${runtimeTypeStorage} f: $runtimeTypeField,"
- " p: $parameter, i: $inInitializer";
-}
-
-abstract class DebugTrace {
- static const bool debugTrace = false;
-
- static const int lineLength = 80;
-
- TransformationContext get context;
-
- String getNodeLevel(TreeNode node) {
- String level = "";
- while (node != null && node is! Library) {
- level = " $level";
- node = node.parent;
- }
- return level;
- }
-
- String shorten(String s) {
- return s.length > lineLength ? s.substring(0, lineLength) : s;
- }
-
- void trace(TreeNode node) {
- if (debugTrace) {
- String nodeText = node.toString().replaceAll("\n", " ");
- print(shorten("trace:${getNodeLevel(node)}$context"
- " [${node.runtimeType}] $nodeText"));
- }
- }
-}
-
-/// Rewrites a tree to remove generic types and runtime type checks and replace
-/// them with Dart objects.
-///
-/// Runtime types are stored in a field/getter called [runtimeTypeName] on the
-/// object, which for parameterized classes is initialized in the constructor.
-// TODO(karlklose):
-// - add a scoped namer
-// - rewrite types (supertypes, implemented types)
-// - rewrite as
-class ReifyVisitor extends Transformer with DebugTrace {
- final RuntimeLibrary rtiLibrary;
- final RuntimeTypeSupportBuilder builder;
- final ProgramKnowledge knowledge;
-
- ReifyVisitor(this.rtiLibrary, this.builder, this.knowledge,
- [this.libraryToTransform]);
-
- /// If not null, the transformation will only be applied to classes declared
- /// in this library.
- final Library libraryToTransform;
-
- // TODO(karlklose): find a way to get rid of this state in the visitor.
- TransformationContext context;
-
- static const String genericMethodTypeParametersName = r"$typeParameters";
-
- bool libraryShouldBeTransformed(Library library) {
- return libraryToTransform == null || libraryToTransform == library;
- }
-
- bool needsTypeInformation(Class cls) {
- return !isObject(cls) &&
- !rtiLibrary.contains(cls) &&
- libraryShouldBeTransformed(cls.enclosingLibrary);
- }
-
- bool usesTypeGetter(Class cls) {
- return cls.typeParameters.isEmpty;
- }
-
- bool isObject(Class cls) {
- // TODO(karlklose): use [CoreTypes].
- return "$cls" == 'dart.core::Object';
- }
-
- Initializer addTypeAsArgument(initializer) {
- assert(initializer is SuperInitializer ||
- initializer is RedirectingInitializer);
- Class cls = getEnclosingClass(initializer.target);
- if (needsTypeInformation(cls) && !usesTypeGetter(cls)) {
- // If the current class uses a getter for type information, we did not add
- // a parameter to the constructor, but we can pass `null` as the value to
- // initialize the type field, since it will be shadowed by the getter.
- Expression type = (context.parameter != null)
- ? new VariableGet(context.parameter)
- : new NullLiteral();
- builder.insertAsFirstArgument(initializer.arguments, type);
- }
- return initializer;
- }
-
- Expression interceptInstantiation(
- InvocationExpression invocation, Member target) {
- Class targetClass = target.parent;
- Library targetLibrary = targetClass.parent;
- Library currentLibrary = getEnclosingLibrary(invocation);
- if (libraryShouldBeTransformed(currentLibrary) &&
- !libraryShouldBeTransformed(targetLibrary) &&
- !rtiLibrary.contains(target)) {
- return builder.attachTypeToConstructorInvocation(invocation, target);
- }
- return invocation;
- }
-
- Expression createRuntimeType(DartType type) {
- if (context?.inInitializer == true) {
- // In initializer context, the instance type is provided in
- // `context.parameter` as there is no `this`.
- return builder.createRuntimeType(type, typeContext: context.parameter);
- } else {
- return builder.createRuntimeType(type);
- }
- }
-
- TreeNode defaultTreeNode(TreeNode node) {
- trace(node);
- return super.defaultTreeNode(node);
- }
-
- Expression visitStaticInvocation(StaticInvocation invocation) {
- trace(invocation);
-
- invocation.transformChildren(this);
-
- Procedure target = invocation.target;
- if (target == rtiLibrary.reifyFunction) {
- /// Rewrite calls to reify(TypeLiteral) to a reified type.
- TypeLiteral literal = invocation.arguments.positional.single;
- return createRuntimeType(literal.type);
- } else if (target.kind == ProcedureKind.Factory) {
- // Intercept calls to factories of classes we do not transform
- return interceptInstantiation(invocation, target);
- }
-
- addTypeArgumentToGenericInvocation(invocation);
-
- return invocation;
- }
-
- Library visitLibrary(Library library) {
- trace(library);
-
- if (libraryShouldBeTransformed(library)) {
- library.transformChildren(this);
- }
- return library;
- }
-
- Expression visitConstructorInvocation(ConstructorInvocation invocation) {
- invocation.transformChildren(this);
- return interceptInstantiation(invocation, invocation.target);
- }
-
- Member getStaticInvocationTarget(InvocationExpression invocation) {
- if (invocation is ConstructorInvocation) {
- return invocation.target;
- } else if (invocation is StaticInvocation) {
- return invocation.target;
- } else {
- throw "Unexpected InvocationExpression $invocation.";
- }
- }
-
- bool isInstantiation(TreeNode invocation) {
- return invocation is ConstructorInvocation ||
- invocation is StaticInvocation &&
- invocation.target.kind == ProcedureKind.Factory;
- }
-
- bool isTypeVariable(DartType type) => type is TypeParameterType;
-
- /// Add the runtime type as an extra argument to constructor invocations.
- Arguments visitArguments(Arguments arguments) {
- trace(arguments);
-
- arguments.transformChildren(this);
- TreeNode parent = arguments.parent;
- if (isInstantiation(parent)) {
- Class targetClass = getEnclosingClass(getStaticInvocationTarget(parent));
- // Do not add the extra argument if the class does not need a type member
- // or if it can be implemented as a getter.
- if (!needsTypeInformation(targetClass) || usesTypeGetter(targetClass)) {
- return arguments;
- }
-
- List<DartType> typeArguments = arguments.types;
-
- Expression type =
- createRuntimeType(new InterfaceType(targetClass, typeArguments));
-
- builder.insertAsFirstArgument(arguments, type);
- }
- return arguments;
- }
-
- Field visitField(Field field) {
- trace(field);
-
- visitDartType(field.type);
- for (Expression annotation in field.annotations) {
- annotation.accept(this);
- }
- // Do not visit initializers, they have already been transformed when the
- // class was handled.
- return field;
- }
-
- /// Go through all initializers of fields and record a static initializer
- /// function, if necessary.
- void rewriteFieldInitializers(Class cls) {
- assert(context != null);
- context.initializers = new LinkedHashMap<Field, Procedure>();
- List<Field> fields = cls.fields;
- bool initializerRewritten = false;
- for (Field field in fields) {
- if (!initializerRewritten && knowledge.usedParameters(field).isEmpty) {
- // This field needs no static initializer.
- continue;
- }
-
- Expression initializer = field.initializer;
- if (initializer == null || field.isStatic) continue;
- // Declare a new variable that holds the type information and can be
- // used to access type variables in initializer context.
- // TODO(karlklose): some fields do not need the parameter.
- VariableDeclaration typeObject = new VariableDeclaration(r"$type");
- context.parameter = typeObject;
- context.inInitializer = true;
- // Translate the initializer while keeping track of whether there was
- // already an initializers that required type information in
- // [typeVariableUsedInInitializer].
- initializer = initializer.accept(this);
- context.parameter = null;
- context.inInitializer = false;
- // Create a static initializer function from the translated initializer
- // expression and record it.
- Name name = new Name("\$init\$${field.name.name}");
- Statement body = new ReturnStatement(initializer);
- Procedure staticInitializer = new Procedure(
- name,
- ProcedureKind.Method,
- new FunctionNode(body,
- positionalParameters: <VariableDeclaration>[typeObject]),
- isStatic: true,
- fileUri: cls.fileUri);
- context.initializers[field] = staticInitializer;
- // Finally, remove the initializer from the field.
- field.initializer = null;
- }
- }
-
- bool inheritsTypeProperty(Class cls) {
- assert(needsTypeInformation(cls));
- Class superclass = cls.superclass;
- return needsTypeInformation(superclass);
- }
-
- Class visitClass(Class cls) {
- trace(cls);
-
- if (needsTypeInformation(cls)) {
- context = new TransformationContext();
- List<TypeParameter> typeParameters = cls.typeParameters;
- if (usesTypeGetter(cls)) {
- assert(typeParameters.isEmpty);
- context.runtimeTypeStorage = RuntimeTypeStorage.getter;
- Member getter = builder.createGetter(rtiLibrary.runtimeTypeName,
- createRuntimeType(cls.rawType), cls, rtiLibrary.typeType);
- cls.addMember(getter);
- } else if (!inheritsTypeProperty(cls)) {
- context.runtimeTypeStorage = RuntimeTypeStorage.field;
- // TODO(karlklose): should we add the field to [Object]?
- context.runtimeTypeField = new Field(rtiLibrary.runtimeTypeName,
- fileUri: cls.fileUri, isFinal: true, type: rtiLibrary.typeType);
- cls.addMember(context.runtimeTypeField);
- } else {
- context.runtimeTypeStorage = RuntimeTypeStorage.inheritedField;
- }
-
- for (int i = 0; i < typeParameters.length; ++i) {
- TypeParameter variable = typeParameters[i];
- cls.addMember(builder.createTypeVariableGetter(cls, variable, i));
- }
-
- // Tag the class as supporting the runtime type getter.
- InterfaceType interfaceTypeForSupertype =
- new InterfaceType(rtiLibrary.markerClass);
- cls.implementedTypes.add(new Supertype(
- interfaceTypeForSupertype.classNode,
- interfaceTypeForSupertype.typeArguments));
-
- // Before transforming the parts of the class declaration, rewrite field
- // initializers that use type variables (or that would be called after one
- // that does) to static functions that can be used from constructors.
- rewriteFieldInitializers(cls);
-
- // Add properties for declaration tests.
- for (Class test in knowledge.classTests) {
- if (test == rtiLibrary.markerClass) continue;
-
- Procedure tag = builder.createGetter(
- builder.getTypeTestTagName(test),
- new BoolLiteral(isSuperClass(test, cls)),
- cls,
- builder.coreTypes.boolClass.rawType);
- cls.addMember(tag);
- }
-
- // Add a runtimeType getter.
- if (!usesTypeGetter(cls) && !inheritsTypeProperty(cls)) {
- cls.addMember(new Procedure(
- new Name("runtimeType"),
- ProcedureKind.Getter,
- new FunctionNode(
- new ReturnStatement(new DirectPropertyGet(
- new ThisExpression(), context.runtimeTypeField)),
- returnType: builder.coreTypes.typeClass.rawType),
- fileUri: cls.fileUri));
- }
- }
-
- cls.transformChildren(this);
-
- // Add the static initializer functions. They have already been transformed.
- if (context?.initializers != null) {
- context.initializers.forEach((_, Procedure initializer) {
- cls.addMember(initializer);
- });
- }
-
- // TODO(karlklose): clear type arguments later, the order of class
- // transformations otherwise influences the result.
- // cls.typeParameters.clear();
- context = null;
- return cls;
- }
-
- // TODO(karlklose): replace with a structure that can answer also the question
- // which tags must be overriden due to different values.
- /// Returns `true` if [a] is a declaration used in a supertype of [b].
- bool isSuperClass(Class a, Class b) {
- if (b == null) return false;
- if (a == b) return true;
-
- if (isSuperClass(a, b.superclass)) {
- return true;
- }
-
- Iterable<Class> interfaceClasses = b.implementedTypes
- .map((Supertype type) => type.classNode)
- .where((Class cls) => cls != rtiLibrary.markerClass);
- return interfaceClasses
- .any((Class declaration) => isSuperClass(a, declaration));
- }
-
- bool isConstructorOrFactory(TreeNode node) {
- return isFactory(node) || node is Constructor;
- }
-
- bool isFactory(TreeNode node) {
- return node is Procedure && node.kind == ProcedureKind.Factory;
- }
-
- bool needsParameterForRuntimeType(TreeNode node) {
- if (!isConstructorOrFactory(node)) return false;
-
- RuntimeTypeStorage access = context.runtimeTypeStorage;
- assert(access != RuntimeTypeStorage.none);
- return access == RuntimeTypeStorage.field ||
- access == RuntimeTypeStorage.inheritedField;
- }
-
- FunctionNode visitFunctionNode(FunctionNode node) {
- trace(node);
-
- addTypeArgumentToGenericDeclaration(node);
-
- // If we have a [TransformationContext] with a runtime type field and we
- // translate a constructor or factory, we need a parameter that the code of
- // initializers or the factory body can use to access type arguments.
- // The parameter field in the context will be reset in the visit-method of
- // the parent.
- if (context != null && needsParameterForRuntimeType(node.parent)) {
- assert(context.parameter == null);
- // Create the parameter and insert it as the function's first parameter.
- context.parameter = new VariableDeclaration(
- rtiLibrary.runtimeTypeName.name,
- type: rtiLibrary.typeType);
- context.parameter.parent = node;
- node.positionalParameters.insert(0, context.parameter);
- node.requiredParameterCount++;
- }
- node.transformChildren(this);
- return node;
- }
-
- SuperInitializer visitSuperInitializer(SuperInitializer initializer) {
- initializer.transformChildren(this);
- return addTypeAsArgument(initializer);
- }
-
- RedirectingInitializer visitRedirectingInitializer(
- RedirectingInitializer initializer) {
- initializer.transformChildren(this);
- return addTypeAsArgument(initializer);
- }
-
- Procedure visitProcedure(Procedure procedure) {
- trace(procedure);
-
- transformList(procedure.annotations, this, procedure.parent);
- // Visit the function body in a initializing context, if it is a factory.
- context?.inInitializer = isFactory(procedure);
- procedure.function?.accept(this);
- context?.inInitializer = false;
-
- context?.parameter = null;
- return procedure;
- }
-
- Constructor visitConstructor(Constructor constructor) {
- trace(constructor);
-
- transformList(constructor.annotations, this, constructor);
- if (constructor.function != null) {
- constructor.function = constructor.function.accept(this);
- constructor.function?.parent = constructor;
- }
-
- context?.inInitializer = true;
- transformList(constructor.initializers, this, constructor);
- context?.inInitializer = false;
-
- if (context != null) {
- if (context.runtimeTypeStorage == RuntimeTypeStorage.field) {
- // Initialize the runtime type field with value given in the additional
- // constructor parameter.
- assert(context.parameter != null);
- Initializer initializer = new FieldInitializer(
- context.runtimeTypeField, new VariableGet(context.parameter));
- initializer.parent = constructor;
- constructor.initializers.insert(0, initializer);
- }
- if (context.initializers != null) {
- // For each field that needed a static initializer function, initialize
- // the field by calling the function.
- List<Initializer> fieldInitializers = <Initializer>[];
- context.initializers.forEach((Field field, Procedure initializer) {
- assert(context.parameter != null);
- Arguments argument =
- new Arguments(<Expression>[new VariableGet(context.parameter)]);
- fieldInitializers.add(new FieldInitializer(
- field, new StaticInvocation(initializer, argument)));
- });
- constructor.initializers.insertAll(0, fieldInitializers);
- }
- context.parameter = null;
- }
-
- return constructor;
- }
-
- /// Returns `true` if the given type can be tested using type test tags.
- ///
- /// This implies that there are no subtypes of the [type] that are not
- /// transformed.
- bool typeSupportsTagTest(InterfaceType type) {
- return needsTypeInformation(type.classNode);
- }
-
- Expression visitIsExpression(IsExpression expression) {
- trace(expression);
-
- expression.transformChildren(this);
-
- if (getEnclosingLibrary(expression) == rtiLibrary.interceptorsLibrary) {
- // In the interceptor library we need actual is-checks at the moment.
- return expression;
- }
-
- Expression target = expression.operand;
- DartType type = expression.type;
-
- if (type is InterfaceType && typeSupportsTagTest(type)) {
- assert(knowledge.classTests.contains(type.classNode));
- bool checkArguments =
- type.typeArguments.any((DartType type) => type is! DynamicType);
- Class declaration = type.classNode;
- VariableDeclaration typeExpression =
- new VariableDeclaration(null, initializer: createRuntimeType(type));
- VariableDeclaration targetValue =
- new VariableDeclaration(null, initializer: target);
- Expression markerClassTest = new IsExpression(
- new VariableGet(targetValue), rtiLibrary.markerClass.rawType);
- Expression tagCheck = new PropertyGet(new VariableGet(targetValue),
- builder.getTypeTestTagName(declaration));
- Expression check = new LogicalExpression(markerClassTest, "&&", tagCheck);
- if (checkArguments) {
- // TODO(karlklose): support a direct argument check, we already checked
- // the declaration.
- Expression uninterceptedCheck = new Let(
- typeExpression,
- builder.createIsSubtypeOf(
- new VariableGet(targetValue), new VariableGet(typeExpression),
- targetHasTypeProperty: true));
- check = new LogicalExpression(check, "&&", uninterceptedCheck);
- }
- return new Let(targetValue, check);
- } else {
- return builder.createIsSubtypeOf(target, createRuntimeType(type));
- }
- }
-
- Expression visitListLiteral(ListLiteral node) {
- trace(node);
- node.transformChildren(this);
- return builder.callAttachType(
- node,
- new InterfaceType(
- builder.coreTypes.listClass, <DartType>[node.typeArgument]));
- }
-
- Expression visitMapLiteral(MapLiteral node) {
- trace(node);
- node.transformChildren(this);
- return builder.callAttachType(
- node,
- new InterfaceType(builder.coreTypes.mapClass,
- <DartType>[node.keyType, node.valueType]));
- }
-
- Expression visitMethodInvocation(MethodInvocation node) {
- node.transformChildren(this);
- addTypeArgumentToGenericInvocation(node);
- return node;
- }
-
- bool isGenericMethod(FunctionNode node) {
- if (node.parent is Member) {
- Member member = node.parent;
- if (member is Constructor ||
- member is Procedure && member.kind == ProcedureKind.Factory) {
- return member.enclosingClass.typeParameters.length <
- node.typeParameters.length;
- }
- }
- return node.typeParameters.isNotEmpty;
- }
-
- void addTypeArgumentToGenericInvocation(InvocationExpression expression) {
- if (expression.arguments.types.length > 0) {
- ListLiteral genericMethodTypeParameters = new ListLiteral(
- expression.arguments.types
- .map(createRuntimeType)
- .toList(growable: false),
- typeArgument: rtiLibrary.typeType);
- expression.arguments.named.add(new NamedExpression(
- genericMethodTypeParametersName, genericMethodTypeParameters)
- ..parent = expression.arguments);
- }
- }
-
- void addTypeArgumentToGenericDeclaration(FunctionNode node) {
- if (isGenericMethod(node)) {
- VariableDeclaration genericMethodTypeParameters = new VariableDeclaration(
- genericMethodTypeParametersName,
- type: new InterfaceType(
- builder.coreTypes.listClass, <DartType>[rtiLibrary.typeType]));
- genericMethodTypeParameters.parent = node;
- node.namedParameters.insert(0, genericMethodTypeParameters);
- }
- }
-}
diff --git a/pkg/kernel/lib/transformations/treeshaker.dart b/pkg/kernel/lib/transformations/treeshaker.dart
index 3fd7046..d615439 100644
--- a/pkg/kernel/lib/transformations/treeshaker.dart
+++ b/pkg/kernel/lib/transformations/treeshaker.dart
@@ -94,6 +94,9 @@
class TreeShaker {
final CoreTypes coreTypes;
final ClosedWorldClassHierarchy hierarchy;
+ final ClassHierarchySubtypes hierarchySubtypes;
+ final Map<Class, int> numberedClasses;
+ final List<Class> classes;
final Component component;
final bool strongMode;
final List<ProgramRoot> programRoots;
@@ -213,7 +216,7 @@
}
ClassRetention getClassRetention(Class classNode) {
- int index = hierarchy.getClassIndex(classNode);
+ int index = numberedClasses[classNode];
return _classRetention[index];
}
@@ -227,11 +230,14 @@
TreeShaker._internal(this.coreTypes, this.hierarchy, this.component,
this.strongMode, this.programRoots)
- : this._dispatchedNames = new List<Set<Name>>(hierarchy.classes.length),
+ : this._dispatchedNames = new List<Set<Name>>(hierarchy.numberOfClasses),
this._usedMembersWithHost =
- new List<Set<Member>>(hierarchy.classes.length),
+ new List<Set<Member>>(hierarchy.numberOfClasses),
this._classRetention = new List<ClassRetention>.filled(
- hierarchy.classes.length, ClassRetention.None) {
+ hierarchy.numberOfClasses, ClassRetention.None),
+ this.hierarchySubtypes = hierarchy.computeSubtypesInformation(),
+ this.numberedClasses = createMapNumberIndex(hierarchy.classes),
+ this.classes = new List<Class>.from(hierarchy.classes) {
_visitor = new _TreeShakerVisitor(this);
_covariantVisitor = new _ExternalTypeVisitor(this, isCovariant: true);
_contravariantVisitor =
@@ -246,6 +252,14 @@
}
}
+ static Map<Class, int> createMapNumberIndex(Iterable<Class> classes) {
+ Map<Class, int> result = new Map<Class, int>();
+ for (Class class_ in classes) {
+ result[class_] = result.length;
+ }
+ return result;
+ }
+
void _build() {
if (component.mainMethod == null) {
throw 'Cannot perform tree shaking on a component without a main method';
@@ -271,8 +285,8 @@
// Mark overridden members in order to preserve abstract members as
// necessary.
if (strongMode) {
- for (int i = hierarchy.classes.length - 1; i >= 0; --i) {
- Class class_ = hierarchy.classes[i];
+ for (int i = classes.length - 1; i >= 0; --i) {
+ Class class_ = classes[i];
if (isHierarchyUsed(class_)) {
hierarchy.forEachOverridePair(class_,
(Member ownMember, Member superMember, bool isSetter) {
@@ -305,7 +319,7 @@
/// Registers the given name as seen in a dynamic dispatch, and discovers used
/// instance members accordingly.
void _addDispatchedName(Class receiver, Name name) {
- int index = hierarchy.getClassIndex(receiver);
+ int index = numberedClasses[receiver];
Set<Name> receiverNames = _dispatchedNames[index] ??= new Set<Name>();
// TODO(asgerf): make use of selector arity and getter/setter kind
if (receiverNames.add(name)) {
@@ -332,7 +346,7 @@
}
}
}
- var subtypes = hierarchy.getSubtypesOf(receiver);
+ var subtypes = hierarchySubtypes.getSubtypesOf(receiver);
var receiverSet = _receiversOfName[name];
_receiversOfName[name] = receiverSet == null
? subtypes
@@ -358,7 +372,7 @@
/// Registers the given class as instantiated and discovers new dispatch
/// target candidates accordingly.
void _addInstantiatedClass(Class classNode) {
- int index = hierarchy.getClassIndex(classNode);
+ int index = numberedClasses[classNode];
ClassRetention retention = _classRetention[index];
if (retention.index < ClassRetention.Instance.index) {
_classRetention[index] = ClassRetention.Instance;
@@ -368,7 +382,7 @@
/// Register that an external subclass of the given class may be instantiated.
void _addInstantiatedExternalSubclass(Class classNode) {
- int index = hierarchy.getClassIndex(classNode);
+ int index = numberedClasses[classNode];
ClassRetention retention = _classRetention[index];
if (retention.index < ClassRetention.ExternalInstance.index) {
_classRetention[index] = ClassRetention.ExternalInstance;
@@ -491,7 +505,7 @@
/// Registers the given class as being used in a type annotation.
void _addClassUsedInType(Class classNode) {
- int index = hierarchy.getClassIndex(classNode);
+ int index = numberedClasses[classNode];
ClassRetention retention = _classRetention[index];
if (retention.index < ClassRetention.Hierarchy.index) {
_classRetention[index] = ClassRetention.Hierarchy;
@@ -516,7 +530,7 @@
void _addStaticNamespace(TreeNode container) {
assert(container is Class || container is Library);
if (container is Class) {
- int index = hierarchy.getClassIndex(container);
+ int index = numberedClasses[container];
var oldRetention = _classRetention[index];
if (oldRetention == ClassRetention.None) {
_classRetention[index] = ClassRetention.Namespace;
@@ -537,7 +551,7 @@
}
if (host != null) {
// Check if the member has been seen with this host before.
- int index = hierarchy.getClassIndex(host);
+ int index = numberedClasses[host];
Set<Member> members = _usedMembersWithHost[index] ??= new Set<Member>();
if (!members.add(member)) return;
_usedMembers.putIfAbsent(member, _makeIncompleteSummary);
diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart
index dd9078b..3678749 100644
--- a/pkg/kernel/lib/vm/constants_native_effects.dart
+++ b/pkg/kernel/lib/vm/constants_native_effects.dart
@@ -65,8 +65,9 @@
constant is IntConstant ? constant.value : null;
int value;
if (defines != null) {
- value = defines.containsKey(name)
- ? int.parse(defines[name], onError: (_) => defaultValue)
+ final String defineValue = defines[name];
+ value = defineValue != null
+ ? (int.tryParse(defineValue) ?? defaultValue)
: defaultValue;
} else {
value = new int.fromEnvironment(name, defaultValue: defaultValue);
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 9e5e4f8..d84856f 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,18 +1,20 @@
name: kernel
-version: 0.3.0-alpha.12
+# Currently, kernel API is not stable and users should
+# not depend on semver semantics when depending on this package.
+version: 0.3.0
author: Dart Team <misc@dartlang.org>
description: Dart IR (Intermediate Representation)
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
environment:
- sdk: ">=1.8.0 <2.0.0"
+ sdk: '>=2.0.0-dev.48.0 <2.0.0'
dependencies:
path: ^1.3.9
args: '>=0.13.4 <2.0.0'
logging: ^0.11.2
package_config: ^1.0.0
dev_dependencies:
- analyzer: '>=0.30.0 <0.32.0'
- front_end: 0.1.0-alpha.12
+ analyzer: '>=0.31.0 <0.33.0'
+ front_end: 0.1.0
test: ^0.12.15+6
stack_trace: ^1.6.6
ansicolor: ^0.0.9
diff --git a/pkg/kernel/test/class_hierarchy_bench.dart b/pkg/kernel/test/class_hierarchy_bench.dart
index 37877d5..cab6148 100644
--- a/pkg/kernel/test/class_hierarchy_bench.dart
+++ b/pkg/kernel/test/class_hierarchy_bench.dart
@@ -60,12 +60,23 @@
hierarchies.add(buildHierarchy());
}
+ List<Class> classes = hierarchies.first.classes.toList();
+
int currentHierarchy = 0;
ClosedWorldClassHierarchy getClassHierarchy() {
currentHierarchy = (currentHierarchy + 1) % hierarchies.length;
return hierarchies[currentHierarchy];
}
+ {
+ var classHierarchy = getClassHierarchy();
+ if (classHierarchy is ClosedWorldClassHierarchy) {
+ for (Class class_ in classes) {
+ classHierarchy.hasProperSubtypes(class_);
+ }
+ }
+ }
+
Random rnd = new Random(12345);
const int numQueryTrials = 100000;
@@ -76,12 +87,11 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int first = rnd.nextInt(classHierarchy.classes.length);
- int second = rnd.nextInt(classHierarchy.classes.length);
- Class firstClass = classHierarchy.classes[first];
- Class secondClass = classHierarchy.classes[second];
+ int first = rnd.nextInt(classes.length);
+ int second = rnd.nextInt(classes.length);
+ Class firstClass = classes[first];
+ Class secondClass = classes[second];
classHierarchy.isSubclassOf(firstClass, secondClass);
- classHierarchy.isSubmixtureOf(firstClass, secondClass);
classHierarchy.isSubtypeOf(firstClass, secondClass);
classHierarchy.getClassAsInstanceOf(firstClass, secondClass);
}
@@ -89,10 +99,10 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int first = rnd.nextInt(classHierarchy.classes.length);
- int second = rnd.nextInt(classHierarchy.classes.length);
- Class firstClass = classHierarchy.classes[first];
- Class secondClass = classHierarchy.classes[second];
+ int first = rnd.nextInt(classes.length);
+ int second = rnd.nextInt(classes.length);
+ Class firstClass = classes[first];
+ Class secondClass = classes[second];
classHierarchy.isSubclassOf(firstClass, secondClass);
}
int subclassQueryTime = watch.elapsedMicroseconds;
@@ -100,21 +110,10 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int first = rnd.nextInt(classHierarchy.classes.length);
- int second = rnd.nextInt(classHierarchy.classes.length);
- Class firstClass = classHierarchy.classes[first];
- Class secondClass = classHierarchy.classes[second];
- classHierarchy.isSubmixtureOf(firstClass, secondClass);
- }
- int submixtureQueryTime = watch.elapsedMicroseconds;
-
- watch.reset();
- for (int i = 0; i < numQueryTrials; i++) {
- var classHierarchy = getClassHierarchy();
- int first = rnd.nextInt(classHierarchy.classes.length);
- int second = rnd.nextInt(classHierarchy.classes.length);
- Class firstClass = classHierarchy.classes[first];
- Class secondClass = classHierarchy.classes[second];
+ int first = rnd.nextInt(classes.length);
+ int second = rnd.nextInt(classes.length);
+ Class firstClass = classes[first];
+ Class secondClass = classes[second];
classHierarchy.isSubtypeOf(firstClass, secondClass);
}
int subtypeQueryTime = watch.elapsedMicroseconds;
@@ -122,10 +121,10 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int first = rnd.nextInt(classHierarchy.classes.length);
- int second = rnd.nextInt(classHierarchy.classes.length);
- Class firstClass = classHierarchy.classes[first];
- Class secondClass = classHierarchy.classes[second];
+ int first = rnd.nextInt(classes.length);
+ int second = rnd.nextInt(classes.length);
+ Class firstClass = classes[first];
+ Class secondClass = classes[second];
classHierarchy.getClassAsInstanceOf(firstClass, secondClass);
}
int asInstanceOfQueryTime = watch.elapsedMicroseconds;
@@ -133,21 +132,18 @@
// Estimate the overhead from test case generation.
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
- var classHierarchy = getClassHierarchy();
- int first = rnd.nextInt(classHierarchy.classes.length);
- int second = rnd.nextInt(classHierarchy.classes.length);
- classHierarchy.classes[first];
- classHierarchy.classes[second];
+ int first = rnd.nextInt(classes.length);
+ int second = rnd.nextInt(classes.length);
+ classes[first];
+ classes[second];
}
int queryNoise = watch.elapsedMicroseconds;
subclassQueryTime -= queryNoise;
- submixtureQueryTime -= queryNoise;
subtypeQueryTime -= queryNoise;
asInstanceOfQueryTime -= queryNoise;
String subclassPerSecond = perSecond(subclassQueryTime, numQueryTrials);
- String submixturePerSecond = perSecond(submixtureQueryTime, numQueryTrials);
String subtypePerSecond = perSecond(subtypeQueryTime, numQueryTrials);
String asInstanceOfPerSecond =
perSecond(asInstanceOfQueryTime, numQueryTrials);
@@ -156,8 +152,8 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int classId = rnd.nextInt(classHierarchy.classes.length);
- Class classNode = classHierarchy.classes[classId];
+ int classId = rnd.nextInt(classes.length);
+ Class classNode = classes[classId];
classHierarchy.getDispatchTarget(classNode, new Name('toString'));
}
int dispatchToStringTime = watch.elapsedMicroseconds;
@@ -165,8 +161,8 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int classId = rnd.nextInt(classHierarchy.classes.length);
- Class classNode = classHierarchy.classes[classId];
+ int classId = rnd.nextInt(classes.length);
+ Class classNode = classes[classId];
classHierarchy.getDispatchTarget(classNode, new Name('getFloo'));
}
int dispatchGenericGetTime = watch.elapsedMicroseconds;
@@ -174,8 +170,8 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int classId = rnd.nextInt(classHierarchy.classes.length);
- Class classNode = classHierarchy.classes[classId];
+ int classId = rnd.nextInt(classes.length);
+ Class classNode = classes[classId];
for (var _ in classHierarchy.getDispatchTargets(classNode)) {}
}
int dispatchAllTargetsTime = watch.elapsedMicroseconds;
@@ -184,8 +180,8 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int classId = rnd.nextInt(classHierarchy.classes.length);
- Class classNode = classHierarchy.classes[classId];
+ int classId = rnd.nextInt(classes.length);
+ Class classNode = classes[classId];
classHierarchy.getInterfaceMember(classNode, new Name('toString'));
}
int interfaceToStringTime = watch.elapsedMicroseconds;
@@ -193,8 +189,8 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int classId = rnd.nextInt(classHierarchy.classes.length);
- Class classNode = classHierarchy.classes[classId];
+ int classId = rnd.nextInt(classes.length);
+ Class classNode = classes[classId];
classHierarchy.getInterfaceMember(classNode, new Name('getFloo'));
}
int interfaceGenericGetTime = watch.elapsedMicroseconds;
@@ -202,8 +198,8 @@
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
var classHierarchy = getClassHierarchy();
- int classId = rnd.nextInt(classHierarchy.classes.length);
- Class classNode = classHierarchy.classes[classId];
+ int classId = rnd.nextInt(classes.length);
+ Class classNode = classes[classId];
for (var _ in classHierarchy.getInterfaceMembers(classNode)) {}
}
int interfaceAllTargetsTime = watch.elapsedMicroseconds;
@@ -211,9 +207,8 @@
// Estimate overhead from test case generation.
watch.reset();
for (int i = 0; i < numQueryTrials; i++) {
- var classHierarchy = getClassHierarchy();
- int classId = rnd.nextInt(classHierarchy.classes.length);
- classHierarchy.classes[classId];
+ int classId = rnd.nextInt(classes.length);
+ classes[classId];
}
int dispatchTargetNoise = watch.elapsedMicroseconds;
@@ -241,7 +236,7 @@
watch.reset();
var classHierarchy = getClassHierarchy();
int numberOfOverridePairs = 0;
- for (var class_ in classHierarchy.classes) {
+ for (var class_ in classes) {
classHierarchy.forEachOverridePair(class_, (member, supermember, isSetter) {
++numberOfOverridePairs;
});
@@ -251,13 +246,18 @@
String overridePairsPerSecond =
perSecond(overrideTime, numberOfOverridePairs);
- List<int> depth = new List(classHierarchy.classes.length);
+ Map<Class, int> classIds = new Map<Class, int>();
+ for (Class class_ in classes) {
+ classIds[class_] = classIds.length;
+ }
+
+ List<int> depth = new List(classes.length);
for (int i = 0; i < depth.length; ++i) {
int parentDepth = 0;
- var classNode = classHierarchy.classes[i];
+ var classNode = classes[i];
for (var supertype in classNode.supers) {
var superclass = supertype.classNode;
- int index = classHierarchy.getClassIndex(superclass);
+ int index = classIds[superclass];
if (!(index < i)) {
throw '${classNode.name}($i) extends ${superclass.name}($index)';
}
@@ -271,7 +271,7 @@
double medianDepth = median(depth);
int totalDepth = sum(depth);
- int numberOfClasses = classHierarchy.classes.length;
+ int numberOfClasses = classes.length;
String expenseHistogram =
classHierarchy.getExpenseHistogram().skip(1).join(' ');
@@ -280,7 +280,6 @@
build.cold: $coldBuildTime ms
build.hot: $hotBuildTime ms
query.isSubclassOf: $subclassPerSecond
-query.isSubmixtureOf: $submixturePerSecond
query.isSubtypeOf: $subtypePerSecond
query.getClassAsInstanceOf: $asInstanceOfPerSecond
query.getDispatchTarget(toString): $dispatchToStringPerSecond
diff --git a/pkg/kernel/test/class_hierarchy_self_check.dart b/pkg/kernel/test/class_hierarchy_self_check.dart
index 486db45..ed26f7b 100644
--- a/pkg/kernel/test/class_hierarchy_self_check.dart
+++ b/pkg/kernel/test/class_hierarchy_self_check.dart
@@ -19,22 +19,17 @@
void testClassHierarchyOnComponent(Component component, {bool verbose: false}) {
BasicClassHierarchy basic = new BasicClassHierarchy(component);
ClosedWorldClassHierarchy classHierarchy = new ClassHierarchy(component);
- int total = classHierarchy.classes.length;
+ int total = classHierarchy.numberOfClasses;
int progress = 0;
for (var class1 in classHierarchy.classes) {
for (var class2 in classHierarchy.classes) {
bool isSubclass = classHierarchy.isSubclassOf(class1, class2);
- bool isSubmixture = classHierarchy.isSubmixtureOf(class1, class2);
bool isSubtype = classHierarchy.isSubtypeOf(class1, class2);
var asInstance = classHierarchy.getClassAsInstanceOf(class1, class2);
if (isSubclass != basic.isSubclassOf(class1, class2)) {
fail('isSubclassOf(${class1.name}, ${class2.name}) returned '
'$isSubclass but should be ${!isSubclass}');
}
- if (isSubmixture != basic.isSubmixtureOf(class1, class2)) {
- fail('isSubmixtureOf(${class1.name}, ${class2.name}) returned '
- '$isSubclass but should be ${!isSubclass}');
- }
if (isSubtype != basic.isSubtypeOf(class1, class2)) {
fail('isSubtypeOf(${class1.name}, ${class2.name}) returned '
'$isSubtype but should be ${!isSubtype}');
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index b9b1dc6..439da52 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -23,9 +23,9 @@
return new ClassHierarchy(component);
}
- void test_applyChanges() {
+ void test_applyTreeChanges() {
var a = addClass(new Class(name: 'A', supertype: objectSuper));
- addClass(new Class(name: 'B', supertype: a.asThisSupertype));
+ var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype));
_assertTestLibraryText('''
class A {}
@@ -33,12 +33,65 @@
''');
// No updated classes, the same hierarchy.
- expect(hierarchy.applyChanges([]), same(hierarchy));
+ expect(hierarchy.applyTreeChanges([], []), same(hierarchy));
+ expect(hierarchy.hasProperSubtypes(a), true);
- // Has updated classes, a new hierarchy.
- var newHierarchy = hierarchy.applyChanges([a]);
- expect(newHierarchy, isNot(same(hierarchy)));
- expect(newHierarchy, new isInstanceOf<ClosedWorldClassHierarchy>());
+ // Has updated classes, still the same hierarchy (instance). Can answer
+ // queries about the new classes.
+ var c = new Class(name: 'C', supertype: a.asThisSupertype);
+ expect(hierarchy.applyTreeChanges([b], [c]), same(hierarchy));
+ expect(hierarchy.isSubclassOf(a, c), false);
+ expect(hierarchy.isSubclassOf(c, a), true);
+ expect(hierarchy.hasProperSubtypes(a), true);
+
+ // Remove so A should no longer be a super of anything.
+ expect(hierarchy.applyTreeChanges([c], []), same(hierarchy));
+ expect(hierarchy.hasProperSubtypes(a), false);
+ }
+
+ void test_applyMemberChanges() {
+ var methodA1 = newEmptyMethod('memberA1');
+ var methodA2 = newEmptyMethod('memberA2');
+ var methodA3 = newEmptyMethod('memberA3');
+ var methodB1 = newEmptyMethod('memberB1');
+
+ var a = addClass(new Class(
+ name: 'A', supertype: objectSuper, procedures: [methodA1, methodA2]));
+ var b = addClass(new Class(
+ name: 'B', supertype: a.asThisSupertype, procedures: [methodB1]));
+
+ _assertTestLibraryText('''
+class A {
+ method memberA1() → void {}
+ method memberA2() → void {}
+}
+class B extends self::A {
+ method memberB1() → void {}
+}
+''');
+
+ // No changes: B has memberA1, memberA2 and memberB1;
+ // A has memberA1 and memberA2
+ expect(hierarchy.getDispatchTargets(b),
+ unorderedEquals([methodA1, methodA2, methodB1]));
+ expect(
+ hierarchy.getDispatchTargets(a), unorderedEquals([methodA1, methodA2]));
+
+ // Add a member to A, but only update A.
+ a.addMember(methodA3);
+ hierarchy.applyMemberChanges([a]);
+ expect(hierarchy.getDispatchTargets(b),
+ unorderedEquals([methodA1, methodA2, methodB1]));
+ expect(hierarchy.getDispatchTargets(a),
+ unorderedEquals([methodA1, methodA2, methodA3]));
+
+ // Apply member changes again, this time telling the hierarchy to find
+ // decendants.
+ hierarchy.applyMemberChanges([a], findDescendants: true);
+ expect(hierarchy.getDispatchTargets(b),
+ unorderedEquals([methodA1, methodA2, methodA3, methodB1]));
+ expect(hierarchy.getDispatchTargets(a),
+ unorderedEquals([methodA1, methodA2, methodA3]));
}
void test_getSingleTargetForInterfaceInvocation() {
@@ -84,12 +137,13 @@
''');
ClosedWorldClassHierarchy cwch = hierarchy as ClosedWorldClassHierarchy;
+ ClassHierarchySubtypes cwchst = cwch.computeSubtypesInformation();
- expect(cwch.getSingleTargetForInterfaceInvocation(methodInA), methodInB);
- expect(cwch.getSingleTargetForInterfaceInvocation(methodInB),
+ expect(cwchst.getSingleTargetForInterfaceInvocation(methodInA), methodInB);
+ expect(cwchst.getSingleTargetForInterfaceInvocation(methodInB),
null); // B::foo and D::foo
- expect(cwch.getSingleTargetForInterfaceInvocation(methodInD), methodInD);
- expect(cwch.getSingleTargetForInterfaceInvocation(methodInE),
+ expect(cwchst.getSingleTargetForInterfaceInvocation(methodInD), methodInD);
+ expect(cwchst.getSingleTargetForInterfaceInvocation(methodInE),
null); // no concrete subtypes
}
@@ -129,15 +183,16 @@
''');
ClosedWorldClassHierarchy cwch = hierarchy as ClosedWorldClassHierarchy;
+ ClassHierarchySubtypes cwchst = cwch.computeSubtypesInformation();
- expect(cwch.getSubtypesOf(a), unorderedEquals([a, d, f, h]));
- expect(cwch.getSubtypesOf(b), unorderedEquals([b, e, f]));
- expect(cwch.getSubtypesOf(c), unorderedEquals([c, e, f, h]));
- expect(cwch.getSubtypesOf(d), unorderedEquals([d]));
- expect(cwch.getSubtypesOf(e), unorderedEquals([e, f]));
- expect(cwch.getSubtypesOf(f), unorderedEquals([f]));
- expect(cwch.getSubtypesOf(g), unorderedEquals([g, h]));
- expect(cwch.getSubtypesOf(h), unorderedEquals([h]));
+ expect(cwchst.getSubtypesOf(a), unorderedEquals([a, d, f, h]));
+ expect(cwchst.getSubtypesOf(b), unorderedEquals([b, e, f]));
+ expect(cwchst.getSubtypesOf(c), unorderedEquals([c, e, f, h]));
+ expect(cwchst.getSubtypesOf(d), unorderedEquals([d]));
+ expect(cwchst.getSubtypesOf(e), unorderedEquals([e, f]));
+ expect(cwchst.getSubtypesOf(f), unorderedEquals([f]));
+ expect(cwchst.getSubtypesOf(g), unorderedEquals([g, h]));
+ expect(cwchst.getSubtypesOf(h), unorderedEquals([h]));
}
}
@@ -583,33 +638,6 @@
expect(hierarchy.getClassAsInstanceOf(z, a), null);
}
- void test_getClassDepth() {
- var base = addClass(new Class(name: 'base', supertype: objectSuper));
- var extends_ =
- addClass(new Class(name: 'extends_', supertype: base.asThisSupertype));
- var with_ = addClass(new Class(
- name: 'with_',
- supertype: objectSuper,
- mixedInType: base.asThisSupertype));
- var implements_ = addClass(new Class(
- name: 'implements_',
- supertype: objectSuper,
- implementedTypes: [base.asThisSupertype]));
-
- _assertTestLibraryText('''
-class base {}
-class extends_ extends self::base {}
-class with_ = core::Object with self::base {}
-class implements_ implements self::base {}
-''');
-
- expect(hierarchy.getClassDepth(objectClass), 0);
- expect(hierarchy.getClassDepth(base), 1);
- expect(hierarchy.getClassDepth(extends_), 2);
- expect(hierarchy.getClassDepth(with_), 2);
- expect(hierarchy.getClassDepth(implements_), 2);
- }
-
/// Copy of the tests/language/least_upper_bound_expansive_test.dart test.
void test_getClassicLeastUpperBound_expansive() {
var int = coreTypes.intClass.rawType;
@@ -1291,32 +1319,6 @@
assertOrderOfClasses([c, b], [b, c]);
}
- void test_getRankedSuperclasses() {
- var a = addImplementsClass('A', []);
- var b = addImplementsClass('B', [a]);
- var c = addImplementsClass('C', [a]);
- var d = addImplementsClass('D', [c]);
- var e = addImplementsClass('E', [b, d]);
-
- _assertTestLibraryText('''
-class A {}
-class B implements self::A {}
-class C implements self::A {}
-class D implements self::C {}
-class E implements self::B, self::D {}
-''');
-
- expect(hierarchy.getRankedSuperclasses(a), [a, objectClass]);
- expect(hierarchy.getRankedSuperclasses(b), [b, a, objectClass]);
- expect(hierarchy.getRankedSuperclasses(c), [c, a, objectClass]);
- expect(hierarchy.getRankedSuperclasses(d), [d, c, a, objectClass]);
- if (hierarchy.getClassIndex(b) < hierarchy.getClassIndex(c)) {
- expect(hierarchy.getRankedSuperclasses(e), [e, d, b, c, a, objectClass]);
- } else {
- expect(hierarchy.getRankedSuperclasses(e), [e, d, c, b, a, objectClass]);
- }
- }
-
void test_getTypeAsInstanceOf_generic_extends() {
var int = coreTypes.intClass.rawType;
var bool = coreTypes.boolClass.rawType;
diff --git a/pkg/kernel/test/closures/closures.status b/pkg/kernel/test/closures/closures.status
deleted file mode 100644
index 53fe05a..0000000
--- a/pkg/kernel/test/closures/closures.status
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE.md file.
diff --git a/pkg/kernel/test/closures/suite.dart b/pkg/kernel/test/closures/suite.dart
deleted file mode 100644
index a993f2e..0000000
--- a/pkg/kernel/test/closures/suite.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.closures.suite;
-
-import 'dart:io' show File, Platform;
-
-import 'dart:async' show Future;
-
-import 'package:kernel/core_types.dart' show CoreTypes;
-
-import 'package:testing/testing.dart'
- show Chain, ChainContext, Result, Step, runMe, StdioProcess;
-
-import 'package:kernel/ast.dart' show Component, Library;
-
-import 'package:kernel/target/targets.dart' show Target;
-
-import 'package:front_end/src/fasta/testing/kernel_chain.dart'
- show
- Print,
- MatchExpectation,
- WriteDill,
- ReadDill,
- Verify,
- Compile,
- CompileContext;
-
-import 'package:kernel/transformations/closure_conversion.dart'
- as closure_conversion;
-
-const String STRONG_MODE = " strong mode ";
-
-class ClosureConversionContext extends ChainContext implements CompileContext {
- final bool strongMode;
- Target get target => null;
-
- final List<Step> steps;
-
- Component platform;
-
- ClosureConversionContext(this.strongMode, bool updateExpectations)
- : steps = <Step>[
- const Compile(),
- const Print(),
- const Verify(true),
- const ClosureConversion(),
- const Print(),
- const Verify(true),
- new MatchExpectation(".expect",
- updateExpectations: updateExpectations),
- const WriteDill(),
- const ReadDill(),
- const Run(),
- ];
-
- static Future<ClosureConversionContext> create(
- Chain suite, Map<String, String> environment, bool strongMode) async {
- bool updateExpectations = environment["updateExpectations"] == "true";
- return new ClosureConversionContext(strongMode, updateExpectations);
- }
-}
-
-Future<ClosureConversionContext> createContext(
- Chain suite, Map<String, String> environment) async {
- bool strongMode = environment.containsKey(STRONG_MODE);
- environment["updateExpectations"] =
- const String.fromEnvironment("updateExpectations");
- return ClosureConversionContext.create(suite, environment, strongMode);
-}
-
-class ClosureConversion
- extends Step<Component, Component, ClosureConversionContext> {
- const ClosureConversion();
-
- String get name => "closure conversion";
-
- Future<Result<Component>> run(
- Component component, ClosureConversionContext testContext) async {
- try {
- CoreTypes coreTypes = new CoreTypes(component);
- Library library = component.libraries
- .firstWhere((Library library) => library.importUri.scheme != "dart");
- closure_conversion.transformLibraries(coreTypes, <Library>[library]);
- return pass(component);
- } catch (e, s) {
- return crash(e, s);
- }
- }
-}
-
-class Run extends Step<Uri, int, ClosureConversionContext> {
- const Run();
-
- String get name => "run";
-
- Future<Result<int>> run(Uri uri, ClosureConversionContext context) async {
- final File generated = new File.fromUri(uri);
- try {
- Uri vm = Uri.base.resolveUri(new Uri.file(Platform.resolvedExecutable));
- final StdioProcess process = await StdioProcess.run(vm.toFilePath(), [
- "--reify",
- "--reify_generic_functions",
- "-c",
- generated.path,
- "Hello, World!"
- ]);
- print(process.output);
- return process.toResult();
- } finally {
- generated.parent.delete(recursive: true);
- }
- }
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/closures/testing.json b/pkg/kernel/test/closures/testing.json
deleted file mode 100644
index 1351cd2..0000000
--- a/pkg/kernel/test/closures/testing.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-"":"Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file",
-"":"for details. All rights reserved. Use of this source code is governed by a",
-"":"BSD-style license that can be found in the LICENSE.md file.",
- "packages": "../../../../.packages",
- "suites": [
- {
- "name": "closures",
- "kind": "Chain",
- "source": "suite.dart",
- "path": "../../testcases/closures/",
- "status": "closures.status",
- "pattern": [
- "\\.dart$"
- ],
- "exclude": [
- "/test/closures/suite\\.dart$"
- ]
- }
- ],
- "analyze": {
- "uris": [
- "suite.dart"
- ],
- "exclude": [
- ]
- }
-}
diff --git a/pkg/kernel/test/closures_initializers/closures_initializers.status b/pkg/kernel/test/closures_initializers/closures_initializers.status
deleted file mode 100644
index 3642988..0000000
--- a/pkg/kernel/test/closures_initializers/closures_initializers.status
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE.md file.
diff --git a/pkg/kernel/test/closures_initializers/suite.dart b/pkg/kernel/test/closures_initializers/suite.dart
deleted file mode 100644
index d7176d4..0000000
--- a/pkg/kernel/test/closures_initializers/suite.dart
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.closures.suite;
-
-import 'dart:async' show Future;
-
-import 'package:kernel/core_types.dart' show CoreTypes;
-
-import 'package:testing/testing.dart'
- show Chain, ChainContext, Result, Step, runMe;
-
-import 'package:kernel/ast.dart' show Component, Library;
-
-import 'package:kernel/transformations/argument_extraction.dart'
- as argument_extraction;
-
-import 'package:kernel/target/targets.dart' show Target;
-
-import 'package:kernel/transformations/closure_conversion.dart'
- as closure_conversion;
-
-import 'package:front_end/src/fasta/testing/kernel_chain.dart'
- show
- Compile,
- CompileContext,
- Print,
- MatchExpectation,
- WriteDill,
- ReadDill,
- Verify;
-
-const String STRONG_MODE = " strong mode ";
-
-class ClosureConversionContext extends ChainContext implements CompileContext {
- final bool strongMode;
-
- Target get target => null;
-
- final List<Step> steps;
-
- ClosureConversionContext(this.strongMode, bool updateExpectations)
- : steps = <Step>[
- const Compile(),
- const Print(),
- const Verify(true),
- const ArgumentExtraction(),
- const Print(),
- const Verify(true),
- const ClosureConversion(),
- const Print(),
- const Verify(true),
- new MatchExpectation(".expect",
- updateExpectations: updateExpectations),
- const WriteDill(),
- const ReadDill(),
- // TODO(29143): add `Run` step when Vectors are added to VM.
- ];
-
- static Future<ClosureConversionContext> create(
- Chain suite, Map<String, String> environment) async {
- bool strongMode = environment.containsKey(STRONG_MODE);
- bool updateExpectations = environment["updateExpectations"] == "true";
- return new ClosureConversionContext(strongMode, updateExpectations);
- }
-}
-
-Future<ClosureConversionContext> createContext(
- Chain suite, Map<String, String> environment) async {
- environment["updateExpectations"] =
- const String.fromEnvironment("updateExpectations");
- return ClosureConversionContext.create(suite, environment);
-}
-
-class ArgumentExtraction
- extends Step<Component, Component, ClosureConversionContext> {
- const ArgumentExtraction();
-
- String get name => "argument extraction";
-
- Future<Result<Component>> run(
- Component component, ClosureConversionContext context) async {
- try {
- CoreTypes coreTypes = new CoreTypes(component);
- Library library = component.libraries
- .firstWhere((Library library) => library.importUri.scheme != "dart");
- argument_extraction.transformLibraries(coreTypes, <Library>[library]);
- return pass(component);
- } catch (e, s) {
- return crash(e, s);
- }
- }
-}
-
-class ClosureConversion
- extends Step<Component, Component, ClosureConversionContext> {
- const ClosureConversion();
-
- String get name => "closure conversion";
-
- Future<Result<Component>> run(
- Component component, ClosureConversionContext testContext) async {
- try {
- CoreTypes coreTypes = new CoreTypes(component);
- Library library = component.libraries
- .firstWhere((Library library) => library.importUri.scheme != "dart");
- closure_conversion.transformLibraries(coreTypes, <Library>[library]);
- return pass(component);
- } catch (e, s) {
- return crash(e, s);
- }
- }
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/closures_initializers/testing.json b/pkg/kernel/test/closures_initializers/testing.json
deleted file mode 100644
index d098a2c..0000000
--- a/pkg/kernel/test/closures_initializers/testing.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "":"Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file",
- "":"for details. All rights reserved. Use of this source code is governed by a",
- "":"BSD-style license that can be found in the LICENSE.md file.",
- "packages": "../../../../.packages",
- "suites": [
- {
- "name": "closures_initializers",
- "kind": "Chain",
- "source": "suite.dart",
- "path": "../../testcases/closures_initializers/",
- "status": "closures_initializers.status",
- "pattern": [
- "\\.dart$"
- ],
- "exclude": [
- "/test/closures_initializers/suite\\.dart$"
- ]
- }
- ],
- "analyze": {
- "uris": [
- "suite.dart"
- ],
- "exclude": [
- ]
- }
-}
diff --git a/pkg/kernel/test/closures_test.dart b/pkg/kernel/test/closures_test.dart
deleted file mode 100644
index bb0d3e2..0000000
--- a/pkg/kernel/test/closures_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.closures_test;
-
-import 'package:test/test.dart' show Timeout, test;
-
-import 'package:testing/testing.dart' show run;
-
-main() {
- test("closures",
- () => run([], ["closures"], "pkg/kernel/test/closures/testing.json"),
- timeout: new Timeout(new Duration(minutes: 5)));
-}
diff --git a/pkg/kernel/test/closures_type_vars/closures_type_vars.status b/pkg/kernel/test/closures_type_vars/closures_type_vars.status
deleted file mode 100644
index 3642988..0000000
--- a/pkg/kernel/test/closures_type_vars/closures_type_vars.status
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE.md file.
diff --git a/pkg/kernel/test/closures_type_vars/suite.dart b/pkg/kernel/test/closures_type_vars/suite.dart
deleted file mode 100644
index 866bf2c..0000000
--- a/pkg/kernel/test/closures_type_vars/suite.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.closures_type_vars.suite;
-
-import 'dart:async' show Future;
-import 'package:testing/testing.dart' show Chain, runMe;
-import '../closures/suite.dart' show ClosureConversionContext;
-
-Future<ClosureConversionContext> createContext(
- Chain suite, Map<String, String> environment) async {
- environment["updateExpectations"] =
- const String.fromEnvironment("updateExpectations");
- return ClosureConversionContext.create(
- suite, environment, true /*strongMode*/);
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/closures_type_vars/testing.json b/pkg/kernel/test/closures_type_vars/testing.json
deleted file mode 100644
index f072315..0000000
--- a/pkg/kernel/test/closures_type_vars/testing.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-"":"Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file",
-"":"for details. All rights reserved. Use of this source code is governed by a",
-"":"BSD-style license that can be found in the LICENSE.md file.",
- "packages": "../../../../.packages",
- "suites": [
- {
- "name": "closures_type_vars",
- "kind": "Chain",
- "source": "suite.dart",
- "path": "../../testcases/closures_type_vars/",
- "status": "closures_type_vars.status",
- "pattern": [
- "\\.dart$"
- ],
- "exclude": [
- "/test/closures_type_vars/suite\\.dart$"
- ]
- }
- ],
- "analyze": {
- "uris": [
- "suite.dart"
- ],
- "exclude": [
- ]
- }
-}
diff --git a/pkg/kernel/test/metadata_test.dart b/pkg/kernel/test/metadata_test.dart
index 1fb9777..4607413 100644
--- a/pkg/kernel/test/metadata_test.dart
+++ b/pkg/kernel/test/metadata_test.dart
@@ -14,16 +14,40 @@
show computePlatformBinariesLocation;
/// Test metadata: to each node we attach a metadata that contains
-/// a reference to this node's parent and this node formatted as string.
+/// * node formatted as string
+/// * reference to its enclosing member
+/// * type representing the first type parameter of its enclosing function
class Metadata {
- final TreeNode parent;
- final String self;
+ final String string;
+ final Reference _memberRef;
+ final DartType type;
+
+ Member get member => _memberRef?.asMember;
Metadata.forNode(TreeNode n)
- : parent = MetadataRepository.isSupported(n.parent) ? n.parent : null,
- self = n.toString();
+ : this(n.toString(), getMemberReference(getMemberForMetadata(n)),
+ getTypeForMetadata(n));
- Metadata(this.parent, this.self);
+ Metadata(this.string, this._memberRef, this.type);
+}
+
+Member getMemberForMetadata(TreeNode node) {
+ final parent = node.parent;
+ if (parent == null) return null;
+ if (parent is Member) return parent;
+ return getMemberForMetadata(parent);
+}
+
+DartType getTypeForMetadata(TreeNode node) {
+ final parent = node.parent;
+ if (parent == null) return const VoidType();
+ if (parent is FunctionNode) {
+ if (parent.typeParameters.isEmpty) {
+ return const VoidType();
+ }
+ return new TypeParameterType(parent.typeParameters[0]);
+ }
+ return getTypeForMetadata(parent);
}
class TestMetadataRepository extends MetadataRepository<Metadata> {
@@ -33,15 +57,21 @@
final Map<TreeNode, Metadata> mapping = <TreeNode, Metadata>{};
- void writeToBinary(Metadata metadata, BinarySink sink) {
- sink.writeNodeReference(metadata.parent);
- sink.writeByteList(utf8.encode(metadata.self));
+ void writeToBinary(Metadata metadata, Node node, BinarySink sink) {
+ expect(metadata, equals(mapping[node]));
+ sink.writeByteList(utf8.encode(metadata.string));
+ sink.writeStringReference(metadata.string);
+ sink.writeCanonicalNameReference(metadata.member?.canonicalName);
+ sink.writeDartType(metadata.type);
}
- Metadata readFromBinary(BinarySource source) {
- final parent = source.readNodeReference();
- final string = utf8.decode(source.readByteList());
- return new Metadata(parent, string);
+ Metadata readFromBinary(Node node, BinarySource source) {
+ final string1 = utf8.decode(source.readByteList());
+ final string2 = source.readStringReference();
+ final memberRef = source.readCanonicalNameReference()?.reference;
+ final type = source.readDartType();
+ expect(string1, equals(string2));
+ return new Metadata(string2, memberRef, type);
}
}
@@ -92,8 +122,9 @@
final m = repository.mapping[node];
final expected = new Metadata.forNode(node);
- expect(m.parent, equals(expected.parent));
- expect(m.self, equals(expected.self));
+ expect(m.string, equals(expected.string));
+ expect(m.member, equals(expected.member));
+ expect(m.type, equals(expected.type));
}
}
diff --git a/pkg/kernel/test/reify/reify.status b/pkg/kernel/test/reify/reify.status
deleted file mode 100644
index f4eda9b..0000000
--- a/pkg/kernel/test/reify/reify.status
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE.md file.
-
-/generic_methods_unused_parameter_test: Crash
-/generic_methods_closure_test: Crash
-/generic_methods_generic_class_tearoff_test: Crash
-/generic_methods_local_variable_declaration_test: Crash
-/generic_methods_named_parameters_test: Crash
-/generic_methods_optional_parameters_test: Crash
-/generic_methods_recursive_bound_error_test: Crash
-/generic_methods_recursive_bound_test: Crash
-/generic_methods_reuse_type_variables_test: Crash
-/generic_methods_shadowing_test: Crash
-/generic_methods_simple_is_expression_test: Crash
-/generic_methods_tearoff_specialization_test: Crash
-/generic_methods_bounds_test: Fail
-/generic_methods_dynamic_dependent_type_error_test: Fail
-/generic_methods_dynamic_simple_error_test: Fail
-/generic_methods_dynamic_test: Fail
-/generic_methods_simple_as_expression_error_test: Fail
diff --git a/pkg/kernel/test/reify/suite.dart b/pkg/kernel/test/reify/suite.dart
deleted file mode 100644
index 768fbdc..0000000
--- a/pkg/kernel/test/reify/suite.dart
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.reify.suite;
-
-import 'dart:async' show Future;
-
-import 'dart:io' show Platform, File;
-
-import 'package:kernel/core_types.dart' show CoreTypes;
-
-import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
-
-import 'package:kernel/target/vmcc.dart' show VmClosureConvertedTarget;
-
-import 'package:front_end/src/compute_platform_binaries_location.dart'
- show computePlatformBinariesLocation;
-
-import 'package:front_end/src/fasta/testing/kernel_chain.dart'
- show
- Compile,
- CompileContext,
- MatchExpectation,
- Print,
- ReadDill,
- Verify,
- WriteDill;
-
-import 'package:testing/testing.dart'
- show Chain, ChainContext, Result, StdioProcess, Step, runMe;
-
-import 'package:kernel/ast.dart' show Component;
-
-import 'package:kernel/transformations/generic_types_reification.dart'
- as generic_types_reification;
-
-class TestContext extends ChainContext implements CompileContext {
- final Uri vm;
- final Uri platformUri;
- final Uri platformBinaries;
-
- @override
- final Target target = new NotReifiedTarget(new TargetFlags(
- strongMode: true,
- kernelRuntime: Platform.script.resolve("../../runtime/")));
-
- // Strong mode is required to keep the type arguments in invocations of
- // generic methods.
- @override
- bool get strongMode => true;
-
- final List<Step> steps;
-
- TestContext(
- this.vm, this.platformUri, this.platformBinaries, bool updateExpectations)
- : steps = <Step>[
- const Compile(),
- const Print(),
- const Verify(true),
- const GenericTypesReification(),
- const Print(),
- const Verify(true),
- new MatchExpectation(".expect",
- updateExpectations: updateExpectations),
- const WriteDill(),
- const ReadDill(),
- const Run(),
- ];
-}
-
-enum Environment {
- directory,
- file,
-}
-
-Future<TestContext> createContext(
- Chain suite, Map<String, String> environment) async {
- Uri vm = Uri.base.resolveUri(new Uri.file(Platform.resolvedExecutable));
- Uri platformBinaries = computePlatformBinariesLocation();
- Uri platform = platformBinaries.resolve("vm_platform.dill");
- bool updateExpectations = environment["updateExpectations"] == "true";
- return new TestContext(vm, platform, platformBinaries, updateExpectations);
-}
-
-// [NotReifiedTarget] is intended to work as the [Target] class that
-// [VmGenericTypesReifiedTarget] inherits from, but with some transformations
-// disabled. Those include tree shaking and generic types information erasure
-// passes.
-// [NotReifiedTarget] also adds the necessary runtime libraries.
-class NotReifiedTarget extends VmClosureConvertedTarget {
- NotReifiedTarget(TargetFlags flags) : super(flags);
-
- @override
- String get name => "not reified target";
-
- // Tree shaking needs to be disabled, because Generic Types Reification
- // transformation relies on certain runtime libraries to be present in
- // the component that is being transformed. If the tree shaker is enabled,
- // it just deletes everything from those libraries, because they aren't
- // used in the component being transformed prior to the transformation.
- @override
- void performTreeShaking(CoreTypes coreTypes, Component component) {}
-
- // Adds the necessary runtime libraries.
- @override
- List<String> get extraRequiredLibraries {
- Target reifyTarget = getTarget("vmreify", this.flags);
- var x = reifyTarget.extraRequiredLibraries;
- return x;
- }
-}
-
-class GenericTypesReification extends Step<Component, Component, TestContext> {
- const GenericTypesReification();
-
- String get name => "generic types reification";
-
- Future<Result<Component>> run(
- Component component, TestContext testContext) async {
- try {
- CoreTypes coreTypes = new CoreTypes(component);
- component =
- generic_types_reification.transformComponent(coreTypes, component);
- return pass(component);
- } catch (e, s) {
- return crash(e, s);
- }
- }
-}
-
-class Run extends Step<Uri, int, TestContext> {
- const Run();
-
- String get name => "run";
-
- bool get isAsync => true;
-
- bool get isRuntime => true;
-
- Future<Result<int>> run(Uri uri, TestContext context) async {
- File generated = new File.fromUri(uri);
- StdioProcess process;
- try {
- var args = [generated.path];
- process = await StdioProcess.run(context.vm.toFilePath(), args);
- print(process.output);
- } finally {
- generated.parent.delete(recursive: true);
- }
- return process.toResult();
- }
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/reify/testing.json b/pkg/kernel/test/reify/testing.json
deleted file mode 100644
index 7b9fcaa..0000000
--- a/pkg/kernel/test/reify/testing.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-"":"Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file",
-"":"for details. All rights reserved. Use of this source code is governed by a",
-"":"BSD-style license that can be found in the LICENSE.md file.",
- "packages": "../../../../.packages",
- "suites": [
- {
- "name": "reify",
- "kind": "Chain",
- "source": "suite.dart",
- "path": "../../testcases/reify",
- "status": "reify.status",
- "pattern": [
- "\\.dart$"
- ],
- "exclude": [
- "/test/reify/suite\\.dart$",
- "/testcases/reify/test_base\\.dart$"
- ]
- }
- ],
- "analyze": {
- "uris": [
- "suite.dart"
- ],
- "exclude": [
- ]
- }
-}
diff --git a/pkg/kernel/testcases/closures/README.md b/pkg/kernel/testcases/closures/README.md
deleted file mode 100644
index 290864f..0000000
--- a/pkg/kernel/testcases/closures/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-<!--
-Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-for details. All rights reserved. Use of this source code is governed by a
-BSD-style license that can be found in the LICENSE file.
--->
-# Running tests
-
- export DART_AOT_SDK=.../xcodebuild/DerivedSources/DebugX64/patched_sdk
- dart -c --packages=.packages package:testing/src/run_tests.dart test/closures/testing.json
diff --git a/pkg/kernel/testcases/closures/arity.dart b/pkg/kernel/testcases/closures/arity.dart
deleted file mode 100644
index e4285d5..0000000
--- a/pkg/kernel/testcases/closures/arity.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// Test that closures check their argument count.
-//
-main() {
- var closures = [
- (x, y, [z]) {},
- (x, y, z) {},
- (x, y, {z}) {},
- (x, y, z, w, v) {}
- ];
- for (var c in closures) {
- bool ok = false;
- try {
- c(1, 2, 3, 4);
- } on NoSuchMethodError catch (_) {
- ok = true;
- }
- if (!ok) {
- throw new Exception("Expected an error!");
- }
- }
-
- (x, y, [z]) {}(1, 2);
- (x, y, [z]) {}(1, 2, 3);
-}
diff --git a/pkg/kernel/testcases/closures/arity.dart.expect b/pkg/kernel/testcases/closures/arity.dart.expect
deleted file mode 100644
index bc1353f..0000000
--- a/pkg/kernel/testcases/closures/arity.dart.expect
+++ /dev/null
@@ -1,27 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main() → dynamic {
- dynamic closures = <dynamic>[MakeClosure<(dynamic, dynamic, [dynamic]) → dynamic>(self::closure#main#function, null), MakeClosure<(dynamic, dynamic, dynamic) → dynamic>(self::closure#main#function#1, null), MakeClosure<(dynamic, dynamic, {z: dynamic}) → dynamic>(self::closure#main#function#2, null), MakeClosure<(dynamic, dynamic, dynamic, dynamic, dynamic) → dynamic>(self::closure#main#function#3, null)];
- for (dynamic c in closures) {
- core::bool ok = false;
- try {
- c.call(1, 2, 3, 4);
- }
- on core::NoSuchMethodError catch(final core::NoSuchMethodError _) {
- ok = true;
- }
- if(!ok) {
- throw core::Exception::•("Expected an error!");
- }
- }
- (MakeClosure<(dynamic, dynamic, [dynamic]) → dynamic>(self::closure#main#function#4, null)).call(1, 2);
- (MakeClosure<(dynamic, dynamic, [dynamic]) → dynamic>(self::closure#main#function#5, null)).call(1, 2, 3);
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x, dynamic y, [dynamic z]) → dynamic {}
-static method closure#main#function#1(dynamic #contextParameter, dynamic x, dynamic y, dynamic z) → dynamic {}
-static method closure#main#function#2(dynamic #contextParameter, dynamic x, dynamic y, {dynamic z}) → dynamic {}
-static method closure#main#function#3(dynamic #contextParameter, dynamic x, dynamic y, dynamic z, dynamic w, dynamic v) → dynamic {}
-static method closure#main#function#4(dynamic #contextParameter, dynamic x, dynamic y, [dynamic z]) → dynamic {}
-static method closure#main#function#5(dynamic #contextParameter, dynamic x, dynamic y, [dynamic z]) → dynamic {}
diff --git a/pkg/kernel/testcases/closures/blocks.dart b/pkg/kernel/testcases/closures/blocks.dart
deleted file mode 100644
index 82e7fe6..0000000
--- a/pkg/kernel/testcases/closures/blocks.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// This test checks that we don't create duplicate local contexts in the same
-// function. It's modeled after the 'startIsolateMock' function which was broken
-// in the standard library.
-class X {}
-
-typedef dynamic fn(dynamic x);
-typedef dynamic fn2(dynamic x, dynamic y);
-
-void startIsolateMock(
- dynamic parentPort,
- dynamic entryPoint,
- dynamic args,
- dynamic message,
- dynamic isSpawnUri,
- dynamic controlPort,
- List<dynamic> capabilities) {
- if (controlPort != null) {
- controlPort.handler = (dynamic _) {};
- }
- if (parentPort != null) {
- dynamic readyMessage = new List<dynamic>(2);
- readyMessage[0] = controlPort.sendPort;
- readyMessage[1] = capabilities;
- capabilities = null;
- parentPort.send(readyMessage);
- }
- assert(capabilities == null);
- dynamic port = "abc";
- port.handler = (dynamic _) {
- port.close();
- if (isSpawnUri) {
- if (entryPoint is fn2) {
- entryPoint.call(args, message);
- } else if (entryPoint is fn) {
- entryPoint.call(args);
- } else {
- entryPoint.call();
- }
- } else {
- entryPoint.call(message);
- }
- };
- port.sendPort.send(null);
-}
-
-main() {
- // No code here -- we just check that duplicate contexts aren't created above.
-}
diff --git a/pkg/kernel/testcases/closures/blocks.dart.expect b/pkg/kernel/testcases/closures/blocks.dart.expect
deleted file mode 100644
index 89fec93..0000000
--- a/pkg/kernel/testcases/closures/blocks.dart.expect
+++ /dev/null
@@ -1,56 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-typedef fn = (dynamic) → dynamic;
-typedef fn2 = (dynamic, dynamic) → dynamic;
-class X extends core::Object {
- synthetic constructor •() → void
- : super core::Object::•()
- ;
-}
-static method startIsolateMock(dynamic parentPort, dynamic entryPoint, dynamic args, dynamic message, dynamic isSpawnUri, dynamic controlPort, core::List<dynamic> capabilities) → void {
- final dynamic #context = MakeVector(7);
- #context[2] = entryPoint;
- entryPoint = null;
- #context[3] = args;
- args = null;
- #context[4] = message;
- message = null;
- #context[5] = isSpawnUri;
- isSpawnUri = null;
- if(!controlPort.==(null)) {
- controlPort.handler = MakeClosure<(dynamic) → dynamic>(self::closure#startIsolateMock#function, #context);
- }
- if(!parentPort.==(null)) {
- dynamic readyMessage = core::List::_internal<dynamic>(2);
- readyMessage.[]=(0, controlPort.sendPort);
- readyMessage.[]=(1, capabilities);
- capabilities = null;
- parentPort.send(readyMessage);
- }
- assert(capabilities.==(null));
- #context[6] = "abc";
- (#context[6]).handler = MakeClosure<(dynamic) → dynamic>(self::closure#startIsolateMock#function#1, #context);
- (#context[6]).sendPort.send(null);
-}
-static method main() → dynamic {}
-static method closure#startIsolateMock#function(dynamic #contextParameter, dynamic _) → dynamic {}
-static method closure#startIsolateMock#function#1(dynamic #contextParameter, dynamic _) → dynamic {
- (#contextParameter[6]).close();
- if(#contextParameter[5]) {
- if((#contextParameter[2]) is (dynamic, dynamic) → dynamic) {
- (#contextParameter[2]).call(#contextParameter[3], #contextParameter[4]);
- }
- else
- if((#contextParameter[2]) is (dynamic) → dynamic) {
- (#contextParameter[2]).call(#contextParameter[3]);
- }
- else {
- (#contextParameter[2]).call();
- }
- }
- else {
- (#contextParameter[2]).call(#contextParameter[4]);
- }
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure.dart b/pkg/kernel/testcases/closures/capture_closure.dart
deleted file mode 100644
index cdfadf5..0000000
--- a/pkg/kernel/testcases/closures/capture_closure.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-main(arguments) {
- f() => null;
- g() => f();
- g();
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure.dart.expect b/pkg/kernel/testcases/closures/capture_closure.dart.expect
deleted file mode 100644
index 6019607..0000000
--- a/pkg/kernel/testcases/closures/capture_closure.dart.expect
+++ /dev/null
@@ -1,15 +0,0 @@
-library;
-import self as self;
-
-static method main(dynamic arguments) → dynamic {
- final dynamic #context = MakeVector(3);
- #context[2] = MakeClosure<() → dynamic>(self::closure#main#f, #context);
- final () → dynamic g = MakeClosure<() → dynamic>(self::closure#main#g, #context);
- g.call();
-}
-static method closure#main#f(dynamic #contextParameter) → dynamic {
- return null;
-}
-static method closure#main#g(dynamic #contextParameter) → dynamic {
- return (#contextParameter[2]).call();
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure_parameter.dart b/pkg/kernel/testcases/closures/capture_closure_parameter.dart
deleted file mode 100644
index 9d14c08..0000000
--- a/pkg/kernel/testcases/closures/capture_closure_parameter.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-main(List<String> arguments) {
- foo(x) {
- bar() {
- print(x);
- }
-
- return bar;
- }
-
- foo(arguments[0])();
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure_parameter.dart.expect b/pkg/kernel/testcases/closures/capture_closure_parameter.dart.expect
deleted file mode 100644
index 636ef9e..0000000
--- a/pkg/kernel/testcases/closures/capture_closure_parameter.dart.expect
+++ /dev/null
@@ -1,19 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main(core::List<core::String> arguments) → dynamic {
- final (dynamic) → dynamic foo = MakeClosure<(dynamic) → dynamic>(self::closure#main#foo, null);
- foo.call(arguments.[](0)).call();
-}
-static method closure#main#foo#bar(dynamic #contextParameter) → dynamic {
- core::print(#contextParameter[2]);
-}
-static method closure#main#foo(dynamic #contextParameter, dynamic x) → dynamic {
- final dynamic #context = MakeVector(3);
- #context[1] = #contextParameter;
- #context[2] = x;
- x = null;
- final () → dynamic bar = MakeClosure<() → dynamic>(self::closure#main#foo#bar, #context);
- return bar;
-}
diff --git a/pkg/kernel/testcases/closures/capture_this.dart b/pkg/kernel/testcases/closures/capture_this.dart
deleted file mode 100644
index bde384d..0000000
--- a/pkg/kernel/testcases/closures/capture_this.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C {
- var x;
- m() => (v) => x = v;
- f() => () => () => x;
-}
-
-main() {
- C c = new C();
- c.x = 41;
- c.m()(42);
- if (42 != c.x) throw "Unexpected value in c.x: ${c.x}";
- var result = c.f()()();
- if (42 != result) throw "Unexpected value from c.f()()(): $result";
-}
diff --git a/pkg/kernel/testcases/closures/capture_this.dart.expect b/pkg/kernel/testcases/closures/capture_this.dart.expect
deleted file mode 100644
index c12586a..0000000
--- a/pkg/kernel/testcases/closures/capture_this.dart.expect
+++ /dev/null
@@ -1,39 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
- field dynamic x = null;
- synthetic constructor •() → void
- : super core::Object::•()
- ;
- method m() → dynamic {
- final dynamic #context = MakeVector(3);
- #context[2] = this;
- return MakeClosure<(dynamic) → dynamic>(self::closure#C#m#function, #context);
- }
- method f() → dynamic {
- final dynamic #context = MakeVector(3);
- #context[2] = this;
- return MakeClosure<() → dynamic>(self::closure#C#f#function, #context);
- }
-}
-static method main() → dynamic {
- self::C c = new self::C::•();
- c.x = 41;
- c.m().call(42);
- if(!42.==(c.x))
- throw "Unexpected value in c.x: ${c.x}";
- dynamic result = c.f().call().call();
- if(!42.==(result))
- throw "Unexpected value from c.f()()(): ${result}";
-}
-static method closure#C#m#function(dynamic #contextParameter, dynamic v) → dynamic {
- return (#contextParameter[2]).x = v;
-}
-static method closure#C#f#function#function(dynamic #contextParameter) → dynamic {
- return (#contextParameter[2]).x;
-}
-static method closure#C#f#function(dynamic #contextParameter) → dynamic {
- return MakeClosure<() → dynamic>(self::closure#C#f#function#function, #contextParameter);
-}
diff --git a/pkg/kernel/testcases/closures/captured_class_type_vars.dart b/pkg/kernel/testcases/closures/captured_class_type_vars.dart
deleted file mode 100644
index 5767a93..0000000
--- a/pkg/kernel/testcases/closures/captured_class_type_vars.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class Isgen<B> {
- getfn() {
- return (x) => x is B;
- }
-}
-
-main() {
- int x = 3;
- var isgen = new Isgen<String>();
- var iser = isgen.getfn();
- assert(!iser(x));
-}
diff --git a/pkg/kernel/testcases/closures/captured_class_type_vars.dart.expect b/pkg/kernel/testcases/closures/captured_class_type_vars.dart.expect
deleted file mode 100644
index 479559a..0000000
--- a/pkg/kernel/testcases/closures/captured_class_type_vars.dart.expect
+++ /dev/null
@@ -1,21 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class Isgen<B extends core::Object> extends core::Object {
- synthetic constructor •() → void
- : super core::Object::•()
- ;
- method getfn() → dynamic {
- return MakeClosure<<B extends core::Object>(dynamic) → dynamic, self::Isgen::B>(self::closure#Isgen#getfn#function, MakeVector(1));
- }
-}
-static method main() → dynamic {
- core::int x = 3;
- dynamic isgen = new self::Isgen::•<core::String>();
- dynamic iser = isgen.getfn();
- assert(!iser.call(x));
-}
-static method closure#Isgen#getfn#function<B extends core::Object>(dynamic #contextParameter, dynamic x) → dynamic {
- return x is self::closure#Isgen#getfn#function::B;
-}
diff --git a/pkg/kernel/testcases/closures/catch.dart b/pkg/kernel/testcases/closures/catch.dart
deleted file mode 100644
index dcf383c..0000000
--- a/pkg/kernel/testcases/closures/catch.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-main() {
- var c;
- try {
- throw "Fisk";
- } on String catch (e, s) {
- c = () {
- print(e);
- if (s != null) print(s);
- };
- }
- c();
- print("TEST PASSED");
-}
diff --git a/pkg/kernel/testcases/closures/catch.dart.expect b/pkg/kernel/testcases/closures/catch.dart.expect
deleted file mode 100644
index 572da81..0000000
--- a/pkg/kernel/testcases/closures/catch.dart.expect
+++ /dev/null
@@ -1,23 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main() → dynamic {
- dynamic c;
- try {
- throw "Fisk";
- }
- on core::String catch(dynamic #t1, dynamic #t2) {
- final dynamic #context = MakeVector(4);
- #context[2] = #t1;
- #context[3] = #t2;
- c = MakeClosure<() → dynamic>(self::closure#main#function, #context);
- }
- c.call();
- core::print("TEST PASSED");
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
- core::print(#contextParameter[2]);
- if(!(#contextParameter[3]).==(null))
- core::print(#contextParameter[3]);
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_constructor.dart b/pkg/kernel/testcases/closures/closure_in_constructor.dart
deleted file mode 100644
index e864ed4..0000000
--- a/pkg/kernel/testcases/closures/closure_in_constructor.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C1 {
- var x;
- C1(y) : x = (() => print('Hello $y'));
-}
-
-class C2 {
- var x;
- C2(y) {
- x = () => print('Hello $y');
- }
-}
-
-main() {
- new C1('hest').x();
- new C2('naebdyr').x();
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_constructor.dart.expect b/pkg/kernel/testcases/closures/closure_in_constructor.dart.expect
deleted file mode 100644
index 8046f99..0000000
--- a/pkg/kernel/testcases/closures/closure_in_constructor.dart.expect
+++ /dev/null
@@ -1,30 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C1 extends core::Object {
- field dynamic x;
- constructor •(dynamic y) → void
- : final dynamic #context = MakeVector(3), dynamic #t1 = #context[2] = y, dynamic #t2 = y = null, self::C1::x = MakeClosure<() → dynamic>(self::closure#C1#function#function, #context), super core::Object::•()
- ;
-}
-class C2 extends core::Object {
- field dynamic x = null;
- constructor •(dynamic y) → void
- : super core::Object::•() {
- final dynamic #context = MakeVector(3);
- #context[2] = y;
- y = null;
- this.x = MakeClosure<() → dynamic>(self::closure#C2#function#function, #context);
- }
-}
-static method main() → dynamic {
- new self::C1::•("hest").x();
- new self::C2::•("naebdyr").x();
-}
-static method closure#C1#function#function(dynamic #contextParameter) → dynamic {
- return core::print("Hello ${#contextParameter[2]}");
-}
-static method closure#C2#function#function(dynamic #contextParameter) → dynamic {
- return core::print("Hello ${#contextParameter[2]}");
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer.dart b/pkg/kernel/testcases/closures/closure_in_initializer.dart
deleted file mode 100644
index 14a94dd..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C {
- var t;
- C.foo(f, x) : t = (() => f(x)) {
- x = 1;
- print(x);
- }
-}
-
-main() {
- print(0);
- var c = new C.foo((x) => print('hest${x}'), 0);
- print(2);
- c.t();
- print(3);
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer.dart.expect b/pkg/kernel/testcases/closures/closure_in_initializer.dart.expect
deleted file mode 100644
index 520a509..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer.dart.expect
+++ /dev/null
@@ -1,28 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
- field dynamic t;
- constructor foo(dynamic f, dynamic x) → void
- : final dynamic #context = MakeVector(4), this self::C::foo#redir(f, x, #context)
- ;
- constructor foo#redir(dynamic f, dynamic x, final dynamic #context) → void
- : dynamic #t1 = #context[2] = f, dynamic #t2 = f = null, dynamic #t3 = #context[3] = x, dynamic #t4 = x = null, self::C::t = MakeClosure<() → dynamic>(self::closure#C#foo#function, #context), super core::Object::•() {
- #context[3] = 1;
- core::print(#context[3]);
- }
-}
-static method main() → dynamic {
- core::print(0);
- dynamic c = new self::C::foo(MakeClosure<(dynamic) → dynamic>(self::closure#main#function, null), 0);
- core::print(2);
- c.t();
- core::print(3);
-}
-static method closure#C#foo#function(dynamic #contextParameter) → dynamic {
- return (#contextParameter[2]).call(#contextParameter[3]);
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
- return core::print("hest${x}");
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart b/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart
deleted file mode 100644
index 1cf175d..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C {
- var t;
- C.foo(f)
- : t = (() {
- var prefix;
- var g = (x) {
- f("$prefix$x");
- };
- prefix = 'hest';
- return g;
- }) {
- print(1);
- }
-}
-
-main() {
- print(0);
- var c = new C.foo((x) => print(x));
- print(2);
- c.t()('fisk');
- print(3);
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart.expect b/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart.expect
deleted file mode 100644
index d056bab..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart.expect
+++ /dev/null
@@ -1,32 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
- field dynamic t;
- constructor foo(dynamic f) → void
- : final dynamic #context = MakeVector(3), dynamic #t1 = #context[2] = f, dynamic #t2 = f = null, self::C::t = MakeClosure<() → dynamic>(self::closure#C#foo#function, #context), super core::Object::•() {
- core::print(1);
- }
-}
-static method main() → dynamic {
- core::print(0);
- dynamic c = new self::C::foo(MakeClosure<(dynamic) → dynamic>(self::closure#main#function, null));
- core::print(2);
- c.t().call("fisk");
- core::print(3);
-}
-static method closure#C#foo#function#function(dynamic #contextParameter, dynamic x) → dynamic {
- (#contextParameter[1][2]).call("${#contextParameter[2]}${x}");
-}
-static method closure#C#foo#function(dynamic #contextParameter) → dynamic {
- final dynamic #context = MakeVector(3);
- #context[1] = #contextParameter;
- #context[2] = null;
- dynamic g = MakeClosure<(dynamic) → dynamic>(self::closure#C#foo#function#function, #context);
- #context[2] = "hest";
- return g;
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
- return core::print(x);
-}
diff --git a/pkg/kernel/testcases/closures/closure_types.dart b/pkg/kernel/testcases/closures/closure_types.dart
deleted file mode 100644
index 86fc3e0..0000000
--- a/pkg/kernel/testcases/closures/closure_types.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-//
-// This tests checks that the runtime types of converted closures are asessed
-// correctly in is-tests.
-
-class C<T> {
- void getf() {
- T fn(T x) {
- return x;
- }
-
- ;
- return fn;
- }
-}
-
-typedef void ct(int x);
-
-void test_c() {
- var x = new C<int>().getf();
- assert(x is ct);
-
- var y = new C<String>().getf();
- assert(y is! ct);
-}
-
-class D<T> {
- void getf<S>() {
- T fn(S y) {
- return null;
- }
-
- return fn;
- }
-}
-
-typedef String dt(int x);
-
-void test_d() {
- var x = new D<String>().getf<int>();
- assert(x is dt);
-
- var y = new D<int>().getf<int>();
- assert(y is! dt);
-
- var z = new D<int>().getf<String>();
- assert(z is! dt);
-}
-
-main() {
- test_c();
- test_d();
-}
diff --git a/pkg/kernel/testcases/closures/closure_types.dart.expect b/pkg/kernel/testcases/closures/closure_types.dart.expect
deleted file mode 100644
index f9ad232..0000000
--- a/pkg/kernel/testcases/closures/closure_types.dart.expect
+++ /dev/null
@@ -1,49 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-typedef ct = (core::int) → void;
-typedef dt = (core::int) → core::String;
-class C<T extends core::Object> extends core::Object {
- synthetic constructor •() → void
- : super core::Object::•()
- ;
- method getf() → void {
- final (self::C::T) → self::C::T fn = MakeClosure<<T extends core::Object>(T) → T, self::C::T>(self::closure#C#getf#fn, MakeVector(1));
- ;
- return fn;
- }
-}
-class D<T extends core::Object> extends core::Object {
- synthetic constructor •() → void
- : super core::Object::•()
- ;
- method getf() → void {
- final (dynamic) → self::D::T fn = MakeClosure<<T extends core::Object>(dynamic) → T, self::D::T>(self::closure#D#getf#fn, MakeVector(1));
- return fn;
- }
-}
-static method test_c() → void {
- dynamic x = new self::C::•<core::int>().getf();
- assert(x is (core::int) → void);
- dynamic y = new self::C::•<core::String>().getf();
- assert(!(y is (core::int) → void));
-}
-static method test_d() → void {
- dynamic x = new self::D::•<core::String>().getf();
- assert(x is (core::int) → core::String);
- dynamic y = new self::D::•<core::int>().getf();
- assert(!(y is (core::int) → core::String));
- dynamic z = new self::D::•<core::int>().getf();
- assert(!(z is (core::int) → core::String));
-}
-static method main() → dynamic {
- self::test_c();
- self::test_d();
-}
-static method closure#C#getf#fn<T extends core::Object>(dynamic #contextParameter, self::closure#C#getf#fn::T x) → self::closure#C#getf#fn::T {
- return x;
-}
-static method closure#D#getf#fn<T extends core::Object>(dynamic #contextParameter, dynamic y) → self::closure#D#getf#fn::T {
- return null;
-}
diff --git a/pkg/kernel/testcases/closures/closures.dart b/pkg/kernel/testcases/closures/closures.dart
deleted file mode 100644
index 545ad55..0000000
--- a/pkg/kernel/testcases/closures/closures.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-var f;
-
-foo() {
- print(f(0));
-}
-
-main(arguments) {
- f = (x) => arguments[x];
- foo();
-}
diff --git a/pkg/kernel/testcases/closures/closures.dart.expect b/pkg/kernel/testcases/closures/closures.dart.expect
deleted file mode 100644
index c853baa..0000000
--- a/pkg/kernel/testcases/closures/closures.dart.expect
+++ /dev/null
@@ -1,18 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static field dynamic f;
-static method foo() → dynamic {
- core::print(self::f.call(0));
-}
-static method main(dynamic arguments) → dynamic {
- final dynamic #context = MakeVector(3);
- #context[2] = arguments;
- arguments = null;
- self::f = MakeClosure<(dynamic) → dynamic>(self::closure#main#function, #context);
- self::foo();
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
- return (#contextParameter[2]).[](x);
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart b/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart
deleted file mode 100644
index 36fc5c1..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// The purpose of this test is to detect that no unnecessary contexts are
-// created when a constructor parameter is used in its field initializers. No
-// contexts should be created either in the initializer or in the constructor
-// body.
-
-class X {}
-
-class A {
- X x;
- A(this.x) {}
-}
-
-class B {
- X x;
- B(X x) : x = x {
- fn() {
- print(x);
- }
-
- fn();
- }
-}
-
-main() {
- A a = new A(new X());
- B b = new B(new X());
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart.expect b/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart.expect
deleted file mode 100644
index 9a8f039..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart.expect
+++ /dev/null
@@ -1,32 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
- synthetic constructor •() → void
- : super core::Object::•()
- ;
-}
-class A extends core::Object {
- field self::X x;
- constructor •(self::X x) → void
- : self::A::x = x, super core::Object::•() {}
-}
-class B extends core::Object {
- field self::X x;
- constructor •(self::X x) → void
- : final dynamic #context = MakeVector(3), this self::B::#redir(x, #context)
- ;
- constructor #redir(self::X x, final dynamic #context) → void
- : dynamic #t1 = #context[2] = x, dynamic #t2 = x = null, self::B::x = #context[2], super core::Object::•() {
- final () → dynamic fn = MakeClosure<() → dynamic>(self::closure#B#function#fn, #context);
- fn.call();
- }
-}
-static method main() → dynamic {
- self::A a = new self::A::•(new self::X::•());
- self::B b = new self::B::•(new self::X::•());
-}
-static method closure#B#function#fn(dynamic #contextParameter) → dynamic {
- core::print(#contextParameter[2]);
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart b/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart
deleted file mode 100644
index 528b76b..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// The purpose of this test is to detect that no unnecessary contexts are
-// created when a constructor parameter is used in its super initializer. No
-// contexts should be created either in the initializer list or in the
-// constructor body.
-
-class X {}
-
-class Y {}
-
-class A {
- X x;
- Y y;
- A(this.x, this.y);
-}
-
-class B extends A {
- B(X x, Y y) : super(x, y) {}
-}
-
-main() {
- B b = new B(new X(), new Y());
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart.expect b/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart.expect
deleted file mode 100644
index 3fb0a71..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart.expect
+++ /dev/null
@@ -1,28 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
- synthetic constructor •() → void
- : super core::Object::•()
- ;
-}
-class Y extends core::Object {
- synthetic constructor •() → void
- : super core::Object::•()
- ;
-}
-class A extends core::Object {
- field self::X x;
- field self::Y y;
- constructor •(self::X x, self::Y y) → void
- : self::A::x = x, self::A::y = y, super core::Object::•()
- ;
-}
-class B extends self::A {
- constructor •(self::X x, self::Y y) → void
- : super self::A::•(x, y) {}
-}
-static method main() → dynamic {
- self::B b = new self::B::•(new self::X::•(), new self::Y::•());
-}
diff --git a/pkg/kernel/testcases/closures/field.dart b/pkg/kernel/testcases/closures/field.dart
deleted file mode 100644
index 910a128..0000000
--- a/pkg/kernel/testcases/closures/field.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-var x = () => "x";
-
-class C<T> {
- var v = (x) => x is T;
-
- final y = () => "y";
-
- static final z = () => "z";
-}
-
-main() {
- if (!new C<String>().v("")) throw "C<String>.v false on String";
- if (new C<String>().v(0)) throw "C<String>.v true on int";
- if (new C<String>().v(null)) throw "C<String>.v true on null";
- if (new C<int>().v("")) throw "C<int>.v true on String";
- if (!new C<int>().v(0)) throw "C<int>.v false on int";
- if (new C<int>().v(null)) throw "C<int>.v true on null";
- if ("x" != x()) throw "x";
- if ("y" != new C<String>().y()) throw "y";
- if ("z" != C.z()) throw "z";
-}
diff --git a/pkg/kernel/testcases/closures/field.dart.expect b/pkg/kernel/testcases/closures/field.dart.expect
deleted file mode 100644
index 7136b0c9..0000000
--- a/pkg/kernel/testcases/closures/field.dart.expect
+++ /dev/null
@@ -1,45 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C<T extends core::Object> extends core::Object {
- field dynamic v = MakeClosure<<T extends core::Object>(dynamic) → dynamic, self::C::T>(self::closure#C#v#function, MakeVector(1));
- final field dynamic y = MakeClosure<() → dynamic>(self::closure#C#y#function, null);
- static final field dynamic z = MakeClosure<() → dynamic>(self::closure#C#z#function, null);
- synthetic constructor •() → void
- : super core::Object::•()
- ;
-}
-static field dynamic x = MakeClosure<() → dynamic>(self::closure#x#function, null);
-static method main() → dynamic {
- if(!new self::C::•<core::String>().v(""))
- throw "C<String>.v false on String";
- if(new self::C::•<core::String>().v(0))
- throw "C<String>.v true on int";
- if(new self::C::•<core::String>().v(null))
- throw "C<String>.v true on null";
- if(new self::C::•<core::int>().v(""))
- throw "C<int>.v true on String";
- if(!new self::C::•<core::int>().v(0))
- throw "C<int>.v false on int";
- if(new self::C::•<core::int>().v(null))
- throw "C<int>.v true on null";
- if(!"x".==(self::x.call()))
- throw "x";
- if(!"y".==(new self::C::•<core::String>().y()))
- throw "y";
- if(!"z".==(self::C::z.call()))
- throw "z";
-}
-static method closure#C#v#function<T extends core::Object>(dynamic #contextParameter, dynamic x) → dynamic {
- return x is self::closure#C#v#function::T;
-}
-static method closure#C#y#function(dynamic #contextParameter) → dynamic {
- return "y";
-}
-static method closure#C#z#function(dynamic #contextParameter) → dynamic {
- return "z";
-}
-static method closure#x#function(dynamic #contextParameter) → dynamic {
- return "x";
-}
diff --git a/pkg/kernel/testcases/closures/for_in_closure.dart b/pkg/kernel/testcases/closures/for_in_closure.dart
deleted file mode 100644
index 7dab558..0000000
--- a/pkg/kernel/testcases/closures/for_in_closure.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-const numbers = const <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-main() {
- var closures = [];
- var captured_outside = 0;
- for (int i in numbers) {
- closures.add(() => i + captured_outside);
- }
- int sum = 0;
- for (Function f in closures) {
- sum += f();
- }
- // This formula is credited to Gauss. Search for "Gauss adding 1 to 100".
- int expectedSum = (numbers.length - 1) * numbers.length ~/ 2;
- if (expectedSum != sum) {
- throw new Exception("Unexpected sum = $sum != $expectedSum");
- }
-}
diff --git a/pkg/kernel/testcases/closures/for_in_closure.dart.expect b/pkg/kernel/testcases/closures/for_in_closure.dart.expect
deleted file mode 100644
index e3180e4..0000000
--- a/pkg/kernel/testcases/closures/for_in_closure.dart.expect
+++ /dev/null
@@ -1,29 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static const field dynamic numbers = const <core::int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-static method main() → dynamic {
- dynamic closures = <dynamic>[];
- final dynamic #context = MakeVector(3);
- #context[2] = 0;
- for (core::int i in self::numbers) {
- final dynamic #context = MakeVector(3);
- #context[1] = #context;
- #context[2] = i;
- {
- closures.add(MakeClosure<() → dynamic>(self::closure#main#function, #context));
- }
- }
- core::int sum = 0;
- for (core::Function f in closures) {
- sum = sum.+(f.call());
- }
- core::int expectedSum = self::numbers.length.-(1).*(self::numbers.length).~/(2);
- if(!expectedSum.==(sum)) {
- throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
- }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
- return (#contextParameter[2]).+(#contextParameter[1][2]);
-}
diff --git a/pkg/kernel/testcases/closures/for_loop.dart b/pkg/kernel/testcases/closures/for_loop.dart
deleted file mode 100644
index f7b4249..0000000
--- a/pkg/kernel/testcases/closures/for_loop.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-const int max = 100;
-
-main() {
- var closures = [];
- var closures2 = [];
- var last;
- for (int i = 0; i < max; i++) {
- closures.add(() => last = i);
- closures2.add(() {
- if (last != max - 1) throw "last: $last != ${max - 1}";
- });
- }
- int sum = 0;
- for (Function f in closures) {
- sum += f();
- }
- for (Function f in closures2) {
- f();
- }
- // This formula is credited to Gauss. Search for "Gauss adding 1 to 100".
- int expectedSum = (max - 1) * max ~/ 2;
- if (expectedSum != sum) {
- throw new Exception("Unexpected sum = $sum != $expectedSum");
- }
-}
diff --git a/pkg/kernel/testcases/closures/for_loop.dart.expect b/pkg/kernel/testcases/closures/for_loop.dart.expect
deleted file mode 100644
index 9334b7b..0000000
--- a/pkg/kernel/testcases/closures/for_loop.dart.expect
+++ /dev/null
@@ -1,38 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static const field core::int max = 100;
-static method main() → dynamic {
- dynamic closures = <dynamic>[];
- dynamic closures2 = <dynamic>[];
- final dynamic #context = MakeVector(3);
- #context[2] = null;
- {
- dynamic #context = MakeVector(3);
- #context[1] = #context;
- #context[2] = 0;
- for (; (#context[2]).<(self::max); #context = CopyVector(#context), #context[2] = (#context[2]).+(1)) {
- closures.add(MakeClosure<() → dynamic>(self::closure#main#function, #context));
- closures2.add(MakeClosure<() → dynamic>(self::closure#main#function#1, #context));
- }
- }
- core::int sum = 0;
- for (core::Function f in closures) {
- sum = sum.+(f.call());
- }
- for (core::Function f in closures2) {
- f.call();
- }
- core::int expectedSum = self::max.-(1).*(self::max).~/(2);
- if(!expectedSum.==(sum)) {
- throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
- }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
- return #contextParameter[1][2] = #contextParameter[2];
-}
-static method closure#main#function#1(dynamic #contextParameter) → dynamic {
- if(!(#contextParameter[1][2]).==(self::max.-(1)))
- throw "last: ${#contextParameter[1][2]} != ${self::max.-(1)}";
-}
diff --git a/pkg/kernel/testcases/closures/for_variable_capture_test.dart b/pkg/kernel/testcases/closures/for_variable_capture_test.dart
deleted file mode 100644
index 1841576..0000000
--- a/pkg/kernel/testcases/closures/for_variable_capture_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-main() {
- var closure;
- for (var i = 0, fn = () => i; i < 3; i++) {
- i += 1;
- closure = fn;
- }
- var x = closure();
- if (x != 1) {
- throw "Expected 1, but got $x.";
- }
-}
diff --git a/pkg/kernel/testcases/closures/for_variable_capture_test.dart.expect b/pkg/kernel/testcases/closures/for_variable_capture_test.dart.expect
deleted file mode 100644
index dd1dffc..0000000
--- a/pkg/kernel/testcases/closures/for_variable_capture_test.dart.expect
+++ /dev/null
@@ -1,22 +0,0 @@
-library;
-import self as self;
-
-static method main() → dynamic {
- dynamic closure;
- {
- dynamic #context = MakeVector(3);
- #context[2] = 0;
- dynamic fn = MakeClosure<() → dynamic>(self::closure#main#function, #context);
- for (; (#context[2]).<(3); #context = CopyVector(#context), #context[2] = (#context[2]).+(1)) {
- #context[2] = (#context[2]).+(1);
- closure = fn;
- }
- }
- dynamic x = closure.call();
- if(!x.==(1)) {
- throw "Expected 1, but got ${x}.";
- }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
- return #contextParameter[2];
-}
diff --git a/pkg/kernel/testcases/closures/instance_tear_off.dart b/pkg/kernel/testcases/closures/instance_tear_off.dart
deleted file mode 100644
index a0c4ce8..0000000
--- a/pkg/kernel/testcases/closures/instance_tear_off.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C {
- var f = () => "f";
- get g => (x) => "g($x)";
- a() => "a";
- b(x) => x;
- c(x, [y = 2]) => x + y;
- d(x, {y: 2}) => x + y;
-}
-
-/// This class doesn't use its type variable.
-class D<T> {
- var f = () => "f";
- get g => (x) => "g($x)";
- a() => "a";
- b(x) => x;
- c(x, [y = 2]) => x + y;
- d(x, {y: 2}) => x + y;
-}
-
-/// This class uses its type variable.
-class E<T> {
- var f = () => "f";
- get g => (T x) => "g($x)";
- a() => "a";
- b(T x) => x;
- c(T x, [T y = 2]) => x + y;
- d(T x, {T y: 2}) => x + y;
-}
-
-expect(expected, actual) {
- print("Expecting '$expected' and got '$actual'");
- if (expected != actual) {
- print("Expected '$expected' but got '$actual'");
- throw "Expected '$expected' but got '$actual'";
- }
-}
-
-test(o) {
- expect("f", o.f());
- expect("f", (o.f)());
- expect("g(42)", o.g(42));
- expect("g(42)", (o.g)(42));
- expect("a", o.a());
- expect("a", (o.a)());
- expect(42, o.b(42));
- expect(42, (o.b)(42));
- expect(42, o.c(40));
- expect(42, (o.c)(40));
- expect(87, o.c(80, 7));
- expect(87, (o.c)(80, 7));
- expect(42, o.d(40));
- expect(42, (o.d)(40));
- expect(87, o.d(80, y: 7));
- expect(87, (o.d)(80, y: 7));
-}
-
-main(arguments) {
- test(new C());
- test(new D<int>());
- test(new E<int>());
-}
diff --git a/pkg/kernel/testcases/closures/instance_tear_off.dart.expect b/pkg/kernel/testcases/closures/instance_tear_off.dart.expect
deleted file mode 100644
index e0f8e77..0000000
--- a/pkg/kernel/testcases/closures/instance_tear_off.dart.expect
+++ /dev/null
@@ -1,100 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
- field dynamic f = MakeClosure<() → dynamic>(self::closure#C#f#function, null);
- synthetic constructor •() → void
- : super core::Object::•()
- ;
- get g() → dynamic
- return MakeClosure<(dynamic) → dynamic>(self::closure#C#g#function, null);
- method a() → dynamic
- return "a";
- method b(dynamic x) → dynamic
- return x;
- method c(dynamic x, [dynamic y = 2]) → dynamic
- return x.+(y);
- method d(dynamic x, {dynamic y = 2}) → dynamic
- return x.+(y);
-}
-class D<T extends core::Object> extends core::Object {
- field dynamic f = MakeClosure<() → dynamic>(self::closure#D#f#function, null);
- synthetic constructor •() → void
- : super core::Object::•()
- ;
- get g() → dynamic
- return MakeClosure<(dynamic) → dynamic>(self::closure#D#g#function, null);
- method a() → dynamic
- return "a";
- method b(dynamic x) → dynamic
- return x;
- method c(dynamic x, [dynamic y = 2]) → dynamic
- return x.+(y);
- method d(dynamic x, {dynamic y = 2}) → dynamic
- return x.+(y);
-}
-class E<T extends core::Object> extends core::Object {
- field dynamic f = MakeClosure<() → dynamic>(self::closure#E#f#function, null);
- synthetic constructor •() → void
- : super core::Object::•()
- ;
- get g() → dynamic
- return MakeClosure<<T extends core::Object>(T) → dynamic, self::E::T>(self::closure#E#g#function, MakeVector(1));
- method a() → dynamic
- return "a";
- method b(self::E::T x) → dynamic
- return x;
- method c(self::E::T x, [self::E::T y = 2]) → dynamic
- return x.+(y);
- method d(self::E::T x, {self::E::T y = 2}) → dynamic
- return x.+(y);
-}
-static method expect(dynamic expected, dynamic actual) → dynamic {
- core::print("Expecting '${expected}' and got '${actual}'");
- if(!expected.==(actual)) {
- core::print("Expected '${expected}' but got '${actual}'");
- throw "Expected '${expected}' but got '${actual}'";
- }
-}
-static method test(dynamic o) → dynamic {
- self::expect("f", o.f());
- self::expect("f", o.f.call());
- self::expect("g(42)", o.g(42));
- self::expect("g(42)", o.g.call(42));
- self::expect("a", o.a());
- self::expect("a", o.a.call());
- self::expect(42, o.b(42));
- self::expect(42, o.b.call(42));
- self::expect(42, o.c(40));
- self::expect(42, o.c.call(40));
- self::expect(87, o.c(80, 7));
- self::expect(87, o.c.call(80, 7));
- self::expect(42, o.d(40));
- self::expect(42, o.d.call(40));
- self::expect(87, o.d(80, y: 7));
- self::expect(87, o.d.call(80, y: 7));
-}
-static method main(dynamic arguments) → dynamic {
- self::test(new self::C::•());
- self::test(new self::D::•<core::int>());
- self::test(new self::E::•<core::int>());
-}
-static method closure#C#g#function(dynamic #contextParameter, dynamic x) → dynamic {
- return "g(${x})";
-}
-static method closure#C#f#function(dynamic #contextParameter) → dynamic {
- return "f";
-}
-static method closure#D#g#function(dynamic #contextParameter, dynamic x) → dynamic {
- return "g(${x})";
-}
-static method closure#D#f#function(dynamic #contextParameter) → dynamic {
- return "f";
-}
-static method closure#E#g#function<T extends core::Object>(dynamic #contextParameter, self::closure#E#g#function::T x) → dynamic {
- return "g(${x})";
-}
-static method closure#E#f#function(dynamic #contextParameter) → dynamic {
- return "f";
-}
diff --git a/pkg/kernel/testcases/closures/loop2.dart b/pkg/kernel/testcases/closures/loop2.dart
deleted file mode 100644
index 2069f03..0000000
--- a/pkg/kernel/testcases/closures/loop2.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// Check that a variable declared and captured inside a loop is given a separate
-// context for each iteration of the loop, so changes to the variable in
-// subsequent iterations are not visible to closures capturing it in prior
-// iterations.
-
-void doit(int x) {
- final int max = 10;
- final double expectedSum = ((max - 1) * max) / 2;
-
- int counter = 0;
- var calls = [];
- while (counter < max) {
- int pos = counter;
- calls.add(() => pos + x);
- counter++;
- }
-
- double sum = 0.0;
- for (var c in calls) sum += c();
- if (sum != expectedSum)
- throw new Exception("Unexpected sum = $sum != $expectedSum");
-}
-
-void main() {
- doit(0);
-}
diff --git a/pkg/kernel/testcases/closures/loop2.dart.expect b/pkg/kernel/testcases/closures/loop2.dart.expect
deleted file mode 100644
index ad312b1..0000000
--- a/pkg/kernel/testcases/closures/loop2.dart.expect
+++ /dev/null
@@ -1,31 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method doit(core::int x) → void {
- final dynamic #context = MakeVector(3);
- #context[2] = x;
- x = null;
- final core::int max = 10;
- final core::double expectedSum = max.-(1).*(max)./(2);
- core::int counter = 0;
- dynamic calls = <dynamic>[];
- while (counter.<(max)) {
- final dynamic #context = MakeVector(3);
- #context[1] = #context;
- #context[2] = counter;
- calls.add(MakeClosure<() → dynamic>(self::closure#doit#function, #context));
- counter = counter.+(1);
- }
- core::double sum = 0.0;
- for (dynamic c in calls)
- sum = sum.+(c.call());
- if(!sum.==(expectedSum))
- throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
-}
-static method main() → void {
- self::doit(0);
-}
-static method closure#doit#function(dynamic #contextParameter) → dynamic {
- return (#contextParameter[2]).+(#contextParameter[1][2]);
-}
diff --git a/pkg/kernel/testcases/closures/named_closure.dart b/pkg/kernel/testcases/closures/named_closure.dart
deleted file mode 100644
index 8040e78..0000000
--- a/pkg/kernel/testcases/closures/named_closure.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-var f;
-
-foo() {
- print(f(0));
-}
-
-main(arguments) {
- g(x) => arguments[x];
- f = g;
- foo();
-}
diff --git a/pkg/kernel/testcases/closures/named_closure.dart.expect b/pkg/kernel/testcases/closures/named_closure.dart.expect
deleted file mode 100644
index 83b9e8e..0000000
--- a/pkg/kernel/testcases/closures/named_closure.dart.expect
+++ /dev/null
@@ -1,19 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static field dynamic f;
-static method foo() → dynamic {
- core::print(self::f.call(0));
-}
-static method main(dynamic arguments) → dynamic {
- final dynamic #context = MakeVector(3);
- #context[2] = arguments;
- arguments = null;
- final (dynamic) → dynamic g = MakeClosure<(dynamic) → dynamic>(self::closure#main#g, #context);
- self::f = g;
- self::foo();
-}
-static method closure#main#g(dynamic #contextParameter, dynamic x) → dynamic {
- return (#contextParameter[2]).[](x);
-}
diff --git a/pkg/kernel/testcases/closures/non_void_context.dart b/pkg/kernel/testcases/closures/non_void_context.dart
deleted file mode 100644
index 0987ab5..0000000
--- a/pkg/kernel/testcases/closures/non_void_context.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-var v;
-
-main(arguments) {
- var w;
- ((x) => v = w = x)(87);
- if (v != 87) {
- throw "Unexpected value in v: $v";
- }
- if (w != 87) {
- throw "Unexpected value in w: $w";
- }
- v = true;
- (() {
- for (; w = v;) {
- v = false;
- }
- })();
- if (v != false) {
- throw "Unexpected value in v: $v";
- }
- if (w != false) {
- throw "Unexpected value in w: $w";
- }
-}
diff --git a/pkg/kernel/testcases/closures/non_void_context.dart.expect b/pkg/kernel/testcases/closures/non_void_context.dart.expect
deleted file mode 100644
index 7e1df31..0000000
--- a/pkg/kernel/testcases/closures/non_void_context.dart.expect
+++ /dev/null
@@ -1,31 +0,0 @@
-library;
-import self as self;
-
-static field dynamic v;
-static method main(dynamic arguments) → dynamic {
- final dynamic #context = MakeVector(3);
- #context[2] = null;
- (MakeClosure<(dynamic) → dynamic>(self::closure#main#function, #context)).call(87);
- if(!self::v.==(87)) {
- throw "Unexpected value in v: ${self::v}";
- }
- if(!(#context[2]).==(87)) {
- throw "Unexpected value in w: ${#context[2]}";
- }
- self::v = true;
- (MakeClosure<() → dynamic>(self::closure#main#function#1, #context)).call();
- if(!self::v.==(false)) {
- throw "Unexpected value in v: ${self::v}";
- }
- if(!(#context[2]).==(false)) {
- throw "Unexpected value in w: ${#context[2]}";
- }
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
- return self::v = #contextParameter[2] = x;
-}
-static method closure#main#function#1(dynamic #contextParameter) → dynamic {
- for (; #contextParameter[2] = self::v; ) {
- self::v = false;
- }
-}
diff --git a/pkg/kernel/testcases/closures/static_tear_off.dart b/pkg/kernel/testcases/closures/static_tear_off.dart
deleted file mode 100644
index 29de7c7..0000000
--- a/pkg/kernel/testcases/closures/static_tear_off.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-f_1_1_no_default(a, [b]) => a + b;
-
-f_1_1_default(a, [b = 2]) => a + b;
-
-f_1_b_no_default(a, {b}) => a + b;
-
-f_1_b_default(a, {b: 2}) => a + b;
-
-test_1_1(Function f, bool hasDefault) {
- var result = f(40, 2);
- if (42 != result) throw "Unexpected result: $result";
- test_1(f, hasDefault);
-}
-
-test_1_b(Function f, bool hasDefault) {
- var result = f(40, b: 2);
- if (42 != result) throw "Unexpected result: $result";
- test_1(f, hasDefault);
-}
-
-test_1(Function f, bool hasDefault) {
- var result = 0;
- bool threw = true;
- try {
- result = f(40);
- threw = false;
- } catch (_) {
- // Ignored.
- }
- if (hasDefault) {
- if (threw) throw "Unexpected exception.";
- if (42 != result) throw "Unexpected result: $result.";
- } else {
- if (!threw) throw "Expected exception missing.";
- if (0 != result) throw "Unexpected result: $result.";
- }
-}
-
-main(arguments) {
- test_1_1(f_1_1_no_default, false);
- test_1_1(f_1_1_default, true);
- test_1_b(f_1_b_no_default, false);
- test_1_b(f_1_b_default, true);
-}
diff --git a/pkg/kernel/testcases/closures/static_tear_off.dart.expect b/pkg/kernel/testcases/closures/static_tear_off.dart.expect
deleted file mode 100644
index 7eed6c1..0000000
--- a/pkg/kernel/testcases/closures/static_tear_off.dart.expect
+++ /dev/null
@@ -1,52 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method f_1_1_no_default(dynamic a, [dynamic b = null]) → dynamic
- return a.+(b);
-static method f_1_1_default(dynamic a, [dynamic b = 2]) → dynamic
- return a.+(b);
-static method f_1_b_no_default(dynamic a, {dynamic b = null}) → dynamic
- return a.+(b);
-static method f_1_b_default(dynamic a, {dynamic b = 2}) → dynamic
- return a.+(b);
-static method test_1_1(core::Function f, core::bool hasDefault) → dynamic {
- dynamic result = f.call(40, 2);
- if(!42.==(result))
- throw "Unexpected result: ${result}";
- self::test_1(f, hasDefault);
-}
-static method test_1_b(core::Function f, core::bool hasDefault) → dynamic {
- dynamic result = f.call(40, b: 2);
- if(!42.==(result))
- throw "Unexpected result: ${result}";
- self::test_1(f, hasDefault);
-}
-static method test_1(core::Function f, core::bool hasDefault) → dynamic {
- dynamic result = 0;
- core::bool threw = true;
- try {
- result = f.call(40);
- threw = false;
- }
- on dynamic catch(final dynamic _) {
- }
- if(hasDefault) {
- if(threw)
- throw "Unexpected exception.";
- if(!42.==(result))
- throw "Unexpected result: ${result}.";
- }
- else {
- if(!threw)
- throw "Expected exception missing.";
- if(!0.==(result))
- throw "Unexpected result: ${result}.";
- }
-}
-static method main(dynamic arguments) → dynamic {
- self::test_1_1(self::f_1_1_no_default, false);
- self::test_1_1(self::f_1_1_default, true);
- self::test_1_b(self::f_1_b_no_default, false);
- self::test_1_b(self::f_1_b_default, true);
-}
diff --git a/pkg/kernel/testcases/closures/syncstar.dart b/pkg/kernel/testcases/closures/syncstar.dart
deleted file mode 100644
index 9dd0543..0000000
--- a/pkg/kernel/testcases/closures/syncstar.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// This tests that the wrapper function around converted closures in the VM
-// doesn't break when the context parameter is captured (since async
-// transformations introduces an additional closure here).
-
-range(int high) {
- iter(int low) sync* {
- while (high-- > low) yield high;
- }
-
- return iter;
-}
-
-main() {
- var sum = 0;
- for (var x in range(10)(2)) sum += x;
-
- if (sum != 44) {
- throw new Exception("Incorrect output.");
- }
-}
diff --git a/pkg/kernel/testcases/closures/syncstar.dart.expect b/pkg/kernel/testcases/closures/syncstar.dart.expect
deleted file mode 100644
index d107c33..0000000
--- a/pkg/kernel/testcases/closures/syncstar.dart.expect
+++ /dev/null
@@ -1,37 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method range(core::int high) → dynamic {
- final dynamic #context = MakeVector(3);
- #context[2] = high;
- high = null;
- final (core::int) → dynamic iter = MakeClosure<(core::int) → dynamic>(self::closure#range#iter, #context);
- return iter;
-}
-static method main() → dynamic {
- dynamic sum = 0;
- for (dynamic x in self::range(10).call(2))
- sum = sum.+(x);
- if(!sum.==(44)) {
- throw core::Exception::•("Incorrect output.");
- }
-}
-static method closure#range#iter(dynamic #contextParameter, core::int low) → dynamic /* originally sync* */ {
- final dynamic #context = MakeVector(3);
- #context[1] = #contextParameter;
- #context[2] = low;
- low = null;
- dynamic :await_jump_var = 0;
- dynamic :await_ctx_var;
- dynamic :sync_op = (core::Iterator<dynamic> :iterator) → core::bool yielding {
- {
- while ((let final dynamic #t1 = #contextParameter[2] in let final dynamic #t2 = #contextParameter[2] = #t1.-(1) in #t1).>(#context[2])) {
- :iterator._current = #context[1][2];
- [yield] true;
- }
- }
- return false;
- };
- return new core::_SyncIterable::•(:sync_op);
-}
diff --git a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart b/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart
deleted file mode 100644
index 8c60816..0000000
--- a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-const numbers = const <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-main() {
- var closures = [];
- for (int i in numbers) {
- int j = i;
- closures.add(() => j);
- }
- int sum = 0;
- for (Function f in closures) {
- sum += f();
- }
- // This formula is credited to Gauss. Search for "Gauss adding 1 to 100".
- int expectedSum = (numbers.length - 1) * numbers.length ~/ 2;
- if (expectedSum != sum) {
- throw new Exception("Unexpected sum = $sum != $expectedSum");
- }
-}
diff --git a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart.expect b/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart.expect
deleted file mode 100644
index 84f45e3..0000000
--- a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart.expect
+++ /dev/null
@@ -1,24 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static const field dynamic numbers = const <core::int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-static method main() → dynamic {
- dynamic closures = <dynamic>[];
- for (core::int i in self::numbers) {
- final dynamic #context = MakeVector(3);
- #context[2] = i;
- closures.add(MakeClosure<() → dynamic>(self::closure#main#function, #context));
- }
- core::int sum = 0;
- for (core::Function f in closures) {
- sum = sum.+(f.call());
- }
- core::int expectedSum = self::numbers.length.-(1).*(self::numbers.length).~/(2);
- if(!expectedSum.==(sum)) {
- throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
- }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
- return #contextParameter[2];
-}
diff --git a/pkg/kernel/testcases/closures_initializers/initializers.dart b/pkg/kernel/testcases/closures_initializers/initializers.dart
deleted file mode 100644
index 290fa98..0000000
--- a/pkg/kernel/testcases/closures_initializers/initializers.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// The purpose of this test is to detect that closures in [LocalInitializer]s
-// and [FieldInitializer]s are properly converted. This test assumes that
-// [ArgumentExtractionForTesting] transformer was run before closure conversion.
-// It should introduce one [LocalInitializer] for each argument passed to a
-// field initializer for a field ending in "_li". If such argument contains a
-// closure, it would appear in a [LocalInitializer]. The [FieldInitializer]
-// example requires no such elaboration.
-
-class X {}
-
-// Closure in field initializer.
-//
-class A {
- X foo;
- A(X i) : foo = ((() => i)());
-}
-
-// Closure in super initializer.
-//
-class S extends A {
- S(X i) : super((() => i)());
-}
-
-// Closure in local initializer.
-//
-class S2 {
- X foo_li;
- S2(X foo) : foo_li = (() => foo)();
-}
-
-// Closure in redirecting initializer.
-//
-class B {
- X foo;
- B.named(X foo) {}
- B(X foo) : this.named((() => foo)());
-}
-
-main() {
- A a = new A(new X());
- a.foo; // To prevent dartanalyzer from marking [a] as unused.
- B b = new B(new X());
- b.foo;
- S s = new S(new X());
- s.foo;
- S2 s2 = new S2(new X());
- s2.foo_li;
-}
diff --git a/pkg/kernel/testcases/closures_initializers/initializers.dart.expect b/pkg/kernel/testcases/closures_initializers/initializers.dart.expect
deleted file mode 100644
index b97b4f0..0000000
--- a/pkg/kernel/testcases/closures_initializers/initializers.dart.expect
+++ /dev/null
@@ -1,56 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
- constructor •() → void
- : super core::Object::•()
- ;
-}
-class A extends core::Object {
- field self::X foo;
- constructor •(self::X i) → void
- : final Vector #context = MakeVector(2), dynamic #t1 = #context[1] = i, self::A::foo = (MakeClosure<() → dynamic>(self::closure#A#function#function, #context)).call(), super core::Object::•()
- ;
-}
-class S extends self::A {
- constructor •(self::X i) → void
- : final Vector #context = MakeVector(2), dynamic #t2 = #context[1] = i, super self::A::•((MakeClosure<() → dynamic>(self::closure#S#function#function, #context)).call())
- ;
-}
-class S2 extends core::Object {
- field self::X foo_li;
- constructor •(self::X foo) → void
- : final Vector #context = MakeVector(2), dynamic #t3 = #context[1] = foo, dynamic #li_0 = (MakeClosure<() → dynamic>(self::closure#S2#function#function, #context)).call(), self::S2::foo_li = #li_0, super core::Object::•()
- ;
-}
-class B extends core::Object {
- field self::X foo = null;
- constructor named(self::X foo) → void
- : super core::Object::•() {}
- constructor •(self::X foo) → void
- : final Vector #context = MakeVector(2), dynamic #t4 = #context[1] = foo, this self::B::named((MakeClosure<() → dynamic>(self::closure#B#function#function, #context)).call())
- ;
-}
-static method main() → dynamic {
- self::A a = new self::A::•(new self::X::•());
- a.foo;
- self::B b = new self::B::•(new self::X::•());
- b.foo;
- self::S s = new self::S::•(new self::X::•());
- s.foo;
- self::S2 s2 = new self::S2::•(new self::X::•());
- s2.foo_li;
-}
-static method closure#A#function#function(Vector #contextParameter) → dynamic {
- return #contextParameter[1];
-}
-static method closure#S#function#function(Vector #contextParameter) → dynamic {
- return #contextParameter[1];
-}
-static method closure#S2#function#function(Vector #contextParameter) → dynamic {
- return #contextParameter[1];
-}
-static method closure#B#function#function(Vector #contextParameter) → dynamic {
- return #contextParameter[1];
-}
diff --git a/pkg/kernel/testcases/closures_initializers/local_initializers.dart.expect b/pkg/kernel/testcases/closures_initializers/local_initializers.dart.expect
deleted file mode 100644
index d4eb340..0000000
--- a/pkg/kernel/testcases/closures_initializers/local_initializers.dart.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
- constructor •() → void
- : super core::Object::•()
- ;
-}
-class A extends core::Object {
- field self::X foo;
- constructor •(self::X i) → void
- : self::A::foo = let final Vector #context = MakeVector(2) in let dynamic #t1 = #context[1] = i in (MakeClosure<() → dynamic>(self::closure#A#function#function, #context)).call(), super core::Object::•()
- ;
-}
-class B extends core::Object {
- field self::X foo = null;
- constructor named(self::X foo) → void
- : super core::Object::•() {}
- constructor •(self::X foo) → void
- : dynamic extracted#0 = let final Vector #context = MakeVector(2) in let dynamic #t2 = #context[1] = foo in (MakeClosure<() → dynamic>(self::closure#B#function#function, #context)).call(), this self::B::named(extracted#0)
- ;
-}
-static method main() → dynamic {
- self::A a = new self::A::•(new self::X::•());
- a.foo;
- self::B b = new self::B::•(new self::X::•());
- b.foo;
-}
-static method closure#A#function#function(Vector #contextParameter) → dynamic {
- return #contextParameter[1];
-}
-static method closure#B#function#function(Vector #contextParameter) → dynamic {
- return #contextParameter[1];
-}
diff --git a/pkg/kernel/testcases/closures_type_vars/type_variables.dart b/pkg/kernel/testcases/closures_type_vars/type_variables.dart
deleted file mode 100644
index 2de2994..0000000
--- a/pkg/kernel/testcases/closures_type_vars/type_variables.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C<T, S> {
- foo(S s) => (T x) {
- T y = x;
- Object z = y;
- C<T, S> self = this;
- return z as T;
- };
-
- bar() {
- C<T, S> self = this;
- }
-
- baz() {
- return () => () => new C<T, S>();
- }
-
- factory C() {
- local() {
- C<T, S> self = new C<T, S>.internal();
- return self;
- }
-
- return local();
- }
- C.internal();
-}
-
-fn<A>(A x) {
- var fn2 = (A x2) {
- var l = <A>[];
- l.add(x2);
- return l;
- };
- return fn2(x);
-}
-
-main(arguments) {
- print(new C<String, String>().foo(null)(arguments.first));
- dynamic c = new C<int, int>().baz()()();
- if (c is! C<int, int>) throw "$c fails type test 'is C<int, int>'";
- if (c is C<String, String>) {
- throw "$c passes type test 'is C<String, String>'";
- }
- print(c);
- print(fn<int>(3));
-}
diff --git a/pkg/kernel/testcases/closures_type_vars/type_variables.dart.expect b/pkg/kernel/testcases/closures_type_vars/type_variables.dart.expect
deleted file mode 100644
index 0eafb09..0000000
--- a/pkg/kernel/testcases/closures_type_vars/type_variables.dart.expect
+++ /dev/null
@@ -1,60 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C<T extends core::Object, S extends core::Object> extends core::Object {
- constructor internal() → void
- : super core::Object::•()
- ;
- method foo(self::C::S s) → dynamic {
- final Vector #context = MakeVector(3);
- #context[2] = this;
- return MakeClosure<<T extends core::Object, S extends core::Object>(T) → T, self::C::T, self::C::S>(self::closure#C#foo#function, #context);
- }
- method bar() → dynamic {
- self::C<self::C::T, self::C::S> self = this;
- }
- method baz() → dynamic {
- return MakeClosure<<T extends core::Object, S extends core::Object>() → () → self::C<T, S>, self::C::T, self::C::S>(self::closure#C#baz#function, MakeVector(1));
- }
- static factory •<T extends core::Object, S extends core::Object>() → self::C<self::C::•::T, self::C::•::S> {
- final <T extends core::Object, S extends core::Object>() → self::C<self::C::•::T, self::C::•::S> local = MakeClosure<<T extends core::Object, S extends core::Object>() → self::C<T, S>, self::C::•::T, self::C::•::S>(self::closure#C#function#local, MakeVector(1));
- return local.call();
- }
-}
-static method fn<A extends core::Object>(self::fn::A x) → dynamic {
- <A extends core::Object>(self::fn::A) → core::List<self::fn::A> fn2 = MakeClosure<<A extends core::Object>(A) → core::List<A>, self::fn::A>(self::closure#fn#function, MakeVector(1));
- return fn2.call(x);
-}
-static method main(dynamic arguments) → dynamic {
- core::print(self::C::•<core::String, core::String>().{self::C::foo}(null).call(arguments.first));
- dynamic c = self::C::•<core::int, core::int>().{self::C::baz}().call().call();
- if(!(c is self::C<core::int, core::int>))
- throw "${c} fails type test 'is C<int, int>'";
- if(c is self::C<core::String, core::String>) {
- throw "${c{self::C<core::String, core::String>}} passes type test 'is C<String, String>'";
- }
- core::print(c);
- core::print(self::fn<core::int>(3));
-}
-static method closure#C#foo#function<T extends core::Object, S extends core::Object>(Vector #contextParameter, self::closure#C#foo#function::T x) → self::closure#C#foo#function::T {
- self::closure#C#foo#function::T y = x;
- core::Object z = y;
- self::C<self::closure#C#foo#function::T, self::closure#C#foo#function::S> self = #contextParameter[2];
- return z as self::closure#C#foo#function::T;
-}
-static method closure#C#baz#function#function<T extends core::Object, S extends core::Object>(Vector #contextParameter) → self::C<self::closure#C#baz#function#function::T, self::closure#C#baz#function#function::S> {
- return self::C::•<self::closure#C#baz#function#function::T, self::closure#C#baz#function#function::S>();
-}
-static method closure#C#baz#function<T extends core::Object, S extends core::Object>(Vector #contextParameter) → () → self::C<self::closure#C#baz#function::T, self::closure#C#baz#function::S> {
- return MakeClosure<<T extends core::Object, S extends core::Object>() → self::C<T, S>, self::closure#C#baz#function::T, self::closure#C#baz#function::S>(self::closure#C#baz#function#function, #contextParameter);
-}
-static method closure#C#function#local<T extends core::Object, S extends core::Object>(Vector #contextParameter) → self::C<self::closure#C#function#local::T, self::closure#C#function#local::S> {
- self::C<self::closure#C#function#local::T, self::closure#C#function#local::S> self = new self::C::internal<self::closure#C#function#local::T, self::closure#C#function#local::S>();
- return self;
-}
-static method closure#fn#function<A extends core::Object>(Vector #contextParameter, self::closure#fn#function::A x2) → core::List<self::closure#fn#function::A> {
- core::List<self::closure#fn#function::A> l = <self::closure#fn#function::A>[];
- l.{core::List::add}(x2);
- return l;
-}
diff --git a/pkg/kernel/testcases/reify/closure2_test.dart b/pkg/kernel/testcases/reify/closure2_test.dart
deleted file mode 100644
index e44aef9..0000000
--- a/pkg/kernel/testcases/reify/closure2_test.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library closure2_test;
-
-import 'test_base.dart';
-
-class A<T> {
- fun() => (o) => o is T;
-}
-
-class X {}
-
-class Y {}
-
-main() {
- var tester = new A<X>().fun();
-
- expectTrue(tester(new X()));
- expectFalse(tester(new Y()));
-}
diff --git a/pkg/kernel/testcases/reify/closure2_test.dart.expect b/pkg/kernel/testcases/reify/closure2_test.dart.expect
deleted file mode 100644
index 3c547f5..0000000
--- a/pkg/kernel/testcases/reify/closure2_test.dart.expect
+++ /dev/null
@@ -1,85 +0,0 @@
-library closure2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- method fun() → dynamic {
- return new self::Closure#A#fun#function::•(new typ::Interface::•(self::$declarations.[](1), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0)))), null);
- }
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
-}
-class Closure#A#fun#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type, final mock::Context context) → dynamic
- : self::Closure#A#fun#function::$type = $type, self::Closure#A#fun#function::context = context
- ;
- method call(dynamic o) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#A#fun#function::context};
- return typ::isSubtypeOf(int::type(o), this.$Closure#A#fun#function$T);
- }
- get $Closure#A#fun#function$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
- get runtimeType() → core::Type
- return this.{=self::Closure#A#fun#function::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](17)));
- dec::init(d, 1, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19))], new typ::FunctionType::•(new typ::Interface::•(d.[](19)), new typ::Interface::•(d.[](5)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 2, new typ::Interface::•(d.[](17)));
- dec::init(d, 3, new typ::Interface::•(d.[](17)));
- dec::init(d, 4, new typ::Interface::•(d.[](17)));
- dec::init(d, 5, new typ::Interface::•(d.[](17)));
- dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](21))]);
- dec::init(d, 7, new typ::Interface::•(d.[](22)));
- dec::init(d, 8, new typ::Interface::•(d.[](22)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](23)));
- dec::init(d, 11, new typ::Interface::•(d.[](23)));
- dec::init(d, 12, new typ::Interface::•(d.[](23)));
- dec::init(d, 13, new typ::Interface::•(d.[](23)));
- dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](24))]);
- dec::init(d, 15, new typ::Interface::•(d.[](16)));
- dec::init(d, 16, new typ::Interface::•(d.[](23)));
- dec::init(d, 17, null);
- dec::init(d, 19, new typ::Interface::•(d.[](17)));
- dec::init(d, 20, new typ::Interface::•(d.[](17)));
- dec::init(d, 21, new typ::Interface::•(d.[](17)));
- dec::init(d, 22, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
- dec::init(d, 23, new typ::Interface::•(d.[](17)));
- dec::init(d, 24, new typ::Interface::•(d.[](17)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "Closure#A#fun#function", "X", "Y", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- dynamic tester = new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])).{self::A::fun}();
- tes::expectTrue(tester.call(new self::X::•()));
- tes::expectFalse(tester.call(new self::Y::•()));
-}
diff --git a/pkg/kernel/testcases/reify/closure_test.dart b/pkg/kernel/testcases/reify/closure_test.dart
deleted file mode 100644
index 17206bc..0000000
--- a/pkg/kernel/testcases/reify/closure_test.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library closure_test;
-
-import 'test_base.dart';
-
-class A {}
-
-class B {}
-
-typedef B A2B(A a);
-typedef A B2A(B b);
-
-bar(A a) {
- return null;
-}
-
-B baz(a) {
- return null;
-}
-
-main() {
- B foo(A a) {
- return null;
- }
-
- A qux(B b) {
- return null;
- }
-
- expectTrue(foo is A2B);
- expectTrue(qux is! A2B);
- expectTrue(foo is! B2A);
- expectTrue(qux is B2A);
-
- expectTrue(bar is A2B);
- expectTrue(bar is! B2A);
- expectTrue(baz is A2B);
- expectTrue(baz is! B2A);
-
- var rab = bar;
- var zab = baz;
- expectTrue(rab is A2B);
- expectTrue(rab is! B2A);
- expectTrue(zab is A2B);
- expectTrue(zab is! B2A);
-}
diff --git a/pkg/kernel/testcases/reify/closure_test.dart.expect b/pkg/kernel/testcases/reify/closure_test.dart.expect
deleted file mode 100644
index 0b759eb..0000000
--- a/pkg/kernel/testcases/reify/closure_test.dart.expect
+++ /dev/null
@@ -1,122 +0,0 @@
-library closure_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
-}
-class Closure#main#foo extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#foo::context = context
- ;
- method call(self::A a) → self::B {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#foo::context};
- return null;
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
-}
-class Closure#main#qux extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#qux::context = context
- ;
- method call(self::B b) → self::A {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#qux::context};
- return null;
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
-}
-class Closure#bar extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- constructor •() → dynamic
- ;
- method call(self::A a) → dynamic
- return self::bar(a);
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
-}
-class Closure#baz extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- constructor •() → dynamic
- ;
- method call(dynamic a) → self::B
- return self::baz(a);
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](5));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](20)));
- dec::init(d, 1, new typ::Interface::•(d.[](20)));
- dec::init(d, 2, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), new typ::Interface::•(d.[](1)), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
- dec::init(d, 3, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), new typ::Interface::•(d.[](0)), 0, <dynamic>[new typ::Interface::•(d.[](1))]));
- dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), const typ::Dynamic::•(), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
- dec::init(d, 5, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), new typ::Interface::•(d.[](1)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 6, new typ::Interface::•(d.[](20)));
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](23))]);
- dec::init(d, 10, new typ::Interface::•(d.[](24)));
- dec::init(d, 11, new typ::Interface::•(d.[](24)));
- dec::init(d, 12, new typ::Interface::•(d.[](20)));
- dec::init(d, 13, new typ::Interface::•(d.[](25)));
- dec::init(d, 14, new typ::Interface::•(d.[](25)));
- dec::init(d, 15, new typ::Interface::•(d.[](25)));
- dec::init(d, 16, new typ::Interface::•(d.[](25)));
- dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](26))]);
- dec::init(d, 18, new typ::Interface::•(d.[](19)));
- dec::init(d, 19, new typ::Interface::•(d.[](25)));
- dec::init(d, 20, null);
- dec::init(d, 22, new typ::Interface::•(d.[](20)));
- dec::init(d, 23, new typ::Interface::•(d.[](20)));
- dec::init(d, 24, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](24))])]);
- dec::init(d, 25, new typ::Interface::•(d.[](20)));
- dec::init(d, 26, new typ::Interface::•(d.[](20)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Closure#main#foo", "Closure#main#qux", "Closure#bar", "Closure#baz", "Function", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method bar(self::A a) → dynamic {
- return null;
-}
-static method baz(dynamic a) → self::B {
- return null;
-}
-static method main() → dynamic {
- final (self::A) → self::B foo = new self::Closure#main#foo::•(null);
- final (self::B) → self::A qux = new self::Closure#main#qux::•(null);
- tes::expectTrue(typ::isSubtypeOf(int::type(foo), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(qux), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(foo), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(typ::isSubtypeOf(int::type(qux), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(typ::isSubtypeOf(int::type(new self::Closure#bar::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(new self::Closure#bar::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(typ::isSubtypeOf(int::type(new self::Closure#baz::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(new self::Closure#baz::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- (self::A) → dynamic rab = new self::Closure#bar::•();
- (dynamic) → self::B zab = new self::Closure#baz::•();
- tes::expectTrue(typ::isSubtypeOf(int::type(rab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(rab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(typ::isSubtypeOf(int::type(zab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(zab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-}
diff --git a/pkg/kernel/testcases/reify/factories_test.dart b/pkg/kernel/testcases/reify/factories_test.dart
deleted file mode 100644
index 805df85..0000000
--- a/pkg/kernel/testcases/reify/factories_test.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library factories_test;
-
-import 'test_base.dart';
-
-class A<T> {
- factory A() {
- return new B<T>();
- }
-
- factory A.named() {
- return new A<T>.internal();
- }
-
- factory A.forward() = A<T>.internal;
-
- A.internal();
-}
-
-class B<T> extends A<T> {
- B() : super.internal();
-}
-
-class X {}
-
-class Y {}
-
-main() {
- expectTrue(new A<X>.named() is A<X>);
- expectTrue(new A<X>.named() is! A<Y>);
- expectTrue(new A<X>.forward() is A<X>);
- expectTrue(new A<X>.forward() is! A<Y>);
- expectTrue(new A<X>() is B<X>);
- expectTrue(new A<X>() is! B<Y>);
- expectTrue(new A<X>.named() is! B<X>);
- expectTrue(new A<X>.forward() is! B<X>);
-}
diff --git a/pkg/kernel/testcases/reify/factories_test.dart.expect b/pkg/kernel/testcases/reify/factories_test.dart.expect
deleted file mode 100644
index de736e8..0000000
--- a/pkg/kernel/testcases/reify/factories_test.dart.expect
+++ /dev/null
@@ -1,97 +0,0 @@
-library factories_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor internal(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- static factory •(typ::ReifiedType $type) → self::A {
- return new self::B::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](0))).[](0)]));
- }
- static factory named(typ::ReifiedType $type) → self::A {
- return new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](0))).[](0)]));
- }
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get $is$A() → core::bool
- return true;
- get $is$B() → core::bool
- return false;
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
- constructor •(typ::ReifiedType $type) → void
- : super self::A::internal($type)
- ;
- get $B$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
- get $is$A() → core::bool
- return true;
- get $is$B() → core::bool
- return true;
-}
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$A() → core::bool
- return false;
- get $is$B() → core::bool
- return false;
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
- get $is$A() → core::bool
- return false;
- get $is$B() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](17)));
- dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[d.[](1).variables.[](0)]));
- dec::init(d, 2, new typ::Interface::•(d.[](17)));
- dec::init(d, 3, new typ::Interface::•(d.[](17)));
- dec::init(d, 4, new typ::Interface::•(d.[](17)));
- dec::init(d, 5, new typ::Interface::•(d.[](17)));
- dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](20))]);
- dec::init(d, 7, new typ::Interface::•(d.[](21)));
- dec::init(d, 8, new typ::Interface::•(d.[](21)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](22)));
- dec::init(d, 11, new typ::Interface::•(d.[](22)));
- dec::init(d, 12, new typ::Interface::•(d.[](22)));
- dec::init(d, 13, new typ::Interface::•(d.[](22)));
- dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](23))]);
- dec::init(d, 15, new typ::Interface::•(d.[](16)));
- dec::init(d, 16, new typ::Interface::•(d.[](22)));
- dec::init(d, 17, null);
- dec::init(d, 19, new typ::Interface::•(d.[](17)));
- dec::init(d, 20, new typ::Interface::•(d.[](17)));
- dec::init(d, 21, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](21))])]);
- dec::init(d, 22, new typ::Interface::•(d.[](17)));
- dec::init(d, 23, new typ::Interface::•(d.[](17)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "X", "Y", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- tes::expectTrue(let dynamic #t1 = self::A::named(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t1.$type, #t2)));
- tes::expectTrue(!(let dynamic #t3 = self::A::named(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t3 is int::HasRuntimeTypeGetter && #t3.$is$A && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](3))]) in typ::isSubtypeOf(#t3.$type, #t4))));
- tes::expectTrue(let dynamic #t5 = new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t5.$type, #t6)));
- tes::expectTrue(!(let dynamic #t7 = new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t7 is int::HasRuntimeTypeGetter && #t7.$is$A && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](3))]) in typ::isSubtypeOf(#t7.$type, #t8))));
- tes::expectTrue(let dynamic #t9 = self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t9 is int::HasRuntimeTypeGetter && #t9.$is$B && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t9.$type, #t10)));
- tes::expectTrue(!(let dynamic #t11 = self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t11 is int::HasRuntimeTypeGetter && #t11.$is$B && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](3))]) in typ::isSubtypeOf(#t11.$type, #t12))));
- tes::expectTrue(!(let dynamic #t13 = self::A::named(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t13 is int::HasRuntimeTypeGetter && #t13.$is$B && (let dynamic #t14 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t13.$type, #t14))));
- tes::expectTrue(!(let dynamic #t15 = new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t15 is int::HasRuntimeTypeGetter && #t15.$is$B && (let dynamic #t16 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t15.$type, #t16))));
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer2_test.dart b/pkg/kernel/testcases/reify/field_initializer2_test.dart
deleted file mode 100644
index 47db808..0000000
--- a/pkg/kernel/testcases/reify/field_initializer2_test.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library field_initializer2_test;
-
-import 'test_base.dart';
-
-class A<T> {}
-
-class B<T> {
- var x = new A<T>();
- var y;
- B() : y = new A<T>();
-}
-
-main() {
- var b = new B<A>();
- expectTrue(b.x is A<A>);
- expectTrue(b.y is A<A>);
-
- expectFalse(b.x is A<B>);
- expectFalse(b.y is A<B>);
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer2_test.dart.expect b/pkg/kernel/testcases/reify/field_initializer2_test.dart.expect
deleted file mode 100644
index 93f4456..0000000
--- a/pkg/kernel/testcases/reify/field_initializer2_test.dart.expect
+++ /dev/null
@@ -1,70 +0,0 @@
-library field_initializer2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get $is$A() → core::bool
- return true;
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
- field self::A x;
- field dynamic y;
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::B::x = self::B::$init$x($type), self::B::$type = $type, self::B::y = new self::A::•(new typ::Interface::•(self::$declarations.[](0), typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](1))))), super core::Object::•()
- ;
- set x$cc(self::A x_) → dynamic {
- this.{=self::B::x} = x_ as self::A;
- }
- get $B$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
- get $is$A() → core::bool
- return false;
- get runtimeType() → core::Type
- return this.{=self::B::$type};
- static method $init$x(dynamic $type) → dynamic
- return new self::A::•(new typ::Interface::•(self::$declarations.[](0), typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](1)))));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](15)));
- dec::init(d, 1, new typ::Interface::•(d.[](15)));
- dec::init(d, 2, new typ::Interface::•(d.[](15)));
- dec::init(d, 3, new typ::Interface::•(d.[](15)));
- dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
- dec::init(d, 5, new typ::Interface::•(d.[](19)));
- dec::init(d, 6, new typ::Interface::•(d.[](19)));
- dec::init(d, 7, new typ::Interface::•(d.[](15)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)));
- dec::init(d, 10, new typ::Interface::•(d.[](20)));
- dec::init(d, 11, new typ::Interface::•(d.[](20)));
- dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
- dec::init(d, 13, new typ::Interface::•(d.[](14)));
- dec::init(d, 14, new typ::Interface::•(d.[](20)));
- dec::init(d, 15, null);
- dec::init(d, 17, new typ::Interface::•(d.[](15)));
- dec::init(d, 18, new typ::Interface::•(d.[](15)));
- dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
- dec::init(d, 20, new typ::Interface::•(d.[](15)));
- dec::init(d, 21, new typ::Interface::•(d.[](15)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::B b = new self::B::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])]));
- tes::expectTrue(let dynamic #t1 = b.{self::B::x} in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t1.$type, #t2)));
- tes::expectTrue(let dynamic #t3 = b.{self::B::y} in #t3 is int::HasRuntimeTypeGetter && #t3.$is$A && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t3.$type, #t4)));
- tes::expectFalse(let dynamic #t5 = b.{self::B::x} in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t5.$type, #t6)));
- tes::expectFalse(let dynamic #t7 = b.{self::B::y} in #t7 is int::HasRuntimeTypeGetter && #t7.$is$A && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t7.$type, #t8)));
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer_test.dart b/pkg/kernel/testcases/reify/field_initializer_test.dart
deleted file mode 100644
index d1e4c9c..0000000
--- a/pkg/kernel/testcases/reify/field_initializer_test.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library field_initializer_test;
-
-import 'test_base.dart';
-
-p(x) {
- write(x);
- return x;
-}
-
-class A<T> {
- var a1 = p("a1");
- var a2;
-
- A() : a2 = p("a2") {
- p("A");
- }
-}
-
-class B<T> extends A<T> {
- var b1 = p("b1");
- var b2 = p("b2");
- var b3;
- var b4;
-
- B()
- : b3 = p("b3"),
- b4 = p("b4"),
- super() {
- p("B");
- }
-}
-
-main() {
- var b = new B();
- expectOutput("b1\nb2\nb3\nb4\na1\na2\nA\nB");
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer_test.dart.expect b/pkg/kernel/testcases/reify/field_initializer_test.dart.expect
deleted file mode 100644
index 8490bf3..0000000
--- a/pkg/kernel/testcases/reify/field_initializer_test.dart.expect
+++ /dev/null
@@ -1,65 +0,0 @@
-library field_initializer_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- field dynamic a1 = self::p("a1");
- field dynamic a2;
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, self::A::a2 = self::p("a2"), super core::Object::•() {
- self::p("A");
- }
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
- field dynamic b1 = self::p("b1");
- field dynamic b2 = self::p("b2");
- field dynamic b3;
- field dynamic b4;
- constructor •(typ::ReifiedType $type) → void
- : self::B::b3 = self::p("b3"), self::B::b4 = self::p("b4"), super self::A::•($type) {
- self::p("B");
- }
- get $B$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](15)));
- dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[d.[](1).variables.[](0)]));
- dec::init(d, 2, new typ::Interface::•(d.[](15)));
- dec::init(d, 3, new typ::Interface::•(d.[](15)));
- dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
- dec::init(d, 5, new typ::Interface::•(d.[](19)));
- dec::init(d, 6, new typ::Interface::•(d.[](19)));
- dec::init(d, 7, new typ::Interface::•(d.[](15)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)));
- dec::init(d, 10, new typ::Interface::•(d.[](20)));
- dec::init(d, 11, new typ::Interface::•(d.[](20)));
- dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
- dec::init(d, 13, new typ::Interface::•(d.[](14)));
- dec::init(d, 14, new typ::Interface::•(d.[](20)));
- dec::init(d, 15, null);
- dec::init(d, 17, new typ::Interface::•(d.[](15)));
- dec::init(d, 18, new typ::Interface::•(d.[](15)));
- dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
- dec::init(d, 20, new typ::Interface::•(d.[](15)));
- dec::init(d, 21, new typ::Interface::•(d.[](15)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method p(dynamic x) → dynamic {
- tes::write(x);
- return x;
-}
-static method main() → dynamic {
- self::B b = new self::B::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[const typ::Dynamic::•()]));
- tes::expectOutput("b1\nb2\nb3\nb4\na1\na2\nA\nB");
-}
diff --git a/pkg/kernel/testcases/reify/function_type_test.dart b/pkg/kernel/testcases/reify/function_type_test.dart
deleted file mode 100644
index b67b743..0000000
--- a/pkg/kernel/testcases/reify/function_type_test.dart
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library function_type_test;
-
-import 'test_base.dart';
-
-class A {}
-
-class B extends A {}
-
-class C extends A {}
-
-class D implements Function {
- B call(A a) {
- return null;
- }
-}
-
-class ER0P1 {
- void call([A a]) {}
-}
-
-class ER1P0 {
- void call(A a) {}
-}
-
-class ER1P1 {
- void call(A a, [B b]) {}
-}
-
-class ER1P2 {
- void call(A a, [B b, C c]) {}
-}
-
-class ER2P1 {
- void call(A a, B b, [C c]) {}
-}
-
-class ER0N1 {
- void call({A a}) {}
-}
-
-class ER1N0 {
- void call(A a) {}
-}
-
-class ER1N1 {
- void call(A a, {B b}) {}
-}
-
-class ER1N2 {
- void call(A a, {B b, C c}) {}
-}
-
-class ER2N1 {
- void call(A a, B b, {C c}) {}
-}
-
-class ER0N8 {
- void call({kE, ii, oP, Ij, pA, zD, aZ, UU}) {}
-}
-
-C foo(A a) {
- return null;
-}
-
-typedef B A2B(A a);
-
-typedef C C2C(C c);
-
-typedef void R0P1([A a]);
-typedef void R1P0(A a);
-typedef void R1P1(A a, [B b]);
-typedef void R1P2(A a, [B b, C c]);
-typedef void R2P1(A a, B b, [C c]);
-
-typedef void R0N1({A a});
-typedef void R1N0(A a);
-typedef void R1N1(A a, {B b});
-typedef void R1N2(A a, {B b, C c});
-typedef void R2N1(A a, B b, {C c});
-
-typedef void R0N8({aZ, oP, Ij, kE, pA, zD, UU, ii});
-
-void test(x) {
- write(x is Function);
- write(x is A2B);
- write(x is C2C);
-
- write(x is R0P1);
- write(x is R1P0);
- write(x is R1P1);
- write(x is R1P2);
- write(x is R2P1);
-
- write(x is R0N1);
- write(x is R1N0);
- write(x is R1N1);
- write(x is R1N2);
- write(x is R2N1);
-}
-
-main() {
- test(new D());
- for (var c in [
- new ER0P1(),
- new ER1P0(),
- new ER1P1(),
- new ER1P2(),
- new ER2P1(),
- new ER0N1(),
- new ER1N0(),
- new ER1N1(),
- new ER1N2(),
- new ER2N1()
- ]) {
- test(c);
- }
-
- expectOutput("""
-true
-true
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-true
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-true
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-true
-true
-true
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-false
-false
-true
-false
-false
-false
-false
-false
-true
-false
-false
-false
-false
-false
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-true
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-true
-true
-false
-true
-false
-false
-false
-false
-false
-false
-false
-false
-false
-false
-false
-true""");
-}
diff --git a/pkg/kernel/testcases/reify/function_type_test.dart.expect b/pkg/kernel/testcases/reify/function_type_test.dart.expect
deleted file mode 100644
index c953f80..0000000
--- a/pkg/kernel/testcases/reify/function_type_test.dart.expect
+++ /dev/null
@@ -1,223 +0,0 @@
-library function_type_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$Function() → core::bool
- return false;
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::A::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$Function() → core::bool
- return false;
-}
-class C extends self::A implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::A::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$Function() → core::bool
- return false;
-}
-class D extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a) → self::B {
- return null;
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
- get $is$Function() → core::bool
- return true;
-}
-class ER0P1 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call([self::A a]) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$Function() → core::bool
- return false;
-}
-class ER1P0 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](5));
- get $is$Function() → core::bool
- return false;
-}
-class ER1P1 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a, [self::B b]) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](6));
- get $is$Function() → core::bool
- return false;
-}
-class ER1P2 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a, [self::B b, self::C c]) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](7));
- get $is$Function() → core::bool
- return false;
-}
-class ER2P1 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a, self::B b, [self::C c]) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](8));
- get $is$Function() → core::bool
- return false;
-}
-class ER0N1 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call({self::A a}) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](9));
- get $is$Function() → core::bool
- return false;
-}
-class ER1N0 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](10));
- get $is$Function() → core::bool
- return false;
-}
-class ER1N1 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a, {self::B b}) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](11));
- get $is$Function() → core::bool
- return false;
-}
-class ER1N2 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a, {self::B b, self::C c}) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](12));
- get $is$Function() → core::bool
- return false;
-}
-class ER2N1 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call(self::A a, self::B b, {self::C c}) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](13));
- get $is$Function() → core::bool
- return false;
-}
-class ER0N8 extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method call({dynamic kE, dynamic ii, dynamic oP, dynamic Ij, dynamic pA, dynamic zD, dynamic aZ, dynamic UU}) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](14));
- get $is$Function() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](17)));
- dec::init(d, 1, new typ::Interface::•(d.[](0)));
- dec::init(d, 2, new typ::Interface::•(d.[](0)));
- dec::init(d, 3, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](15))], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Interface::•(d.[](1)), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
- dec::init(d, 4, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(d.[](0))]));
- dec::init(d, 5, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
- dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1))]));
- dec::init(d, 7, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 4, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1)), new typ::Interface::•(d.[](2))]));
- dec::init(d, 8, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1)), new typ::Interface::•(d.[](2))]));
- dec::init(d, 9, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 3, <dynamic>["a", new typ::Interface::•(d.[](0))]));
- dec::init(d, 10, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
- dec::init(d, 11, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(d.[](0)), "b", new typ::Interface::•(d.[](1))]));
- dec::init(d, 12, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 5, <dynamic>[new typ::Interface::•(d.[](0)), "b", new typ::Interface::•(d.[](1)), "c", new typ::Interface::•(d.[](2))]));
- dec::init(d, 13, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1)), "c", new typ::Interface::•(d.[](2))]));
- dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 17, <dynamic>["kE", const typ::Dynamic::•(), "ii", const typ::Dynamic::•(), "oP", const typ::Dynamic::•(), "Ij", const typ::Dynamic::•(), "pA", const typ::Dynamic::•(), "zD", const typ::Dynamic::•(), "aZ", const typ::Dynamic::•(), "UU", const typ::Dynamic::•()]));
- dec::init(d, 15, new typ::Interface::•(d.[](17)));
- dec::init(d, 16, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](32), <dynamic>[d.[](16).variables.[](0)])]);
- dec::init(d, 17, null);
- dec::init(d, 18, new typ::Interface::•(d.[](17)));
- dec::init(d, 19, new typ::Interface::•(d.[](17)));
- dec::init(d, 20, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](33), <dynamic>[new typ::Interface::•(d.[](20))]), new typ::Interface::•(d.[](34))]);
- dec::init(d, 21, new typ::Interface::•(d.[](35)));
- dec::init(d, 22, new typ::Interface::•(d.[](35)));
- dec::init(d, 23, new typ::Interface::•(d.[](17)));
- dec::init(d, 24, new typ::Interface::•(d.[](36)));
- dec::init(d, 25, new typ::Interface::•(d.[](36)));
- dec::init(d, 26, new typ::Interface::•(d.[](36)));
- dec::init(d, 27, new typ::Interface::•(d.[](36)));
- dec::init(d, 28, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](37))]);
- dec::init(d, 29, new typ::Interface::•(d.[](30)));
- dec::init(d, 30, new typ::Interface::•(d.[](36)));
- dec::init(d, 32, new typ::Interface::•(d.[](38), <dynamic>[d.[](32).variables.[](0)]));
- dec::init(d, 33, new typ::Interface::•(d.[](17)));
- dec::init(d, 34, new typ::Interface::•(d.[](17)));
- dec::init(d, 35, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](33), <dynamic>[new typ::Interface::•(d.[](35))])]);
- dec::init(d, 36, new typ::Interface::•(d.[](17)));
- dec::init(d, 37, new typ::Interface::•(d.[](17)));
- dec::init(d, 38, new typ::Interface::•(d.[](17)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "D", "ER0P1", "ER1P0", "ER1P1", "ER1P2", "ER2P1", "ER0N1", "ER1N0", "ER1N1", "ER1N2", "ER2N1", "ER0N8", "Function", "List", "Object", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method foo(self::A a) → self::C {
- return null;
-}
-static method test(dynamic x) → void {
- tes::write(typ::isSubtypeOf(int::type(x), new typ::Interface::•(self::$declarations.[](15))));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Interface::•(self::$declarations.[](2)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](2))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 4, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 3, <dynamic>["a", new typ::Interface::•(self::$declarations.[](0))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), "b", new typ::Interface::•(self::$declarations.[](1))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 5, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), "b", new typ::Interface::•(self::$declarations.[](1)), "c", new typ::Interface::•(self::$declarations.[](2))])));
- tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), "c", new typ::Interface::•(self::$declarations.[](2))])));
-}
-static method main() → dynamic {
- self::test(new self::D::•());
- for (core::Object c in int::attachType(<core::Object>[new self::ER0P1::•(), new self::ER1P0::•(), new self::ER1P1::•(), new self::ER1P2::•(), new self::ER2P1::•(), new self::ER0N1::•(), new self::ER1N0::•(), new self::ER1N1::•(), new self::ER1N2::•(), new self::ER2N1::•()], new typ::Interface::•(self::$declarations.[](16), <dynamic>[new typ::Interface::•(self::$declarations.[](17))]))) {
- self::test(c);
- }
- tes::expectOutput("true\ntrue\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\ntrue\ntrue\ntrue\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart b/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart
deleted file mode 100644
index 4007e5c..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that a dynamic call to a generic function checks the type argument
-// against its bound.
-
-library generic_methods_bounds_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
- void fun<T extends A>(T t) {}
-}
-
-main() {
- dynamic obj = new C();
- expectThrows(() => obj.fun<B>(new B()), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart.expect
deleted file mode 100644
index 9d9796a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart.expect
+++ /dev/null
@@ -1,105 +0,0 @@
-library generic_methods_bounds_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$TypeError() → core::bool
- return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$TypeError() → core::bool
- return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method fun<T extends self::A>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → void {}
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$TypeError() → core::bool
- return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function::context = context
- ;
- method call() → dynamic {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function::context};
- return #contextParameter.[](0).fun(new self::B::•(), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
- get $is$TypeError() → core::bool
- return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#1::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](5)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$TypeError() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](20)));
- dec::init(d, 1, new typ::Interface::•(d.[](20)));
- dec::init(d, 2, new typ::Interface::•(d.[](20)));
- dec::init(d, 3, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[]));
- dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), new typ::Interface::•(d.[](8)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 5, new typ::Interface::•(d.[](23)));
- dec::init(d, 6, new typ::Interface::•(d.[](20)));
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](25))]);
- dec::init(d, 10, new typ::Interface::•(d.[](26)));
- dec::init(d, 11, new typ::Interface::•(d.[](26)));
- dec::init(d, 12, new typ::Interface::•(d.[](20)));
- dec::init(d, 13, new typ::Interface::•(d.[](27)));
- dec::init(d, 14, new typ::Interface::•(d.[](27)));
- dec::init(d, 15, new typ::Interface::•(d.[](27)));
- dec::init(d, 16, new typ::Interface::•(d.[](27)));
- dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](28))]);
- dec::init(d, 18, new typ::Interface::•(d.[](19)));
- dec::init(d, 19, new typ::Interface::•(d.[](27)));
- dec::init(d, 20, null);
- dec::init(d, 22, new typ::Interface::•(d.[](20)));
- dec::init(d, 23, new typ::Interface::•(d.[](27)));
- dec::init(d, 24, new typ::Interface::•(d.[](20)));
- dec::init(d, 25, new typ::Interface::•(d.[](20)));
- dec::init(d, 26, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](26))])]);
- dec::init(d, 27, new typ::Interface::•(d.[](20)));
- dec::init(d, 28, new typ::Interface::•(d.[](20)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "Closure#main#function", "Closure#main#function#1", "TypeError", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "AssertionError", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- final mock::Context #context = int::attachType(new mock::Context::•(1), new typ::Interface::•(self::$declarations.[](6)));
- #context.[]=(0, new self::C::•());
- tes::expectThrows(new self::Closure#main#function::•(#context), new self::Closure#main#function#1::•(#context));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_closure_test.dart b/pkg/kernel/testcases/reify/generic_methods_closure_test.dart
deleted file mode 100644
index 0304499..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_closure_test.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that a generic closure is correctly constructed.
-
-library generic_methods_closure_test;
-
-import "test_base.dart";
-
-class A {}
-
-class I<T> {}
-
-class B extends I<B> {}
-
-void fun<T>(List<T> list) {
- var helper1 = <S>(List<S> list) {
- if (list.length > 0) {
- expectTrue(list[0] is S);
- }
- expectTrue(list is List<S>);
- expectTrue(list is List<T>);
- };
-
- void helper2<S>(List<S> list) {
- if (list.length > 0) {
- expectTrue(list[0] is S);
- }
- expectTrue(list is List<S>);
- expectTrue(list is List<T>);
- }
-
- helper1<T>(list);
- helper2<T>(list);
-}
-
-main() {
- List<B> list = <B>[new B()];
- fun<B>(list);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart
deleted file mode 100644
index 92ec7bd..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that if the type of a parameter of a generic method depends on type
-// parameter, the type of the passed argument is checked at runtime if the
-// receiver is dynamic, and an exception is thrown.
-
-library generic_methods_dynamic_dependent_type_error_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
- List<T> bar<T>(Iterable<T> t) => <T>[t.first];
-}
-
-main() {
- C c = new C();
- dynamic obj = c;
-
- expectThrows(() => obj.bar<A>(<B>[new B()]), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart.expect
deleted file mode 100644
index d1d47ac..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart.expect
+++ /dev/null
@@ -1,111 +0,0 @@
-library generic_methods_dynamic_dependent_type_error_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$TypeError() → core::bool
- return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$TypeError() → core::bool
- return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method bar<T extends core::Object>(core::Iterable<self::C::bar::T> t, {core::List<typ::ReifiedType> $typeParameters}) → core::List<self::C::bar::T> {
- return int::attachType(<dynamic>[t.{core::Iterable::first}], new typ::Interface::•(self::$declarations.[](3), <dynamic>[this.$C$T]));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$TypeError() → core::bool
- return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function::context = context
- ;
- method call() → dynamic {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function::context};
- return #contextParameter.[](0).bar(int::attachType(<self::B>[new self::B::•()], new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]);
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$TypeError() → core::bool
- return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#1::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](6)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](5));
- get $is$TypeError() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](21)));
- dec::init(d, 1, new typ::Interface::•(d.[](21)));
- dec::init(d, 2, new typ::Interface::•(d.[](21)));
- dec::init(d, 3, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](23), <dynamic>[d.[](3).variables.[](0)])]);
- dec::init(d, 4, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](24))], new typ::FunctionType::•(new typ::Interface::•(d.[](24)), const typ::Dynamic::•(), 0, <dynamic>[]));
- dec::init(d, 5, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](24))], new typ::FunctionType::•(new typ::Interface::•(d.[](24)), new typ::Interface::•(d.[](9)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 6, new typ::Interface::•(d.[](25)));
- dec::init(d, 7, new typ::Interface::•(d.[](21)));
- dec::init(d, 8, new typ::Interface::•(d.[](21)));
- dec::init(d, 9, new typ::Interface::•(d.[](21)));
- dec::init(d, 10, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](26), <dynamic>[new typ::Interface::•(d.[](10))]), new typ::Interface::•(d.[](27))]);
- dec::init(d, 11, new typ::Interface::•(d.[](28)));
- dec::init(d, 12, new typ::Interface::•(d.[](28)));
- dec::init(d, 13, new typ::Interface::•(d.[](21)));
- dec::init(d, 14, new typ::Interface::•(d.[](29)));
- dec::init(d, 15, new typ::Interface::•(d.[](29)));
- dec::init(d, 16, new typ::Interface::•(d.[](29)));
- dec::init(d, 17, new typ::Interface::•(d.[](29)));
- dec::init(d, 18, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](30))]);
- dec::init(d, 19, new typ::Interface::•(d.[](20)));
- dec::init(d, 20, new typ::Interface::•(d.[](29)));
- dec::init(d, 21, null);
- dec::init(d, 23, new typ::Interface::•(d.[](31), <dynamic>[d.[](23).variables.[](0)]));
- dec::init(d, 24, new typ::Interface::•(d.[](21)));
- dec::init(d, 25, new typ::Interface::•(d.[](29)));
- dec::init(d, 26, new typ::Interface::•(d.[](21)));
- dec::init(d, 27, new typ::Interface::•(d.[](21)));
- dec::init(d, 28, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](26), <dynamic>[new typ::Interface::•(d.[](28))])]);
- dec::init(d, 29, new typ::Interface::•(d.[](21)));
- dec::init(d, 30, new typ::Interface::•(d.[](21)));
- dec::init(d, 31, new typ::Interface::•(d.[](21)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "List", "Closure#main#function", "Closure#main#function#1", "TypeError", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Function", "AssertionError", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1]));
-static method main() → dynamic {
- self::C c = new self::C::•();
- final mock::Context #context = int::attachType(new mock::Context::•(1), new typ::Interface::•(self::$declarations.[](7)));
- #context.[]=(0, c);
- tes::expectThrows(new self::Closure#main#function::•(#context), new self::Closure#main#function#1::•(#context));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart
deleted file mode 100644
index 0b47476..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that if the type of a parameter of a generic method is a type parameter,
-// the type of the passed argument is checked at runtime if the receiver is
-// dynamic, and an exception is thrown.
-
-library generic_methods_dynamic_simple_error_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
- T foo<T>(T t) => t;
-}
-
-main() {
- B b = new B();
- C c = new C();
- dynamic obj = c;
-
- expectThrows(() => obj.foo<A>(b), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart.expect
deleted file mode 100644
index 91f35f8..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart.expect
+++ /dev/null
@@ -1,109 +0,0 @@
-library generic_methods_dynamic_simple_error_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$TypeError() → core::bool
- return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$TypeError() → core::bool
- return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method foo<T extends core::Object>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
- return t;
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$TypeError() → core::bool
- return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function::context = context
- ;
- method call() → dynamic {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function::context};
- return #contextParameter.[](1).foo(#contextParameter.[](0), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]);
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
- get $is$TypeError() → core::bool
- return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#1::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](5)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$TypeError() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](20)));
- dec::init(d, 1, new typ::Interface::•(d.[](20)));
- dec::init(d, 2, new typ::Interface::•(d.[](20)));
- dec::init(d, 3, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[]));
- dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), new typ::Interface::•(d.[](8)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 5, new typ::Interface::•(d.[](23)));
- dec::init(d, 6, new typ::Interface::•(d.[](20)));
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](25))]);
- dec::init(d, 10, new typ::Interface::•(d.[](26)));
- dec::init(d, 11, new typ::Interface::•(d.[](26)));
- dec::init(d, 12, new typ::Interface::•(d.[](20)));
- dec::init(d, 13, new typ::Interface::•(d.[](27)));
- dec::init(d, 14, new typ::Interface::•(d.[](27)));
- dec::init(d, 15, new typ::Interface::•(d.[](27)));
- dec::init(d, 16, new typ::Interface::•(d.[](27)));
- dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](28))]);
- dec::init(d, 18, new typ::Interface::•(d.[](19)));
- dec::init(d, 19, new typ::Interface::•(d.[](27)));
- dec::init(d, 20, null);
- dec::init(d, 22, new typ::Interface::•(d.[](20)));
- dec::init(d, 23, new typ::Interface::•(d.[](27)));
- dec::init(d, 24, new typ::Interface::•(d.[](20)));
- dec::init(d, 25, new typ::Interface::•(d.[](20)));
- dec::init(d, 26, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](26))])]);
- dec::init(d, 27, new typ::Interface::•(d.[](20)));
- dec::init(d, 28, new typ::Interface::•(d.[](20)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "Closure#main#function", "Closure#main#function#1", "TypeError", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "AssertionError", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- final mock::Context #context = int::attachType(new mock::Context::•(2), new typ::Interface::•(self::$declarations.[](6)));
- #context.[]=(0, new self::B::•());
- self::C c = new self::C::•();
- #context.[]=(1, c);
- tes::expectThrows(new self::Closure#main#function::•(#context), new self::Closure#main#function#1::•(#context));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart b/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart
deleted file mode 100644
index 33f8b90..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that if the type of a parameter of a generic method depends on a type
-// parameter, the type of the passed argument is checked at runtime if the
-// receiver is dynamic. The checks should pass if the variables are declared
-// correctly.
-
-library generic_methods_dynamic_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
- T foo<T>(T t) => t;
- List<T> bar<T>(Iterable<T> t) => <T>[t.first];
-}
-
-main() {
- B b = new B();
- C c = new C();
- dynamic obj = c;
-
- expectTrue(c.foo<B>(b) == b);
- expectTrue(obj.foo<B>(b) == b);
-
- dynamic x = c.bar<B>(<B>[new B()]);
- expectTrue(x is List<B>);
- expectTrue(x.length == 1);
-
- dynamic y = obj.bar<B>(<B>[new B()]);
- expectTrue(y is List<B>);
- expectTrue(y.length == 1);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart.expect
deleted file mode 100644
index cca42f8..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart.expect
+++ /dev/null
@@ -1,82 +0,0 @@
-library generic_methods_dynamic_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$List() → core::bool
- return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$List() → core::bool
- return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method foo<T extends core::Object>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
- return t;
- }
- method bar<T extends core::Object>(core::Iterable<self::C::bar::T> t, {core::List<typ::ReifiedType> $typeParameters}) → core::List<self::C::bar::T> {
- return int::attachType(<dynamic>[t.{core::Iterable::first}], new typ::Interface::•(self::$declarations.[](3), <dynamic>[this.$C$T]));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$List() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](17)));
- dec::init(d, 1, new typ::Interface::•(d.[](17)));
- dec::init(d, 2, new typ::Interface::•(d.[](17)));
- dec::init(d, 3, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[d.[](3).variables.[](0)])]);
- dec::init(d, 4, new typ::Interface::•(d.[](17)));
- dec::init(d, 5, new typ::Interface::•(d.[](17)));
- dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](21))]);
- dec::init(d, 7, new typ::Interface::•(d.[](22)));
- dec::init(d, 8, new typ::Interface::•(d.[](22)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](23)));
- dec::init(d, 11, new typ::Interface::•(d.[](23)));
- dec::init(d, 12, new typ::Interface::•(d.[](23)));
- dec::init(d, 13, new typ::Interface::•(d.[](23)));
- dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](24))]);
- dec::init(d, 15, new typ::Interface::•(d.[](16)));
- dec::init(d, 16, new typ::Interface::•(d.[](23)));
- dec::init(d, 17, null);
- dec::init(d, 19, new typ::Interface::•(d.[](25), <dynamic>[d.[](19).variables.[](0)]));
- dec::init(d, 20, new typ::Interface::•(d.[](17)));
- dec::init(d, 21, new typ::Interface::•(d.[](17)));
- dec::init(d, 22, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
- dec::init(d, 23, new typ::Interface::•(d.[](17)));
- dec::init(d, 24, new typ::Interface::•(d.[](17)));
- dec::init(d, 25, new typ::Interface::•(d.[](17)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "List", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method main() → dynamic {
- self::B b = new self::B::•();
- self::C c = new self::C::•();
- dynamic obj = c;
- tes::expectTrue(c.{self::C::foo}(b, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::Object::==}(b));
- tes::expectTrue(obj.foo(b, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).==(b));
- dynamic x = c.{self::C::bar}(int::attachType(<self::B>[new self::B::•()], new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
- tes::expectTrue(typ::isSubtypeOf(int::type(x), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(x.length.==(1));
- dynamic y = obj.bar(int::attachType(<self::B>[new self::B::•()], new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
- tes::expectTrue(typ::isSubtypeOf(int::type(y), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(y.length.==(1));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_generic_class_tearoff_test.dart b/pkg/kernel/testcases/reify/generic_methods_generic_class_tearoff_test.dart
deleted file mode 100644
index 377af7b..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_generic_class_tearoff_test.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that a torn off method of a generic class is not a generic method,
-// and that it is correctly specialized.
-
-library generic_methods_generic_class_tearoff_test;
-
-import "test_base.dart";
-
-class A<T> {
- T fun(T t) => t;
-}
-
-typedef Int2Int = int Function(int);
-typedef String2String = String Function(String);
-typedef Object2Object = Object Function(Object);
-typedef GenericMethod = T Function<T>(T);
-
-main() {
- A<int> x = new A<int>();
- var f = x.fun; // The type of f should be 'int Function(Object)'.
- A<String> y = new A<String>();
- var g = y.fun; // The type of g should be 'String Function(Object)'.
- A z = new A();
- var h = z.fun; // The type of h should be 'dynamic Function(Object)'.
-
- expectTrue(f is Int2Int);
- expectTrue(f is! String2String);
- expectTrue(f is Object2Object);
- expectTrue(f is! GenericMethod);
-
- expectTrue(g is! Int2Int);
- expectTrue(g is String2String);
- expectTrue(g is Object2Object);
- expectTrue(g is! GenericMethod);
-
- expectTrue(h is! Int2Int);
- expectTrue(h is! String2String);
- expectTrue(h is Object2Object);
- expectTrue(h is! GenericMethod);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_local_variable_declaration_test.dart b/pkg/kernel/testcases/reify/generic_methods_local_variable_declaration_test.dart
deleted file mode 100644
index 211f58a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_local_variable_declaration_test.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that a type variable can be used to declare local variables, and that
-// these local variables are of correct type.
-
-library generic_methods_local_variable_declaration_test;
-
-import "test_base.dart";
-
-class X {}
-
-abstract class Generator<T> {
- T generate();
-}
-
-class A implements Generator<A> {
- generate() {
- return new A();
- }
-
- String toString() => "instance of A";
-}
-
-class B implements Generator<B> {
- generate() {
- return new B();
- }
-
- String toString() => "instance of B";
-}
-
-String fun<T extends Generator<T>>(T t) {
- T another = t.generate();
- String anotherName = "$another";
-
- expectTrue(another is T);
- expectTrue(another is Generator<T>);
-
- return anotherName;
-}
-
-main() {
- A a = new A();
- B b = new B();
-
- expectTrue(fun<A>(a) == "instance of A");
- expectTrue(fun<B>(b) == "instance of B");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_named_parameters_test.dart b/pkg/kernel/testcases/reify/generic_methods_named_parameters_test.dart
deleted file mode 100644
index 05804da..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_named_parameters_test.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods with named parameters are of correct type.
-
-library generic_methods_named_parameters_test;
-
-import "test_base.dart";
-
-typedef FunObjObj = Object Function<T>(Object, {Object y});
-typedef FunTypObj = Object Function<T>(T, {Object y});
-typedef FunObjTyp = Object Function<T>(Object, {T y});
-typedef FunTypTyp = Object Function<T>(T, {T y});
-
-Object funObjObj<T>(Object x, {Object y}) => x;
-Object funTypObj<T>(T x, {Object y}) => y;
-Object funObjTyp<T>(Object x, {T y}) => x;
-Object funTypTyp<T>(T x, {T y}) => null;
-
-main() {
- expectTrue(funObjObj is FunObjObj);
- expectTrue(funObjObj is FunTypObj);
- expectTrue(funObjObj is FunObjTyp);
- expectTrue(funObjObj is FunTypTyp);
-
- expectTrue(funTypObj is! FunObjObj);
- expectTrue(funTypObj is FunTypObj);
- expectTrue(funTypObj is! FunObjTyp);
- expectTrue(funTypObj is FunTypTyp);
-
- expectTrue(funObjTyp is! FunObjObj);
- expectTrue(funObjTyp is! FunTypObj);
- expectTrue(funObjTyp is FunObjTyp);
- expectTrue(funObjTyp is FunTypTyp);
-
- expectTrue(funTypTyp is! FunObjObj);
- expectTrue(funTypTyp is! FunTypObj);
- expectTrue(funTypTyp is! FunObjTyp);
- expectTrue(funTypTyp is FunTypTyp);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_optional_parameters_test.dart b/pkg/kernel/testcases/reify/generic_methods_optional_parameters_test.dart
deleted file mode 100644
index 8b5f106..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_optional_parameters_test.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods with optional parameters are of correct type.
-
-library generic_methods_optional_parameters_test;
-
-import "test_base.dart";
-
-typedef FunObjObj = Object Function<T>(Object, [Object]);
-typedef FunTypObj = Object Function<T>(T, [Object]);
-typedef FunObjTyp = Object Function<T>(Object, [T]);
-typedef FunTypTyp = Object Function<T>(T, [T]);
-
-Object funObjObj<T>(Object x, [Object y]) => x;
-Object funTypObj<T>(T x, [Object y]) => y;
-Object funObjTyp<T>(Object x, [T y]) => x;
-Object funTypTyp<T>(T x, [T y]) => null;
-
-main() {
- expectTrue(funObjObj is FunObjObj);
- expectTrue(funObjObj is FunTypObj);
- expectTrue(funObjObj is FunObjTyp);
- expectTrue(funObjObj is FunTypTyp);
-
- expectTrue(funTypObj is! FunObjObj);
- expectTrue(funTypObj is FunTypObj);
- expectTrue(funTypObj is! FunObjTyp);
- expectTrue(funTypObj is FunTypTyp);
-
- expectTrue(funObjTyp is! FunObjObj);
- expectTrue(funObjTyp is! FunTypObj);
- expectTrue(funObjTyp is FunObjTyp);
- expectTrue(funObjTyp is FunTypTyp);
-
- expectTrue(funTypTyp is! FunObjObj);
- expectTrue(funTypTyp is! FunTypObj);
- expectTrue(funTypTyp is! FunObjTyp);
- expectTrue(funTypTyp is FunTypTyp);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart
deleted file mode 100644
index 5d1da65..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods can be overridden using the bound of a type
-// variable as the type of the parameter in the overloaded method.
-
-library generic_methods_overriding_contravariance_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class Z extends Y {}
-
-class C {
- String fun<T extends Y>(T t) => "C";
-}
-
-class E extends C {
- String fun<T extends Y>(Y y) => "E";
-}
-
-main() {
- Y y = new Y();
-
- C c = new C();
- E e = new E();
-
- expectTrue(c.fun<Y>(y) == "C");
- expectTrue(e.fun<Y>(y) == "E");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart.expect
deleted file mode 100644
index c8cdab6..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart.expect
+++ /dev/null
@@ -1,83 +0,0 @@
-library generic_methods_overriding_contravariance_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::X::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
-}
-class Z extends self::Y implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::Y::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- return "C";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
-}
-class E extends self::C implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::C::•()
- ;
- method fun<T extends self::Y>(self::Y y, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- return "E";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](18)));
- dec::init(d, 1, new typ::Interface::•(d.[](0)));
- dec::init(d, 2, new typ::Interface::•(d.[](1)));
- dec::init(d, 3, new typ::Interface::•(d.[](18)));
- dec::init(d, 4, new typ::Interface::•(d.[](3)));
- dec::init(d, 5, new typ::Interface::•(d.[](18)));
- dec::init(d, 6, new typ::Interface::•(d.[](18)));
- dec::init(d, 7, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](7))]), new typ::Interface::•(d.[](21))]);
- dec::init(d, 8, new typ::Interface::•(d.[](22)));
- dec::init(d, 9, new typ::Interface::•(d.[](22)));
- dec::init(d, 10, new typ::Interface::•(d.[](18)));
- dec::init(d, 11, new typ::Interface::•(d.[](23)));
- dec::init(d, 12, new typ::Interface::•(d.[](23)));
- dec::init(d, 13, new typ::Interface::•(d.[](23)));
- dec::init(d, 14, new typ::Interface::•(d.[](23)));
- dec::init(d, 15, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](24))]);
- dec::init(d, 16, new typ::Interface::•(d.[](17)));
- dec::init(d, 17, new typ::Interface::•(d.[](23)));
- dec::init(d, 18, null);
- dec::init(d, 20, new typ::Interface::•(d.[](18)));
- dec::init(d, 21, new typ::Interface::•(d.[](18)));
- dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
- dec::init(d, 23, new typ::Interface::•(d.[](18)));
- dec::init(d, 24, new typ::Interface::•(d.[](18)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "E", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::Y y = new self::Y::•();
- self::C c = new self::C::•();
- self::E e = new self::E::•();
- tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
- tes::expectTrue(e.{self::E::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("E"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart
deleted file mode 100644
index 2d742e5..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods can be overridden.
-
-library generic_methods_overriding_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class C {
- String fun<T extends Y>(T t) => "C";
-}
-
-class D extends C {
- String fun<T extends Y>(T t) => "D";
-}
-
-main() {
- Y y = new Y();
-
- C c = new C();
- D d = new D();
-
- expectTrue(c.fun<Y>(y) == "C");
- expectTrue(d.fun<Y>(y) == "D");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart.expect
deleted file mode 100644
index 25d5120..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart.expect
+++ /dev/null
@@ -1,75 +0,0 @@
-library generic_methods_overriding_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::X::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- return "C";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
-}
-class D extends self::C implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::C::•()
- ;
- method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- return "D";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](17)));
- dec::init(d, 1, new typ::Interface::•(d.[](0)));
- dec::init(d, 2, new typ::Interface::•(d.[](17)));
- dec::init(d, 3, new typ::Interface::•(d.[](2)));
- dec::init(d, 4, new typ::Interface::•(d.[](17)));
- dec::init(d, 5, new typ::Interface::•(d.[](17)));
- dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](20))]);
- dec::init(d, 7, new typ::Interface::•(d.[](21)));
- dec::init(d, 8, new typ::Interface::•(d.[](21)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](22)));
- dec::init(d, 11, new typ::Interface::•(d.[](22)));
- dec::init(d, 12, new typ::Interface::•(d.[](22)));
- dec::init(d, 13, new typ::Interface::•(d.[](22)));
- dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](23))]);
- dec::init(d, 15, new typ::Interface::•(d.[](16)));
- dec::init(d, 16, new typ::Interface::•(d.[](22)));
- dec::init(d, 17, null);
- dec::init(d, 19, new typ::Interface::•(d.[](17)));
- dec::init(d, 20, new typ::Interface::•(d.[](17)));
- dec::init(d, 21, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](21))])]);
- dec::init(d, 22, new typ::Interface::•(d.[](17)));
- dec::init(d, 23, new typ::Interface::•(d.[](17)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "C", "D", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::Y y = new self::Y::•();
- self::C c = new self::C::•();
- self::D d = new self::D::•();
- tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
- tes::expectTrue(d.{self::D::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("D"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart
deleted file mode 100644
index 5aa081a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods that have bounds on type parameters can be
-// overridden, and that type propagation can be used in such methods.
-
-library generic_methods_overriding_type_propagation2_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class Z extends Y {}
-
-class C {
- String fun<T extends Y>(T t) => "C";
-}
-
-class F extends C {
- String foobar(Z z) {
- return "FZ";
- }
-
- String fun<T extends Y>(T t) {
- if (t is Z) {
- return this.foobar(t);
- }
- return "FY";
- }
-}
-
-main() {
- Y y = new Y();
- Z z = new Z();
-
- C c = new C();
- F f = new F();
-
- expectTrue(c.fun<Y>(y) == "C");
-
- expectTrue(f.fun<Y>(y) == "FY");
- expectTrue(f.fun<Z>(z) == "FZ");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart.expect
deleted file mode 100644
index ed69cfe..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart.expect
+++ /dev/null
@@ -1,101 +0,0 @@
-library generic_methods_overriding_type_propagation2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$Z() → core::bool
- return false;
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::X::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$Z() → core::bool
- return false;
-}
-class Z extends self::Y implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::Y::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$Z() → core::bool
- return true;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- return "C";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
- get $is$Z() → core::bool
- return false;
-}
-class F extends self::C implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::C::•()
- ;
- method foobar(self::Z z) → core::String {
- return "FZ";
- }
- method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- if(let dynamic #t1 = t in #t1 is int::HasRuntimeTypeGetter && #t1.$is$Z) {
- return this.{self::F::foobar}(t{self::Z});
- }
- return "FY";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$Z() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](18)));
- dec::init(d, 1, new typ::Interface::•(d.[](0)));
- dec::init(d, 2, new typ::Interface::•(d.[](1)));
- dec::init(d, 3, new typ::Interface::•(d.[](18)));
- dec::init(d, 4, new typ::Interface::•(d.[](3)));
- dec::init(d, 5, new typ::Interface::•(d.[](18)));
- dec::init(d, 6, new typ::Interface::•(d.[](18)));
- dec::init(d, 7, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](7))]), new typ::Interface::•(d.[](21))]);
- dec::init(d, 8, new typ::Interface::•(d.[](22)));
- dec::init(d, 9, new typ::Interface::•(d.[](22)));
- dec::init(d, 10, new typ::Interface::•(d.[](18)));
- dec::init(d, 11, new typ::Interface::•(d.[](23)));
- dec::init(d, 12, new typ::Interface::•(d.[](23)));
- dec::init(d, 13, new typ::Interface::•(d.[](23)));
- dec::init(d, 14, new typ::Interface::•(d.[](23)));
- dec::init(d, 15, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](24))]);
- dec::init(d, 16, new typ::Interface::•(d.[](17)));
- dec::init(d, 17, new typ::Interface::•(d.[](23)));
- dec::init(d, 18, null);
- dec::init(d, 20, new typ::Interface::•(d.[](18)));
- dec::init(d, 21, new typ::Interface::•(d.[](18)));
- dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
- dec::init(d, 23, new typ::Interface::•(d.[](18)));
- dec::init(d, 24, new typ::Interface::•(d.[](18)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "F", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::Y y = new self::Y::•();
- self::Z z = new self::Z::•();
- self::C c = new self::C::•();
- self::F f = new self::F::•();
- tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
- tes::expectTrue(f.{self::F::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("FY"));
- tes::expectTrue(f.{self::F::fun}(z, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](2))]).{core::String::==}("FZ"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart
deleted file mode 100644
index 974948a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods that have bounds on type parameters can be
-// overridden, and that type propagation can be used in such methods.
-
-library generic_methods_overriding_type_propagation_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class Z extends Y {}
-
-class C {
- String fun<T extends Y>(T t) => "C";
-}
-
-class F extends C {
- String foobar(Z z) {
- return "FZ";
- }
-
- String fun<T extends Y>(T t) {
- if (t is Z) {
- return this.foobar(t as Z);
- }
- return "FY";
- }
-}
-
-main() {
- Y y = new Y();
- Z z = new Z();
-
- C c = new C();
- F f = new F();
-
- expectTrue(c.fun<Y>(y) == "C");
-
- expectTrue(f.fun<Y>(y) == "FY");
- expectTrue(f.fun<Z>(z) == "FZ");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart.expect
deleted file mode 100644
index fb2d894..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart.expect
+++ /dev/null
@@ -1,101 +0,0 @@
-library generic_methods_overriding_type_propagation_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$Z() → core::bool
- return false;
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::X::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$Z() → core::bool
- return false;
-}
-class Z extends self::Y implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::Y::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$Z() → core::bool
- return true;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- return "C";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
- get $is$Z() → core::bool
- return false;
-}
-class F extends self::C implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::C::•()
- ;
- method foobar(self::Z z) → core::String {
- return "FZ";
- }
- method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
- if(let dynamic #t1 = t in #t1 is int::HasRuntimeTypeGetter && #t1.$is$Z) {
- return this.{self::F::foobar}(t{self::Z} as self::Z);
- }
- return "FY";
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$Z() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](18)));
- dec::init(d, 1, new typ::Interface::•(d.[](0)));
- dec::init(d, 2, new typ::Interface::•(d.[](1)));
- dec::init(d, 3, new typ::Interface::•(d.[](18)));
- dec::init(d, 4, new typ::Interface::•(d.[](3)));
- dec::init(d, 5, new typ::Interface::•(d.[](18)));
- dec::init(d, 6, new typ::Interface::•(d.[](18)));
- dec::init(d, 7, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](7))]), new typ::Interface::•(d.[](21))]);
- dec::init(d, 8, new typ::Interface::•(d.[](22)));
- dec::init(d, 9, new typ::Interface::•(d.[](22)));
- dec::init(d, 10, new typ::Interface::•(d.[](18)));
- dec::init(d, 11, new typ::Interface::•(d.[](23)));
- dec::init(d, 12, new typ::Interface::•(d.[](23)));
- dec::init(d, 13, new typ::Interface::•(d.[](23)));
- dec::init(d, 14, new typ::Interface::•(d.[](23)));
- dec::init(d, 15, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](24))]);
- dec::init(d, 16, new typ::Interface::•(d.[](17)));
- dec::init(d, 17, new typ::Interface::•(d.[](23)));
- dec::init(d, 18, null);
- dec::init(d, 20, new typ::Interface::•(d.[](18)));
- dec::init(d, 21, new typ::Interface::•(d.[](18)));
- dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
- dec::init(d, 23, new typ::Interface::•(d.[](18)));
- dec::init(d, 24, new typ::Interface::•(d.[](18)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "F", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::Y y = new self::Y::•();
- self::Z z = new self::Z::•();
- self::C c = new self::C::•();
- self::F f = new self::F::•();
- tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
- tes::expectTrue(f.{self::F::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("FY"));
- tes::expectTrue(f.{self::F::fun}(z, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](2))]).{core::String::==}("FZ"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_recursive_bound_error_test.dart
deleted file mode 100644
index c90957d..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_error_test.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that F-bounded quantification works for generic methods, and that types
-// that are passed to generic methods in dynamic calls are checked for being
-// recursively defined. An exception should be thrown if the type doesn't meet
-// the expectation.
-
-library generic_methods_recursive_bound_error_test;
-
-import "test_base.dart";
-
-abstract class I<T> {
- bool fun(T x);
-}
-
-void foo<T extends I<T>>(List<T> a) {
- if (a.length > 1) {
- a[0].fun(a[1]);
- }
-}
-
-class C implements I<C> {
- bool fun(C c) => true;
-}
-
-main() {
- dynamic bar = foo;
- List<int> list = <int>[4, 2];
- // The type int does not extend I<int>.
- expectThrows(() => bar<int>(list), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_test.dart b/pkg/kernel/testcases/reify/generic_methods_recursive_bound_test.dart
deleted file mode 100644
index e6cbcf3..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_test.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that F-bounded quantification works for generic methods.
-
-library generic_methods_recursive_bound_test;
-
-import "test_base.dart";
-
-abstract class I<T> {
- bool fun(T x);
-}
-
-int foo<T extends I<T>>(List<T> a) {
- if (a.length > 1) {
- a[0].fun(a[1]);
- }
- return a.length;
-}
-
-class C implements I<C> {
- bool fun(C c) => true;
-}
-
-main() {
- expectTrue(foo<C>(<C>[new C(), new C()]) == 2);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_reuse_type_variables_test.dart b/pkg/kernel/testcases/reify/generic_methods_reuse_type_variables_test.dart
deleted file mode 100644
index f21305f..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_reuse_type_variables_test.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that type parameter can be passed as a type argument in a definition of
-// a local variable, and that this local variable is correctly constructed.
-
-library generic_methods_reuse_type_variables_test;
-
-import "test_base.dart";
-
-int fun<T extends String>(T t) {
- List<T> list = <T>[t, t, t];
- expectTrue(list is List<String>);
- expectTrue(list is! List<int>);
- return list.length;
-}
-
-main() {
- expectTrue(fun<String>("foo") == 3);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_shadowing_test.dart b/pkg/kernel/testcases/reify/generic_methods_shadowing_test.dart
deleted file mode 100644
index e13e1e6..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_shadowing_test.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that type parameters in generic methods can be shadowed.
-
-library generic_methods_shadowing_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y {}
-
-bool foo<T, S>(T t, S s) {
- // The type parameter T of bar shadows the type parameter T of foo.
- bool bar<T>(T t) {
- return t is T && t is S;
- }
-
- return bar<S>(s);
-}
-
-main() {
- expectTrue(foo<X, Y>(new X(), new Y()));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart
deleted file mode 100644
index 1b89821..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that type parameters in generic methods can be used in as-expressions,
-// and that an exception is thrown if the cast can't be made.
-
-library generic_methods_simple_as_expression_error_test;
-
-import "test_base.dart";
-
-T cast<T>(dynamic obj) {
- return obj as T;
-}
-
-main() {
- expectThrows(() => cast<String>(42), (e) => e is CastError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart.expect
deleted file mode 100644
index 9dea62b..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart.expect
+++ /dev/null
@@ -1,73 +0,0 @@
-library generic_methods_simple_as_expression_error_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "dart:mock" as mock;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function::context = context
- ;
- method call() → core::String {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function::context};
- return self::cast(42, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$CastError() → core::bool
- return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#1::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](3)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$CastError() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](17))], new typ::FunctionType::•(new typ::Interface::•(d.[](17)), new typ::Interface::•(d.[](1)), 0, <dynamic>[]));
- dec::init(d, 1, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](1))]), new typ::Interface::•(d.[](20))]);
- dec::init(d, 2, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](17))], new typ::FunctionType::•(new typ::Interface::•(d.[](17)), new typ::Interface::•(d.[](5)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 3, new typ::Interface::•(d.[](21)));
- dec::init(d, 4, new typ::Interface::•(d.[](16)));
- dec::init(d, 5, new typ::Interface::•(d.[](16)));
- dec::init(d, 6, new typ::Interface::•(d.[](22)));
- dec::init(d, 7, new typ::Interface::•(d.[](22)));
- dec::init(d, 8, new typ::Interface::•(d.[](16)));
- dec::init(d, 9, new typ::Interface::•(d.[](21)));
- dec::init(d, 10, new typ::Interface::•(d.[](21)));
- dec::init(d, 11, new typ::Interface::•(d.[](21)));
- dec::init(d, 12, new typ::Interface::•(d.[](21)));
- dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](23))]);
- dec::init(d, 14, new typ::Interface::•(d.[](15)));
- dec::init(d, 15, new typ::Interface::•(d.[](21)));
- dec::init(d, 16, null);
- dec::init(d, 17, new typ::Interface::•(d.[](16)));
- dec::init(d, 19, new typ::Interface::•(d.[](16)));
- dec::init(d, 20, new typ::Interface::•(d.[](16)));
- dec::init(d, 21, new typ::Interface::•(d.[](16)));
- dec::init(d, 22, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](22))])]);
- dec::init(d, 23, new typ::Interface::•(d.[](16)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["Closure#main#function", "String", "Closure#main#function#1", "CastError", "Null", "bool", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "Function", "HasRuntimeTypeGetter", "Comparable", "Pattern", "Error", "num", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method cast(dynamic obj, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
- return obj as dynamic;
-}
-static method main() → dynamic {
- tes::expectThrows(new self::Closure#main#function::•(null), new self::Closure#main#function#1::•(null));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart
deleted file mode 100644
index b668d77..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that type parameters in generic methods can be used in as-expressions.
-
-library generic_methods_simple_as_expression_test;
-
-import "test_base.dart";
-
-T cast<T>(dynamic obj) {
- return obj as T;
-}
-
-main() {
- expectTrue(cast<num>(42) == 42);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart.expect
deleted file mode 100644
index b7cab5c..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library generic_methods_simple_as_expression_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](0))])]);
- dec::init(d, 1, new typ::Interface::•(d.[](14)));
- dec::init(d, 2, new typ::Interface::•(d.[](14)));
- dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](16))]);
- dec::init(d, 4, new typ::Interface::•(d.[](0)));
- dec::init(d, 5, new typ::Interface::•(d.[](0)));
- dec::init(d, 6, new typ::Interface::•(d.[](14)));
- dec::init(d, 7, new typ::Interface::•(d.[](17)));
- dec::init(d, 8, new typ::Interface::•(d.[](17)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](17)));
- dec::init(d, 11, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](18))]);
- dec::init(d, 12, new typ::Interface::•(d.[](13)));
- dec::init(d, 13, new typ::Interface::•(d.[](17)));
- dec::init(d, 14, null);
- dec::init(d, 15, new typ::Interface::•(d.[](14)));
- dec::init(d, 16, new typ::Interface::•(d.[](14)));
- dec::init(d, 17, new typ::Interface::•(d.[](14)));
- dec::init(d, 18, new typ::Interface::•(d.[](14)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["num", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "Comparable", "Pattern", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]));
-static method cast(dynamic obj, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
- return obj as dynamic;
-}
-static method main() → dynamic {
- tes::expectTrue(self::cast(42, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]).{core::num::==}(42));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_is_expression_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_is_expression_test.dart
deleted file mode 100644
index 66dcb70..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_is_expression_test.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that type parameters in generic methods can be used in is-expressions.
-
-library generic_methods_simple_is_expression_test;
-
-import "test_base.dart";
-
-bool fun<T>(int n) {
- return n is T;
-}
-
-main() {
- expectTrue(fun<int>(42));
- expectFalse(fun<String>(42));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_test.dart
deleted file mode 100644
index f2e13d8..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library generic_methods_simple_test;
-
-import 'test_base.dart';
-
-bool fun<T>(int s) {
- return true;
-}
-
-main() {
- expectTrue(fun<double>(2));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_simple_test.dart.expect
deleted file mode 100644
index 53c2725..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library generic_methods_simple_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](13)));
- dec::init(d, 1, new typ::Interface::•(d.[](14)));
- dec::init(d, 2, new typ::Interface::•(d.[](14)));
- dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](16))]);
- dec::init(d, 4, new typ::Interface::•(d.[](13)));
- dec::init(d, 5, new typ::Interface::•(d.[](14)));
- dec::init(d, 6, new typ::Interface::•(d.[](17)));
- dec::init(d, 7, new typ::Interface::•(d.[](17)));
- dec::init(d, 8, new typ::Interface::•(d.[](17)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](18))]);
- dec::init(d, 11, new typ::Interface::•(d.[](12)));
- dec::init(d, 12, new typ::Interface::•(d.[](17)));
- dec::init(d, 13, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](13))])]);
- dec::init(d, 14, null);
- dec::init(d, 15, new typ::Interface::•(d.[](14)));
- dec::init(d, 16, new typ::Interface::•(d.[](14)));
- dec::init(d, 17, new typ::Interface::•(d.[](14)));
- dec::init(d, 18, new typ::Interface::•(d.[](14)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["double", "Null", "bool", "String", "int", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "num", "Object", "Comparable", "Pattern", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]));
-static method fun(core::int s, {core::List<typ::ReifiedType> $typeParameters}) → core::bool {
- return true;
-}
-static method main() → dynamic {
- tes::expectTrue(self::fun(2, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_tearoff_specialization_test.dart b/pkg/kernel/testcases/reify/generic_methods_tearoff_specialization_test.dart
deleted file mode 100644
index 2424ecd..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_tearoff_specialization_test.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods can be specialized after being torn off, and that
-// their specialized versions are correctly constructed.
-
-library generic_methods_tearoff_specialization_test;
-
-import "test_base.dart";
-
-class A {
- T fun<T>(T t) => t;
-}
-
-typedef Int2Int = int Function(int);
-typedef String2String = String Function(String);
-typedef Object2Object = Object Function(Object);
-typedef GenericMethod = T Function<T>(T);
-
-main() {
- A a = new A();
- Int2Int f = a.fun;
- String2String g = a.fun;
- Object2Object h = a.fun;
- var generic = a.fun;
-
- expectTrue(f is Int2Int);
- expectTrue(f is! String2String);
- expectTrue(f is! Object2Object);
- expectTrue(f is! GenericMethod);
-
- expectTrue(g is! Int2Int);
- expectTrue(g is String2String);
- expectTrue(g is! Object2Object);
- expectTrue(g is! GenericMethod);
-
- expectTrue(h is! Int2Int);
- expectTrue(h is! String2String);
- expectTrue(h is Object2Object);
- expectTrue(g is! GenericMethod);
-
- expectTrue(generic is! Int2Int);
- expectTrue(generic is! String2String);
- expectTrue(generic is! Object2Object);
- expectTrue(generic is GenericMethod);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_unused_parameter_test.dart b/pkg/kernel/testcases/reify/generic_methods_unused_parameter_test.dart
deleted file mode 100644
index 3c52eea..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_unused_parameter_test.dart
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that generic methods with unused parameters aren't treated as
-// non-generic methods, but can be specialized as such.
-
-library generic_methods_unused_parameter_test;
-
-import "test_base.dart";
-
-typedef Fun = int Function();
-typedef FunReq = int Function(int);
-typedef FunOpt = int Function([int]);
-typedef FunReqOpt = int Function(int, [int]);
-typedef FunNam = int Function({int p});
-typedef FunReqNam = int Function(int, {int p});
-
-typedef FunTyp = int Function<T>();
-typedef FunTypReq = int Function<T>(int);
-typedef FunTypOpt = int Function<T>([int]);
-typedef FunTypReqOpt = int Function<T>(int, [int]);
-typedef FunTypNam = int Function<T>({int p});
-typedef FunTypReqNam = int Function<T>(int, {int p});
-
-int fun() {}
-int funReq(int x) => x;
-int funOpt([int y]) => y ?? 42;
-int funReqOpt(int x, [int y]) => x;
-int funNam({int p}) => p ?? 42;
-int funReqNam(int x, {int p}) => x;
-
-int funTyp<T>() {}
-int funTypReq<T>(int x) => x;
-int funTypOpt<T>([int y]) => y ?? 42;
-int funTypReqOpt<T>(int x, [int y]) => x;
-int funTypNam<T>({int p}) => p ?? 42;
-int funTypReqNam<T>(int x, {int p}) => x;
-
-main() {
- Fun varFun = funTyp;
- FunReq varFunReq = funTypReq;
- FunOpt varFunOpt = funTypOpt;
- FunReqOpt varFunReqOpt = funTypReqOpt;
- FunNam varFunNam = funTypNam;
- FunReqNam varFunReqNam = funTypReqNam;
-
- expectTrue(fun is Fun);
- expectTrue(fun is! FunTyp);
- expectTrue(funTyp is! Fun);
- expectTrue(funTyp is FunTyp);
- expectTrue(varFun is Fun);
- expectTrue(varFun is! FunTyp);
-
- expectTrue(funReq is FunReq);
- expectTrue(funReq is! FunTypReq);
- expectTrue(funTypReq is! FunReq);
- expectTrue(funTypReq is FunTypReq);
- expectTrue(varFunReq is FunReq);
- expectTrue(varFunReq is! FunTypReq);
-
- expectTrue(funOpt is FunOpt);
- expectTrue(funOpt is! FunTypOpt);
- expectTrue(funTypOpt is! FunOpt);
- expectTrue(funTypOpt is FunTypOpt);
- expectTrue(varFunOpt is FunOpt);
- expectTrue(varFunOpt is! FunTypOpt);
-
- expectTrue(funReqOpt is FunReqOpt);
- expectTrue(funReqOpt is! FunTypReqOpt);
- expectTrue(funTypReqOpt is! FunReqOpt);
- expectTrue(funTypReqOpt is FunTypReqOpt);
- expectTrue(varFunReqOpt is FunReqOpt);
- expectTrue(varFunReqOpt is! FunTypReqOpt);
-
- expectTrue(funNam is FunNam);
- expectTrue(funNam is! FunTypNam);
- expectTrue(funTypNam is! FunNam);
- expectTrue(funTypNam is FunTypNam);
- expectTrue(varFunNam is FunNam);
- expectTrue(varFunNam is! FunTypNam);
-
- expectTrue(funReqNam is FunReqNam);
- expectTrue(funReqNam is! FunTypReqNam);
- expectTrue(funTypReqNam is! FunReqNam);
- expectTrue(funTypReqNam is FunTypReqNam);
- expectTrue(varFunReqNam is FunReqNam);
- expectTrue(varFunReqNam is! FunTypReqNam);
-}
diff --git a/pkg/kernel/testcases/reify/is1_test.dart b/pkg/kernel/testcases/reify/is1_test.dart
deleted file mode 100644
index e84dae9..0000000
--- a/pkg/kernel/testcases/reify/is1_test.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library is1_test;
-
-import 'test_base.dart';
-
-class N {}
-
-class I extends N {}
-
-class D extends N {}
-
-class A<T> {}
-
-main() {
- var x = new A<I>();
- expectTrue(x is A<N>);
- expectTrue(x is A<I>);
- expectFalse(x is A<D>);
-
- var y = new A();
- expectTrue(y is A<N>);
- expectTrue(y is A<I>);
- expectTrue(y is A<D>);
-}
diff --git a/pkg/kernel/testcases/reify/is1_test.dart.expect b/pkg/kernel/testcases/reify/is1_test.dart.expect
deleted file mode 100644
index 020cdc3..0000000
--- a/pkg/kernel/testcases/reify/is1_test.dart.expect
+++ /dev/null
@@ -1,83 +0,0 @@
-library is1_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class N extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$A() → core::bool
- return false;
-}
-class I extends self::N implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::N::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$A() → core::bool
- return false;
-}
-class D extends self::N implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::N::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$A() → core::bool
- return false;
-}
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](0);
- get $is$A() → core::bool
- return true;
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](17)));
- dec::init(d, 1, new typ::Interface::•(d.[](0)));
- dec::init(d, 2, new typ::Interface::•(d.[](0)));
- dec::init(d, 3, new typ::Interface::•(d.[](17)));
- dec::init(d, 4, new typ::Interface::•(d.[](17)));
- dec::init(d, 5, new typ::Interface::•(d.[](17)));
- dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](20))]);
- dec::init(d, 7, new typ::Interface::•(d.[](21)));
- dec::init(d, 8, new typ::Interface::•(d.[](21)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](22)));
- dec::init(d, 11, new typ::Interface::•(d.[](22)));
- dec::init(d, 12, new typ::Interface::•(d.[](22)));
- dec::init(d, 13, new typ::Interface::•(d.[](22)));
- dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](23))]);
- dec::init(d, 15, new typ::Interface::•(d.[](16)));
- dec::init(d, 16, new typ::Interface::•(d.[](22)));
- dec::init(d, 17, null);
- dec::init(d, 19, new typ::Interface::•(d.[](17)));
- dec::init(d, 20, new typ::Interface::•(d.[](17)));
- dec::init(d, 21, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](21))])]);
- dec::init(d, 22, new typ::Interface::•(d.[](17)));
- dec::init(d, 23, new typ::Interface::•(d.[](17)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["N", "I", "D", "A", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::A x = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]));
- tes::expectTrue(let dynamic #t1 = x in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t1.$type, #t2)));
- tes::expectTrue(let dynamic #t3 = x in #t3 is int::HasRuntimeTypeGetter && #t3.$is$A && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t3.$type, #t4)));
- tes::expectFalse(let dynamic #t5 = x in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t5.$type, #t6)));
- self::A y = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[const typ::Dynamic::•()]));
- tes::expectTrue(let dynamic #t7 = y in #t7 is int::HasRuntimeTypeGetter && #t7.$is$A && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t7.$type, #t8)));
- tes::expectTrue(let dynamic #t9 = y in #t9 is int::HasRuntimeTypeGetter && #t9.$is$A && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t9.$type, #t10)));
- tes::expectTrue(let dynamic #t11 = y in #t11 is int::HasRuntimeTypeGetter && #t11.$is$A && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t11.$type, #t12)));
-}
diff --git a/pkg/kernel/testcases/reify/literals_test.dart b/pkg/kernel/testcases/reify/literals_test.dart
deleted file mode 100644
index 6b820dd..0000000
--- a/pkg/kernel/testcases/reify/literals_test.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library literals_test;
-
-import 'test_base.dart';
-
-class A {}
-
-class B {}
-
-main() {
- expectTrue(<A>[] is List<A>);
- expectTrue(<A>[] is! List<B>);
-
- expectTrue(<A, B>{} is Map<A, B>);
- expectTrue(<A, B>{} is! Map<A, A>);
- expectTrue(<A, B>{} is! Map<B, B>);
-}
diff --git a/pkg/kernel/testcases/reify/literals_test.dart.expect b/pkg/kernel/testcases/reify/literals_test.dart.expect
deleted file mode 100644
index 3d0d11d..0000000
--- a/pkg/kernel/testcases/reify/literals_test.dart.expect
+++ /dev/null
@@ -1,65 +0,0 @@
-library literals_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$List() → core::bool
- return false;
- get $is$Map() → core::bool
- return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$List() → core::bool
- return false;
- get $is$Map() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](17)));
- dec::init(d, 1, new typ::Interface::•(d.[](17)));
- dec::init(d, 2, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[d.[](2).variables.[](0)])]);
- dec::init(d, 3, new typ::Interface::•(d.[](17)));
- dec::init(d, 4, new typ::Interface::•(d.[](17)));
- dec::init(d, 5, new typ::Interface::•(d.[](17)));
- dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](21))]);
- dec::init(d, 7, new typ::Interface::•(d.[](22)));
- dec::init(d, 8, new typ::Interface::•(d.[](22)));
- dec::init(d, 9, new typ::Interface::•(d.[](17)));
- dec::init(d, 10, new typ::Interface::•(d.[](23)));
- dec::init(d, 11, new typ::Interface::•(d.[](23)));
- dec::init(d, 12, new typ::Interface::•(d.[](23)));
- dec::init(d, 13, new typ::Interface::•(d.[](23)));
- dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](24))]);
- dec::init(d, 15, new typ::Interface::•(d.[](16)));
- dec::init(d, 16, new typ::Interface::•(d.[](23)));
- dec::init(d, 17, null);
- dec::init(d, 19, new typ::Interface::•(d.[](25), <dynamic>[d.[](19).variables.[](0)]));
- dec::init(d, 20, new typ::Interface::•(d.[](17)));
- dec::init(d, 21, new typ::Interface::•(d.[](17)));
- dec::init(d, 22, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
- dec::init(d, 23, new typ::Interface::•(d.[](17)));
- dec::init(d, 24, new typ::Interface::•(d.[](17)));
- dec::init(d, 25, new typ::Interface::•(d.[](17)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "List", "Map", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method main() → dynamic {
- tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(<self::A>[], new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]))), new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(<self::A>[], new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]))), new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(<self::A, self::B>{}, new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))]))), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(<self::A, self::B>{}, new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))]))), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](0))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(<self::A, self::B>{}, new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))]))), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](1))])));
-}
diff --git a/pkg/kernel/testcases/reify/multiple_variables_test.dart b/pkg/kernel/testcases/reify/multiple_variables_test.dart
deleted file mode 100644
index 5c33c33..0000000
--- a/pkg/kernel/testcases/reify/multiple_variables_test.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library multiple_variables_test;
-
-import '../../runtime/reify/types.dart' as rti;
-
-class X<A, B, C, D, E> {}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/multiple_variables_test.dart.expect b/pkg/kernel/testcases/reify/multiple_variables_test.dart.expect
deleted file mode 100644
index 9b1dccf..0000000
--- a/pkg/kernel/testcases/reify/multiple_variables_test.dart.expect
+++ /dev/null
@@ -1,49 +0,0 @@
-library multiple_variables_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::X::$type = $type, super core::Object::•()
- ;
- get $X$A() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get $X$B() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](1);
- get $X$C() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](2);
- get $X$D() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](3);
- get $X$E() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](4);
- get runtimeType() → core::Type
- return this.{=self::X::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](14)));
- dec::init(d, 1, new typ::Interface::•(d.[](14)));
- dec::init(d, 2, new typ::Interface::•(d.[](14)));
- dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](17))]);
- dec::init(d, 4, new typ::Interface::•(d.[](18)));
- dec::init(d, 5, new typ::Interface::•(d.[](18)));
- dec::init(d, 6, new typ::Interface::•(d.[](14)));
- dec::init(d, 7, new typ::Interface::•(d.[](19)));
- dec::init(d, 8, new typ::Interface::•(d.[](19)));
- dec::init(d, 9, new typ::Interface::•(d.[](19)));
- dec::init(d, 10, new typ::Interface::•(d.[](19)));
- dec::init(d, 11, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](20))]);
- dec::init(d, 12, new typ::Interface::•(d.[](13)));
- dec::init(d, 13, new typ::Interface::•(d.[](19)));
- dec::init(d, 14, null);
- dec::init(d, 16, new typ::Interface::•(d.[](14)));
- dec::init(d, 17, new typ::Interface::•(d.[](14)));
- dec::init(d, 18, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](18))])]);
- dec::init(d, 19, new typ::Interface::•(d.[](14)));
- dec::init(d, 20, new typ::Interface::•(d.[](14)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/native_types_test.dart b/pkg/kernel/testcases/reify/native_types_test.dart
deleted file mode 100644
index 738b151..0000000
--- a/pkg/kernel/testcases/reify/native_types_test.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library native_types;
-
-import 'test_base.dart';
-
-abstract class C {}
-
-class D {}
-
-var foo = bar;
-var bar = foo;
-
-main() {
- expectTrue(1 is int);
- expectTrue(1 is! double);
-
- expectTrue(new List<int>() is List<int>);
- expectTrue(new List<int>() is! List<double>);
- expectTrue("hest" is String);
- expectTrue("hest" is! int);
-
- expectTrue(null is! String);
- expectTrue(null is dynamic);
- expectTrue(null is Object);
-
- expectTrue(true is bool);
- expectTrue(true is! int);
-
- // Test error and exception classes
- expectThrows(() => new C(), (e) => e is AbstractClassInstantiationError);
-
- /// 01: static type warning
-
- expectThrows(() => new D().foo(), (e) => e is NoSuchMethodError);
-
- /// 02: static type warning
-
- expectThrows(() => foo, (e) => e is CyclicInitializationError);
-
- expectThrows(() => [][1], (e) => e is RangeError);
-
- expectTrue(new UnsupportedError("") is UnsupportedError);
-
- expectTrue(new ArgumentError() is ArgumentError);
-
- expectTrue(
- new IntegerDivisionByZeroException() is IntegerDivisionByZeroException);
-}
diff --git a/pkg/kernel/testcases/reify/native_types_test.dart.expect b/pkg/kernel/testcases/reify/native_types_test.dart.expect
deleted file mode 100644
index ca0fa91..0000000
--- a/pkg/kernel/testcases/reify/native_types_test.dart.expect
+++ /dev/null
@@ -1,453 +0,0 @@
-library native_types;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-abstract class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class D extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function::context = context
- ;
- method call() → self::C {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function::context};
- return throw int::attachType(new core::AbstractClassInstantiationError::•("C"), new typ::Interface::•(self::$declarations.[](3)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#1::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](3)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function#2 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#2::context = context
- ;
- method call() → dynamic {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#2::context};
- return new self::D::•().foo();
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](5));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function#3 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#3::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#3::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](7)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](6));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function#4 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#4::context = context
- ;
- method call() → dynamic {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#4::context};
- return self::foo;
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](8));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function#5 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#5::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#5::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](10)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](9));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function#6 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#6::context = context
- ;
- method call() → dynamic {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#6::context};
- return int::attachType(<dynamic>[], new typ::Interface::•(self::$declarations.[](12), <dynamic>[const typ::Dynamic::•()])).{core::List::[]}(1);
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](11));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-class Closure#main#function#7 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field mock::Context context;
- constructor •(final mock::Context context) → dynamic
- : self::Closure#main#function#7::context = context
- ;
- method call(dynamic e) → core::bool {
- "This is a temporary solution. In the VM, this will become an additional parameter.";
- final mock::Context #contextParameter = this.{self::Closure#main#function#7::context};
- return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](14)));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](13));
- get $is$AbstractClassInstantiationError() → core::bool
- return false;
- get $is$NoSuchMethodError() → core::bool
- return false;
- get $is$CyclicInitializationError() → core::bool
- return false;
- get $is$RangeError() → core::bool
- return false;
- get $is$int() → core::bool
- return false;
- get $is$double() → core::bool
- return false;
- get $is$List() → core::bool
- return false;
- get $is$String() → core::bool
- return false;
- get $is$Object() → core::bool
- return true;
- get $is$bool() → core::bool
- return false;
- get $is$UnsupportedError() → core::bool
- return false;
- get $is$ArgumentError() → core::bool
- return false;
- get $is$IntegerDivisionByZeroException() → core::bool
- return false;
-}
-static field dynamic foo = self::bar;
-static field dynamic bar = self::foo;
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](18)));
- dec::init(d, 1, new typ::Interface::•(d.[](18)));
- dec::init(d, 2, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](0)), 0, <dynamic>[]));
- dec::init(d, 3, new typ::Interface::•(d.[](27)));
- dec::init(d, 4, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 5, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), const typ::Dynamic::•(), 0, <dynamic>[]));
- dec::init(d, 6, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 7, new typ::Interface::•(d.[](27)));
- dec::init(d, 8, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), const typ::Dynamic::•(), 0, <dynamic>[]));
- dec::init(d, 9, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 10, new typ::Interface::•(d.[](27)));
- dec::init(d, 11, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), const typ::Dynamic::•(), 0, <dynamic>[]));
- dec::init(d, 12, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](28), <dynamic>[d.[](12).variables.[](0)])]);
- dec::init(d, 13, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 14, new typ::Interface::•(d.[](21)));
- dec::init(d, 15, new typ::Interface::•(d.[](29)));
- dec::init(d, 16, new typ::Interface::•(d.[](29)));
- dec::init(d, 17, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](30), <dynamic>[new typ::Interface::•(d.[](17))]), new typ::Interface::•(d.[](31))]);
- dec::init(d, 18, null);
- dec::init(d, 19, new typ::Interface::•(d.[](18)));
- dec::init(d, 20, new typ::Interface::•(d.[](27)));
- dec::init(d, 21, new typ::Interface::•(d.[](27)));
- dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](32))]);
- dec::init(d, 23, new typ::Interface::•(d.[](18)));
- dec::init(d, 24, new typ::Interface::•(d.[](18)));
- dec::init(d, 26, new typ::Interface::•(d.[](18)));
- dec::init(d, 27, new typ::Interface::•(d.[](18)));
- dec::init(d, 28, new typ::Interface::•(d.[](33), <dynamic>[d.[](28).variables.[](0)]));
- dec::init(d, 29, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](30), <dynamic>[new typ::Interface::•(d.[](29))])]);
- dec::init(d, 30, new typ::Interface::•(d.[](18)));
- dec::init(d, 31, new typ::Interface::•(d.[](18)));
- dec::init(d, 32, new typ::Interface::•(d.[](18)));
- dec::init(d, 33, new typ::Interface::•(d.[](18)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "D", "Closure#main#function", "AbstractClassInstantiationError", "Closure#main#function#1", "Closure#main#function#2", "Closure#main#function#3", "NoSuchMethodError", "Closure#main#function#4", "Closure#main#function#5", "CyclicInitializationError", "Closure#main#function#6", "List", "Closure#main#function#7", "RangeError", "int", "double", "String", "Object", "bool", "UnsupportedError", "ArgumentError", "IntegerDivisionByZeroException", "Null", "Type", "HasRuntimeTypeGetter", "Function", "Error", "EfficientLengthIterable", "num", "Comparable", "Pattern", "Exception", "Iterable"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1]));
-static method main() → dynamic {
- tes::expectTrue(typ::isSubtypeOf(int::type(1), new typ::Interface::•(self::$declarations.[](15))));
- tes::expectTrue(!typ::isSubtypeOf(int::type(1), new typ::Interface::•(self::$declarations.[](16))));
- tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(core::List::_internal<core::int>(), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](15))]))), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](15))])));
- tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(core::List::_internal<core::int>(), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](15))]))), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](16))])));
- tes::expectTrue(typ::isSubtypeOf(int::type("hest"), new typ::Interface::•(self::$declarations.[](17))));
- tes::expectTrue(!typ::isSubtypeOf(int::type("hest"), new typ::Interface::•(self::$declarations.[](15))));
- tes::expectTrue(!typ::isSubtypeOf(int::type(null), new typ::Interface::•(self::$declarations.[](17))));
- tes::expectTrue(typ::isSubtypeOf(int::type(null), const typ::Dynamic::•()));
- tes::expectTrue(typ::isSubtypeOf(int::type(null), new typ::Interface::•(self::$declarations.[](18))));
- tes::expectTrue(typ::isSubtypeOf(int::type(true), new typ::Interface::•(self::$declarations.[](19))));
- tes::expectTrue(!typ::isSubtypeOf(int::type(true), new typ::Interface::•(self::$declarations.[](15))));
- tes::expectThrows(new self::Closure#main#function::•(null), new self::Closure#main#function#1::•(null));
- tes::expectThrows(new self::Closure#main#function#2::•(null), new self::Closure#main#function#3::•(null));
- tes::expectThrows(new self::Closure#main#function#4::•(null), new self::Closure#main#function#5::•(null));
- tes::expectThrows(new self::Closure#main#function#6::•(null), new self::Closure#main#function#7::•(null));
- tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(new core::UnsupportedError::•(""), new typ::Interface::•(self::$declarations.[](20)))), new typ::Interface::•(self::$declarations.[](20))));
- tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(new core::ArgumentError::•(), new typ::Interface::•(self::$declarations.[](21)))), new typ::Interface::•(self::$declarations.[](21))));
- tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(new core::IntegerDivisionByZeroException::•(), new typ::Interface::•(self::$declarations.[](22)))), new typ::Interface::•(self::$declarations.[](22))));
-}
diff --git a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart b/pkg/kernel/testcases/reify/reuse_type_variables_test.dart
deleted file mode 100644
index 1e6cdc2..0000000
--- a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library reuse_type_variables_test;
-
-import 'test_base.dart';
-
-class X {}
-
-class Y {}
-
-class Z {}
-
-class C<T, U, V> {
- foo() => new D<T, U, V>();
- bar() => new E<T, U>();
- hest() => new D<T, V, U>();
-}
-
-class D<T, U, V> {
- baz() => new C<T, U, V>();
-}
-
-class E<T, U> {
- qux() => new C<T, U, U>();
-}
-
-main() {
- var c = new C<X, Y, Z>();
- var d = c.foo();
- expectTrue(d is D<X, Y, Z>);
- d = c.hest();
- expectTrue(d is! D<X, Y, Z>);
- expectTrue(d is D<X, Z, Y>);
- c = d.baz();
- expectTrue(c is C<X, Z, Y>);
- var e = c.bar();
- expectTrue(e is E<X, Z>);
- c = e.qux();
- expectTrue(c is C<X, Z, Z>);
-}
diff --git a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart.expect b/pkg/kernel/testcases/reify/reuse_type_variables_test.dart.expect
deleted file mode 100644
index 473772b..0000000
--- a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart.expect
+++ /dev/null
@@ -1,162 +0,0 @@
-library reuse_type_variables_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$D() → core::bool
- return false;
- get $is$C() → core::bool
- return false;
- get $is$E() → core::bool
- return false;
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$D() → core::bool
- return false;
- get $is$C() → core::bool
- return false;
- get $is$E() → core::bool
- return false;
-}
-class Z extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$D() → core::bool
- return false;
- get $is$C() → core::bool
- return false;
- get $is$E() → core::bool
- return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::C::$type = $type, super core::Object::•()
- ;
- method foo() → dynamic {
- return new self::D::•(new typ::Interface::•(self::$declarations.[](4), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3)))));
- }
- method bar() → dynamic {
- return new self::E::•(new typ::Interface::•(self::$declarations.[](5), <dynamic>[this.$C$T, this.$C$U]));
- }
- method hest() → dynamic {
- return new self::D::•(new typ::Interface::•(self::$declarations.[](4), <dynamic>[this.$C$T, this.$C$V, this.$C$U]));
- }
- get $C$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](0);
- get $C$U() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](1);
- get $C$V() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](2);
- get $is$D() → core::bool
- return false;
- get $is$C() → core::bool
- return true;
- get $is$E() → core::bool
- return false;
- get runtimeType() → core::Type
- return this.{=self::C::$type};
-}
-class D extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::D::$type = $type, super core::Object::•()
- ;
- method baz() → dynamic {
- return new self::C::•(new typ::Interface::•(self::$declarations.[](3), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4)))));
- }
- get $D$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](0);
- get $D$U() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](1);
- get $D$V() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](2);
- get $is$D() → core::bool
- return true;
- get $is$C() → core::bool
- return false;
- get $is$E() → core::bool
- return false;
- get runtimeType() → core::Type
- return this.{=self::D::$type};
-}
-class E extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::E::$type = $type, super core::Object::•()
- ;
- method qux() → dynamic {
- return new self::C::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[this.$E$T, this.$E$U, this.$E$U]));
- }
- get $E$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](5))).[](0);
- get $E$U() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](5))).[](1);
- get $is$D() → core::bool
- return false;
- get $is$C() → core::bool
- return false;
- get $is$E() → core::bool
- return true;
- get runtimeType() → core::Type
- return this.{=self::E::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](19)));
- dec::init(d, 1, new typ::Interface::•(d.[](19)));
- dec::init(d, 2, new typ::Interface::•(d.[](19)));
- dec::init(d, 3, new typ::Interface::•(d.[](19)));
- dec::init(d, 4, new typ::Interface::•(d.[](19)));
- dec::init(d, 5, new typ::Interface::•(d.[](19)));
- dec::init(d, 6, new typ::Interface::•(d.[](19)));
- dec::init(d, 7, new typ::Interface::•(d.[](19)));
- dec::init(d, 8, new typ::Interface::•(d.[](19)), <dynamic>[new typ::Interface::•(d.[](21), <dynamic>[new typ::Interface::•(d.[](8))]), new typ::Interface::•(d.[](22))]);
- dec::init(d, 9, new typ::Interface::•(d.[](23)));
- dec::init(d, 10, new typ::Interface::•(d.[](23)));
- dec::init(d, 11, new typ::Interface::•(d.[](19)));
- dec::init(d, 12, new typ::Interface::•(d.[](24)));
- dec::init(d, 13, new typ::Interface::•(d.[](24)));
- dec::init(d, 14, new typ::Interface::•(d.[](24)));
- dec::init(d, 15, new typ::Interface::•(d.[](24)));
- dec::init(d, 16, new typ::Interface::•(d.[](19)), <dynamic>[new typ::Interface::•(d.[](25))]);
- dec::init(d, 17, new typ::Interface::•(d.[](18)));
- dec::init(d, 18, new typ::Interface::•(d.[](24)));
- dec::init(d, 19, null);
- dec::init(d, 21, new typ::Interface::•(d.[](19)));
- dec::init(d, 22, new typ::Interface::•(d.[](19)));
- dec::init(d, 23, new typ::Interface::•(d.[](19)), <dynamic>[new typ::Interface::•(d.[](21), <dynamic>[new typ::Interface::•(d.[](23))])]);
- dec::init(d, 24, new typ::Interface::•(d.[](19)));
- dec::init(d, 25, new typ::Interface::•(d.[](19)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "D", "E", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::C c = new self::C::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))]));
- dynamic d = c.{self::C::foo}();
- tes::expectTrue(let dynamic #t1 = d in #t1 is int::HasRuntimeTypeGetter && #t1.$is$D && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t1.$type, #t2)));
- d = c.{self::C::hest}();
- tes::expectTrue(!(let dynamic #t3 = d in #t3 is int::HasRuntimeTypeGetter && #t3.$is$D && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t3.$type, #t4))));
- tes::expectTrue(let dynamic #t5 = d in #t5 is int::HasRuntimeTypeGetter && #t5.$is$D && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2)), new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t5.$type, #t6)));
- c = d.baz();
- tes::expectTrue(let dynamic #t7 = c in #t7 is int::HasRuntimeTypeGetter && #t7.$is$C && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2)), new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t7.$type, #t8)));
- dynamic e = c.{self::C::bar}();
- tes::expectTrue(let dynamic #t9 = e in #t9 is int::HasRuntimeTypeGetter && #t9.$is$E && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](5), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t9.$type, #t10)));
- c = e.qux();
- tes::expectTrue(let dynamic #t11 = c in #t11 is int::HasRuntimeTypeGetter && #t11.$is$C && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t11.$type, #t12)));
-}
diff --git a/pkg/kernel/testcases/reify/runtime_type_test.dart b/pkg/kernel/testcases/reify/runtime_type_test.dart
deleted file mode 100644
index 39b6b54..0000000
--- a/pkg/kernel/testcases/reify/runtime_type_test.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library runtime_type_test;
-
-import 'test_base.dart';
-
-class A<T> {}
-
-class X {}
-
-class Y {}
-
-bool eqt(a, b) => a.runtimeType == b.runtimeType;
-
-main() {
- expectTrue(eqt(new A(), new A<dynamic>()));
- expectTrue(eqt(new A<X>(), new A<X>()));
- expectFalse(eqt(new A<X>(), new A()));
- expectFalse(eqt(new A<X>(), new A<Y>()));
-}
diff --git a/pkg/kernel/testcases/reify/runtime_type_test.dart.expect b/pkg/kernel/testcases/reify/runtime_type_test.dart.expect
deleted file mode 100644
index 360e853..0000000
--- a/pkg/kernel/testcases/reify/runtime_type_test.dart.expect
+++ /dev/null
@@ -1,66 +0,0 @@
-library runtime_type_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](16)));
- dec::init(d, 1, new typ::Interface::•(d.[](16)));
- dec::init(d, 2, new typ::Interface::•(d.[](16)));
- dec::init(d, 3, new typ::Interface::•(d.[](16)));
- dec::init(d, 4, new typ::Interface::•(d.[](16)));
- dec::init(d, 5, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](5))]), new typ::Interface::•(d.[](19))]);
- dec::init(d, 6, new typ::Interface::•(d.[](20)));
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](16)));
- dec::init(d, 9, new typ::Interface::•(d.[](21)));
- dec::init(d, 10, new typ::Interface::•(d.[](21)));
- dec::init(d, 11, new typ::Interface::•(d.[](21)));
- dec::init(d, 12, new typ::Interface::•(d.[](21)));
- dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](22))]);
- dec::init(d, 14, new typ::Interface::•(d.[](15)));
- dec::init(d, 15, new typ::Interface::•(d.[](21)));
- dec::init(d, 16, null);
- dec::init(d, 18, new typ::Interface::•(d.[](16)));
- dec::init(d, 19, new typ::Interface::•(d.[](16)));
- dec::init(d, 20, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
- dec::init(d, 21, new typ::Interface::•(d.[](16)));
- dec::init(d, 22, new typ::Interface::•(d.[](16)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "X", "Y", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method eqt(dynamic a, dynamic b) → core::bool {
- return a.runtimeType.==(b.runtimeType);
-}
-static method main() → dynamic {
- tes::expectTrue(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()]))));
- tes::expectTrue(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]))));
- tes::expectFalse(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()]))));
- tes::expectFalse(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]))));
-}
diff --git a/pkg/kernel/testcases/reify/simple_test.dart b/pkg/kernel/testcases/reify/simple_test.dart
deleted file mode 100644
index 4a2d11f..0000000
--- a/pkg/kernel/testcases/reify/simple_test.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library simple_test;
-
-import 'test_base.dart';
-
-class C {}
-
-class A implements C {}
-
-class B extends C {}
-
-class D extends B {}
-
-testIs(o) {
- write(o is A);
- write(o is B);
- write(o is C);
- write(o is D);
-}
-
-testIsNot(o) {
- write(o is! A);
- write(o is! B);
- write(o is! C);
- write(o is! D);
-}
-
-main() {
- var objects = [new A(), new B(), new C(), new D()];
- objects.forEach(testIs);
- objects.forEach(testIsNot);
-
- expectOutput("""
-true
-false
-true
-false
-false
-true
-true
-false
-false
-false
-true
-false
-false
-true
-true
-true
-false
-true
-false
-true
-true
-false
-false
-true
-true
-true
-false
-true
-true
-false
-false
-false""");
-}
diff --git a/pkg/kernel/testcases/reify/simple_test.dart.expect b/pkg/kernel/testcases/reify/simple_test.dart.expect
deleted file mode 100644
index 3b1c713..0000000
--- a/pkg/kernel/testcases/reify/simple_test.dart.expect
+++ /dev/null
@@ -1,152 +0,0 @@
-library simple_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$A() → core::bool
- return false;
- get $is$B() → core::bool
- return false;
- get $is$C() → core::bool
- return true;
- get $is$D() → core::bool
- return false;
-}
-class A extends core::Object implements self::C, int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$A() → core::bool
- return true;
- get $is$B() → core::bool
- return false;
- get $is$C() → core::bool
- return true;
- get $is$D() → core::bool
- return false;
-}
-class B extends self::C implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::C::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
- get $is$A() → core::bool
- return false;
- get $is$B() → core::bool
- return true;
- get $is$C() → core::bool
- return true;
- get $is$D() → core::bool
- return false;
-}
-class D extends self::B implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::B::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](3));
- get $is$A() → core::bool
- return false;
- get $is$B() → core::bool
- return true;
- get $is$C() → core::bool
- return true;
- get $is$D() → core::bool
- return true;
-}
-class Closure#testIs extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- constructor •() → dynamic
- ;
- method call(dynamic o) → dynamic
- return self::testIs(o);
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](4));
- get $is$A() → core::bool
- return false;
- get $is$B() → core::bool
- return false;
- get $is$C() → core::bool
- return false;
- get $is$D() → core::bool
- return false;
-}
-class Closure#testIsNot extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- constructor •() → dynamic
- ;
- method call(dynamic o) → dynamic
- return self::testIsNot(o);
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](5));
- get $is$A() → core::bool
- return false;
- get $is$B() → core::bool
- return false;
- get $is$C() → core::bool
- return false;
- get $is$D() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](20)));
- dec::init(d, 1, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](0))]);
- dec::init(d, 2, new typ::Interface::•(d.[](0)));
- dec::init(d, 3, new typ::Interface::•(d.[](2)));
- dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 5, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 6, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](23), <dynamic>[d.[](6).variables.[](0)])]);
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](25))]);
- dec::init(d, 10, new typ::Interface::•(d.[](26)));
- dec::init(d, 11, new typ::Interface::•(d.[](26)));
- dec::init(d, 12, new typ::Interface::•(d.[](20)));
- dec::init(d, 13, new typ::Interface::•(d.[](27)));
- dec::init(d, 14, new typ::Interface::•(d.[](27)));
- dec::init(d, 15, new typ::Interface::•(d.[](27)));
- dec::init(d, 16, new typ::Interface::•(d.[](27)));
- dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](28))]);
- dec::init(d, 18, new typ::Interface::•(d.[](19)));
- dec::init(d, 19, new typ::Interface::•(d.[](27)));
- dec::init(d, 20, null);
- dec::init(d, 22, new typ::Interface::•(d.[](20)));
- dec::init(d, 23, new typ::Interface::•(d.[](29), <dynamic>[d.[](23).variables.[](0)]));
- dec::init(d, 24, new typ::Interface::•(d.[](20)));
- dec::init(d, 25, new typ::Interface::•(d.[](20)));
- dec::init(d, 26, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](26))])]);
- dec::init(d, 27, new typ::Interface::•(d.[](20)));
- dec::init(d, 28, new typ::Interface::•(d.[](20)));
- dec::init(d, 29, new typ::Interface::•(d.[](20)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "A", "B", "D", "Closure#testIs", "Closure#testIsNot", "List", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method testIs(dynamic o) → dynamic {
- tes::write(let dynamic #t1 = o in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A);
- tes::write(let dynamic #t2 = o in #t2 is int::HasRuntimeTypeGetter && #t2.$is$B);
- tes::write(let dynamic #t3 = o in #t3 is int::HasRuntimeTypeGetter && #t3.$is$C);
- tes::write(let dynamic #t4 = o in #t4 is int::HasRuntimeTypeGetter && #t4.$is$D);
-}
-static method testIsNot(dynamic o) → dynamic {
- tes::write(!(let dynamic #t5 = o in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A));
- tes::write(!(let dynamic #t6 = o in #t6 is int::HasRuntimeTypeGetter && #t6.$is$B));
- tes::write(!(let dynamic #t7 = o in #t7 is int::HasRuntimeTypeGetter && #t7.$is$C));
- tes::write(!(let dynamic #t8 = o in #t8 is int::HasRuntimeTypeGetter && #t8.$is$D));
-}
-static method main() → dynamic {
- core::List<self::C> objects = int::attachType(<self::C>[new self::A::•(), new self::B::•(), new self::C::•(), new self::D::•()], new typ::Interface::•(self::$declarations.[](6), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]));
- objects.{core::Iterable::forEach}(new self::Closure#testIs::•());
- objects.{core::Iterable::forEach}(new self::Closure#testIsNot::•());
- tes::expectOutput("true\nfalse\ntrue\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\nfalse\ntrue\ntrue\nfalse\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse");
-}
diff --git a/pkg/kernel/testcases/reify/subclass_test.dart b/pkg/kernel/testcases/reify/subclass_test.dart
deleted file mode 100644
index 5b5b6bc..0000000
--- a/pkg/kernel/testcases/reify/subclass_test.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library superclass_test;
-
-import 'test_base.dart';
-
-class X {}
-
-class Y {}
-
-class R<T> {}
-
-class A<T> {
- foo() => new R<T>();
-}
-
-class B<T> extends A<T> {}
-
-class C<T> extends A<Y> {}
-
-class D<T> extends B<R<T>> {}
-
-main() {
- expectTrue(new A<X>().foo() is R<X>);
- expectTrue(new B<X>().foo() is R<X>);
- expectTrue(new C<X>().foo() is R<Y>);
- expectTrue(new D<X>().foo() is R<R<X>>);
-
- expectTrue(new A<X>().foo() is! R<Y>);
- expectTrue(new B<X>().foo() is! R<Y>);
- expectTrue(new C<X>().foo() is! R<X>);
- expectTrue(new D<X>().foo() is! R<R<Y>>);
-}
diff --git a/pkg/kernel/testcases/reify/subclass_test.dart.expect b/pkg/kernel/testcases/reify/subclass_test.dart.expect
deleted file mode 100644
index 2317bb7..0000000
--- a/pkg/kernel/testcases/reify/subclass_test.dart.expect
+++ /dev/null
@@ -1,119 +0,0 @@
-library superclass_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
- get $is$R() → core::bool
- return false;
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
- get $is$R() → core::bool
- return false;
-}
-class R extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::R::$type = $type, super core::Object::•()
- ;
- get $R$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](2))).[](0);
- get $is$R() → core::bool
- return true;
- get runtimeType() → core::Type
- return this.{=self::R::$type};
-}
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- method foo() → dynamic {
- return new self::R::•(new typ::Interface::•(self::$declarations.[](2), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3)))));
- }
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](0);
- get $is$R() → core::bool
- return false;
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
- constructor •(typ::ReifiedType $type) → void
- : super self::A::•($type)
- ;
- get $B$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](0);
- get $is$R() → core::bool
- return false;
-}
-class C extends self::A implements int::HasRuntimeTypeGetter {
- constructor •(typ::ReifiedType $type) → void
- : super self::A::•($type)
- ;
- get $C$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](5))).[](0);
- get $is$R() → core::bool
- return false;
-}
-class D extends self::B implements int::HasRuntimeTypeGetter {
- constructor •(typ::ReifiedType $type) → void
- : super self::B::•($type)
- ;
- get $D$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](6))).[](0);
- get $is$R() → core::bool
- return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](20)));
- dec::init(d, 1, new typ::Interface::•(d.[](20)));
- dec::init(d, 2, new typ::Interface::•(d.[](20)));
- dec::init(d, 3, new typ::Interface::•(d.[](20)));
- dec::init(d, 4, new typ::Interface::•(d.[](3), <dynamic>[d.[](4).variables.[](0)]));
- dec::init(d, 5, new typ::Interface::•(d.[](3), <dynamic>[new typ::Interface::•(d.[](1))]));
- dec::init(d, 6, new typ::Interface::•(d.[](4), <dynamic>[new typ::Interface::•(d.[](2), <dynamic>[d.[](6).variables.[](0)])]));
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](23))]);
- dec::init(d, 10, new typ::Interface::•(d.[](24)));
- dec::init(d, 11, new typ::Interface::•(d.[](24)));
- dec::init(d, 12, new typ::Interface::•(d.[](20)));
- dec::init(d, 13, new typ::Interface::•(d.[](25)));
- dec::init(d, 14, new typ::Interface::•(d.[](25)));
- dec::init(d, 15, new typ::Interface::•(d.[](25)));
- dec::init(d, 16, new typ::Interface::•(d.[](25)));
- dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](26))]);
- dec::init(d, 18, new typ::Interface::•(d.[](19)));
- dec::init(d, 19, new typ::Interface::•(d.[](25)));
- dec::init(d, 20, null);
- dec::init(d, 22, new typ::Interface::•(d.[](20)));
- dec::init(d, 23, new typ::Interface::•(d.[](20)));
- dec::init(d, 24, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](24))])]);
- dec::init(d, 25, new typ::Interface::•(d.[](20)));
- dec::init(d, 26, new typ::Interface::•(d.[](20)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "R", "A", "B", "C", "D", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- tes::expectTrue(let dynamic #t1 = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t1 is int::HasRuntimeTypeGetter && #t1.$is$R && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t1.$type, #t2)));
- tes::expectTrue(let dynamic #t3 = new self::B::•(new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t3 is int::HasRuntimeTypeGetter && #t3.$is$R && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t3.$type, #t4)));
- tes::expectTrue(let dynamic #t5 = new self::C::•(new typ::Interface::•(self::$declarations.[](5), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t5 is int::HasRuntimeTypeGetter && #t5.$is$R && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t5.$type, #t6)));
- tes::expectTrue(let dynamic #t7 = new self::D::•(new typ::Interface::•(self::$declarations.[](6), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t7 is int::HasRuntimeTypeGetter && #t7.$is$R && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])]) in typ::isSubtypeOf(#t7.$type, #t8)));
- tes::expectTrue(!(let dynamic #t9 = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t9 is int::HasRuntimeTypeGetter && #t9.$is$R && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t9.$type, #t10))));
- tes::expectTrue(!(let dynamic #t11 = new self::B::•(new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t11 is int::HasRuntimeTypeGetter && #t11.$is$R && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t11.$type, #t12))));
- tes::expectTrue(!(let dynamic #t13 = new self::C::•(new typ::Interface::•(self::$declarations.[](5), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t13 is int::HasRuntimeTypeGetter && #t13.$is$R && (let dynamic #t14 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t13.$type, #t14))));
- tes::expectTrue(!(let dynamic #t15 = new self::D::•(new typ::Interface::•(self::$declarations.[](6), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t15 is int::HasRuntimeTypeGetter && #t15.$is$R && (let dynamic #t16 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])]) in typ::isSubtypeOf(#t15.$type, #t16))));
-}
diff --git a/pkg/kernel/testcases/reify/super1_test.dart b/pkg/kernel/testcases/reify/super1_test.dart
deleted file mode 100644
index bd007ff..0000000
--- a/pkg/kernel/testcases/reify/super1_test.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library super1_test;
-
-import 'test_base.dart';
-
-class A<T> {}
-
-class B<T> extends A<T> {
- int i;
- B(this.i) : super();
-
- B.redirect() : this(42);
-}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/super1_test.dart.expect b/pkg/kernel/testcases/reify/super1_test.dart.expect
deleted file mode 100644
index 3879cd4..0000000
--- a/pkg/kernel/testcases/reify/super1_test.dart.expect
+++ /dev/null
@@ -1,55 +0,0 @@
-library super1_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
- field core::int i;
- constructor •(typ::ReifiedType $type, core::int i) → void
- : self::B::i = let final mock::Context #context = int::attachType(new mock::Context::•(1), new typ::Interface::•(self::$declarations.[](2))) in let dynamic #t1 = #context.[]=(0, i) in #context.[](0), super self::A::•($type)
- ;
- constructor redirect(typ::ReifiedType $type) → void
- : this self::B::•($type, 42)
- ;
- get $B$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](16)));
- dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[d.[](1).variables.[](0)]));
- dec::init(d, 2, new typ::Interface::•(d.[](16)));
- dec::init(d, 3, new typ::Interface::•(d.[](16)));
- dec::init(d, 4, new typ::Interface::•(d.[](16)));
- dec::init(d, 5, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](5))]), new typ::Interface::•(d.[](19))]);
- dec::init(d, 6, new typ::Interface::•(d.[](20)));
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](16)));
- dec::init(d, 9, new typ::Interface::•(d.[](21)));
- dec::init(d, 10, new typ::Interface::•(d.[](21)));
- dec::init(d, 11, new typ::Interface::•(d.[](21)));
- dec::init(d, 12, new typ::Interface::•(d.[](21)));
- dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](22))]);
- dec::init(d, 14, new typ::Interface::•(d.[](15)));
- dec::init(d, 15, new typ::Interface::•(d.[](21)));
- dec::init(d, 16, null);
- dec::init(d, 18, new typ::Interface::•(d.[](16)));
- dec::init(d, 19, new typ::Interface::•(d.[](16)));
- dec::init(d, 20, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
- dec::init(d, 21, new typ::Interface::•(d.[](16)));
- dec::init(d, 22, new typ::Interface::•(d.[](16)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/super2_test.dart b/pkg/kernel/testcases/reify/super2_test.dart
deleted file mode 100644
index 0707d4a..0000000
--- a/pkg/kernel/testcases/reify/super2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library super2_test;
-
-import 'test_base.dart';
-
-class X {}
-
-class A<T> {}
-
-class B extends A<X> {}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/super2_test.dart.expect b/pkg/kernel/testcases/reify/super2_test.dart.expect
deleted file mode 100644
index eb95978..0000000
--- a/pkg/kernel/testcases/reify/super2_test.dart.expect
+++ /dev/null
@@ -1,57 +0,0 @@
-library super2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
-}
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::A::•(null)
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](2));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](16)));
- dec::init(d, 1, new typ::Interface::•(d.[](16)));
- dec::init(d, 2, new typ::Interface::•(d.[](1), <dynamic>[new typ::Interface::•(d.[](0))]));
- dec::init(d, 3, new typ::Interface::•(d.[](16)));
- dec::init(d, 4, new typ::Interface::•(d.[](16)));
- dec::init(d, 5, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](5))]), new typ::Interface::•(d.[](19))]);
- dec::init(d, 6, new typ::Interface::•(d.[](20)));
- dec::init(d, 7, new typ::Interface::•(d.[](20)));
- dec::init(d, 8, new typ::Interface::•(d.[](16)));
- dec::init(d, 9, new typ::Interface::•(d.[](21)));
- dec::init(d, 10, new typ::Interface::•(d.[](21)));
- dec::init(d, 11, new typ::Interface::•(d.[](21)));
- dec::init(d, 12, new typ::Interface::•(d.[](21)));
- dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](22))]);
- dec::init(d, 14, new typ::Interface::•(d.[](15)));
- dec::init(d, 15, new typ::Interface::•(d.[](21)));
- dec::init(d, 16, null);
- dec::init(d, 18, new typ::Interface::•(d.[](16)));
- dec::init(d, 19, new typ::Interface::•(d.[](16)));
- dec::init(d, 20, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
- dec::init(d, 21, new typ::Interface::•(d.[](16)));
- dec::init(d, 22, new typ::Interface::•(d.[](16)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/super3_test.dart b/pkg/kernel/testcases/reify/super3_test.dart
deleted file mode 100644
index 4de6a33..0000000
--- a/pkg/kernel/testcases/reify/super3_test.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library super3_test;
-
-import 'test_base.dart';
-
-class A<T> {
- get foo => T;
-}
-
-class B extends A<A> {
- B();
- B.redirect() : this();
-}
-
-main() {
- new B().foo;
- new B.redirect();
-}
diff --git a/pkg/kernel/testcases/reify/super3_test.dart.expect b/pkg/kernel/testcases/reify/super3_test.dart.expect
deleted file mode 100644
index 6ec46e7..0000000
--- a/pkg/kernel/testcases/reify/super3_test.dart.expect
+++ /dev/null
@@ -1,58 +0,0 @@
-library super3_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::A::$type = $type, super core::Object::•()
- ;
- get foo() → dynamic {
- return dynamic;
- }
- get $A$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get runtimeType() → core::Type
- return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super self::A::•(null)
- ;
- constructor redirect() → void
- : this self::B::•()
- ;
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](1));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](15)));
- dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[new typ::Interface::•(d.[](0), <dynamic>[const typ::Dynamic::•()])]));
- dec::init(d, 2, new typ::Interface::•(d.[](15)));
- dec::init(d, 3, new typ::Interface::•(d.[](15)));
- dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
- dec::init(d, 5, new typ::Interface::•(d.[](19)));
- dec::init(d, 6, new typ::Interface::•(d.[](19)));
- dec::init(d, 7, new typ::Interface::•(d.[](15)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)));
- dec::init(d, 10, new typ::Interface::•(d.[](20)));
- dec::init(d, 11, new typ::Interface::•(d.[](20)));
- dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
- dec::init(d, 13, new typ::Interface::•(d.[](14)));
- dec::init(d, 14, new typ::Interface::•(d.[](20)));
- dec::init(d, 15, null);
- dec::init(d, 17, new typ::Interface::•(d.[](15)));
- dec::init(d, 18, new typ::Interface::•(d.[](15)));
- dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
- dec::init(d, 20, new typ::Interface::•(d.[](15)));
- dec::init(d, 21, new typ::Interface::•(d.[](15)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- new self::B::•().{self::A::foo};
- new self::B::redirect();
-}
diff --git a/pkg/kernel/testcases/reify/test_base.dart b/pkg/kernel/testcases/reify/test_base.dart
deleted file mode 100644
index 696cb73..0000000
--- a/pkg/kernel/testcases/reify/test_base.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test_base;
-
-expectIs(expected, actual, [String note]) {
- if (expected != actual) {
- if (note != null) {
- throw "Expected: '$expected': $note, actual: '$actual'";
- }
- throw "Expected: '$expected', actual: '$actual'";
- }
-}
-
-expectTrue(actual) => expectIs(true, actual);
-
-expectFalse(actual) => expectIs(false, actual);
-
-expectThrows(f(), test(e)) {
- var exception = false;
- String note = null;
- try {
- f();
- } catch (e) {
- exception = test(e);
- if (!exception) {
- note = "$e [${e.runtimeType}]";
- }
- }
- expectIs(true, exception, note);
-}
-
-expectOutput(String expected) => expectIs(expected, output);
-
-String output;
-
-write(o) {
- output = output == null ? "$o" : "$output\n$o";
-}
diff --git a/pkg/kernel/testcases/reify/typevariable1_test.dart b/pkg/kernel/testcases/reify/typevariable1_test.dart
deleted file mode 100644
index 306a076..0000000
--- a/pkg/kernel/testcases/reify/typevariable1_test.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library typevariable1_test;
-
-import 'test_base.dart';
-
-class Z {
- get succ => new N<Z>();
-}
-
-class N<T> {
- get succ => new N<N<T>>();
- get pred => T;
-}
-
-main() {
- var one = new Z().succ;
- var two = one.succ;
-}
diff --git a/pkg/kernel/testcases/reify/typevariable1_test.dart.expect b/pkg/kernel/testcases/reify/typevariable1_test.dart.expect
deleted file mode 100644
index d6856ba..0000000
--- a/pkg/kernel/testcases/reify/typevariable1_test.dart.expect
+++ /dev/null
@@ -1,61 +0,0 @@
-library typevariable1_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class Z extends core::Object implements int::HasRuntimeTypeGetter {
- constructor •() → void
- : super core::Object::•()
- ;
- get succ() → dynamic {
- return new self::N::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]));
- }
- get $type() → typ::ReifiedType
- return new typ::Interface::•(self::$declarations.[](0));
-}
-class N extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::N::$type = $type, super core::Object::•()
- ;
- get succ() → dynamic {
- return new self::N::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](1), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))))]));
- }
- get pred() → dynamic {
- return dynamic;
- }
- get $N$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
- get runtimeType() → core::Type
- return this.{=self::N::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](15)));
- dec::init(d, 1, new typ::Interface::•(d.[](15)));
- dec::init(d, 2, new typ::Interface::•(d.[](15)));
- dec::init(d, 3, new typ::Interface::•(d.[](15)));
- dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
- dec::init(d, 5, new typ::Interface::•(d.[](19)));
- dec::init(d, 6, new typ::Interface::•(d.[](19)));
- dec::init(d, 7, new typ::Interface::•(d.[](15)));
- dec::init(d, 8, new typ::Interface::•(d.[](20)));
- dec::init(d, 9, new typ::Interface::•(d.[](20)));
- dec::init(d, 10, new typ::Interface::•(d.[](20)));
- dec::init(d, 11, new typ::Interface::•(d.[](20)));
- dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
- dec::init(d, 13, new typ::Interface::•(d.[](14)));
- dec::init(d, 14, new typ::Interface::•(d.[](20)));
- dec::init(d, 15, null);
- dec::init(d, 17, new typ::Interface::•(d.[](15)));
- dec::init(d, 18, new typ::Interface::•(d.[](15)));
- dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
- dec::init(d, 20, new typ::Interface::•(d.[](15)));
- dec::init(d, 21, new typ::Interface::•(d.[](15)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["Z", "N", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- dynamic one = new self::Z::•().{self::Z::succ};
- dynamic two = one.succ;
-}
diff --git a/pkg/kernel/testcases/reify/typevariable2_test.dart b/pkg/kernel/testcases/reify/typevariable2_test.dart
deleted file mode 100644
index 1b4a0cd..0000000
--- a/pkg/kernel/testcases/reify/typevariable2_test.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library typevariable2_test;
-
-import 'test_base.dart';
-
-class C<T> {
- bool test(o) => o is T;
- Type get t => T;
-}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/typevariable2_test.dart.expect b/pkg/kernel/testcases/reify/typevariable2_test.dart.expect
deleted file mode 100644
index d6a878f..0000000
--- a/pkg/kernel/testcases/reify/typevariable2_test.dart.expect
+++ /dev/null
@@ -1,65 +0,0 @@
-library typevariable2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::C::$type = $type, super core::Object::•()
- ;
- method test(dynamic o) → core::bool {
- return typ::isSubtypeOf(int::type(o), this.$C$T);
- }
- get t() → core::Type {
- return dynamic;
- }
- get test#get() → dynamic
- return new self::Closure#C#test::•(new typ::Interface::•(self::$declarations.[](1), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0)))), this);
- get $C$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get runtimeType() → core::Type
- return this.{=self::C::$type};
-}
-class Closure#C#test extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
- field core::String note = "This is temporary. The VM doesn't need closure classes.";
- field self::C self;
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type, final self::C self) → dynamic
- : self::Closure#C#test::$type = $type, self::Closure#C#test::self = self
- ;
- method call(dynamic o) → core::bool
- return this.{self::Closure#C#test::self}.{self::C::test}(o);
- get $Closure#C#test$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
- get runtimeType() → core::Type
- return this.{=self::Closure#C#test::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](15)));
- dec::init(d, 1, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17))], new typ::FunctionType::•(new typ::Interface::•(d.[](17)), new typ::Interface::•(d.[](3)), 0, <dynamic>[const typ::Dynamic::•()]));
- dec::init(d, 2, new typ::Interface::•(d.[](15)));
- dec::init(d, 3, new typ::Interface::•(d.[](15)));
- dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](19))]);
- dec::init(d, 5, new typ::Interface::•(d.[](20)));
- dec::init(d, 6, new typ::Interface::•(d.[](20)));
- dec::init(d, 7, new typ::Interface::•(d.[](15)));
- dec::init(d, 8, new typ::Interface::•(d.[](21)));
- dec::init(d, 9, new typ::Interface::•(d.[](21)));
- dec::init(d, 10, new typ::Interface::•(d.[](21)));
- dec::init(d, 11, new typ::Interface::•(d.[](21)));
- dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](22))]);
- dec::init(d, 13, new typ::Interface::•(d.[](14)));
- dec::init(d, 14, new typ::Interface::•(d.[](21)));
- dec::init(d, 15, null);
- dec::init(d, 17, new typ::Interface::•(d.[](15)));
- dec::init(d, 18, new typ::Interface::•(d.[](15)));
- dec::init(d, 19, new typ::Interface::•(d.[](15)));
- dec::init(d, 20, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
- dec::init(d, 21, new typ::Interface::•(d.[](15)));
- dec::init(d, 22, new typ::Interface::•(d.[](15)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "Closure#C#test", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/typevariable3_test.dart b/pkg/kernel/testcases/reify/typevariable3_test.dart
deleted file mode 100644
index f7ecef8..0000000
--- a/pkg/kernel/testcases/reify/typevariable3_test.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library typevariable3_test;
-
-import 'test_base.dart';
-
-class C<T> {
- T foo(T t) {
- T temp = t;
- return temp;
- }
-}
-
-main() {
- C c = new C<C>().foo(new C());
-}
diff --git a/pkg/kernel/testcases/reify/typevariable3_test.dart.expect b/pkg/kernel/testcases/reify/typevariable3_test.dart.expect
deleted file mode 100644
index a6f8ff2..0000000
--- a/pkg/kernel/testcases/reify/typevariable3_test.dart.expect
+++ /dev/null
@@ -1,50 +0,0 @@
-library typevariable3_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class C extends core::Object implements int::HasRuntimeTypeGetter {
- final field typ::ReifiedType $type;
- constructor •(typ::ReifiedType $type) → void
- : self::C::$type = $type, super core::Object::•()
- ;
- method foo(dynamic t) → dynamic {
- dynamic temp = t;
- return temp;
- }
- method foo$cc(core::Object t) → dynamic {
- return this.{=self::C::foo}(t as dynamic);
- }
- get $C$T() → typ::ReifiedType
- return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
- get runtimeType() → core::Type
- return this.{=self::C::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
- dec::init(d, 0, new typ::Interface::•(d.[](14)));
- dec::init(d, 1, new typ::Interface::•(d.[](14)));
- dec::init(d, 2, new typ::Interface::•(d.[](14)));
- dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](17))]);
- dec::init(d, 4, new typ::Interface::•(d.[](18)));
- dec::init(d, 5, new typ::Interface::•(d.[](18)));
- dec::init(d, 6, new typ::Interface::•(d.[](14)));
- dec::init(d, 7, new typ::Interface::•(d.[](19)));
- dec::init(d, 8, new typ::Interface::•(d.[](19)));
- dec::init(d, 9, new typ::Interface::•(d.[](19)));
- dec::init(d, 10, new typ::Interface::•(d.[](19)));
- dec::init(d, 11, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](20))]);
- dec::init(d, 12, new typ::Interface::•(d.[](13)));
- dec::init(d, 13, new typ::Interface::•(d.[](19)));
- dec::init(d, 14, null);
- dec::init(d, 16, new typ::Interface::•(d.[](14)));
- dec::init(d, 17, new typ::Interface::•(d.[](14)));
- dec::init(d, 18, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](18))])]);
- dec::init(d, 19, new typ::Interface::•(d.[](14)));
- dec::init(d, 20, new typ::Interface::•(d.[](14)));
- return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
- self::C c = new self::C::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])])).{self::C::foo}(new self::C::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])));
-}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 7b88bf2..a6d778d 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -169,10 +169,6 @@
front_end/test/incremental_dart2js_load_from_dill_test: StaticWarning
front_end/test/incremental_load_from_dill_test: StaticWarning
-# Don't analyze tests in strong mode yet
-[ $compiler == dart2analyzer && $strong ]
-*: Skip # Issue 28649
-
# Analyze dev_compiler but only run its tests on the vm
[ $compiler != dart2analyzer && $runtime != vm ]
dev_compiler/test/*: Skip
diff --git a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
index e37478c..f7e3357 100644
--- a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
@@ -285,14 +285,12 @@
String fileName;
int lastColon = text.lastIndexOf(':');
if (lastColon != -1) {
- int lastValue =
- int.parse(text.substring(lastColon + 1), onError: (_) => null);
+ int lastValue = int.tryParse(text.substring(lastColon + 1));
if (lastValue != null) {
int secondToLastColon = text.lastIndexOf(':', lastColon - 1);
if (secondToLastColon != -1) {
- int secondToLastValue = int.parse(
- text.substring(secondToLastColon + 1, lastColon),
- onError: (_) => null);
+ int secondToLastValue =
+ int.tryParse(text.substring(secondToLastColon + 1, lastColon));
if (secondToLastValue != null) {
lineNo = secondToLastValue;
columnNo = lastValue;
diff --git a/pkg/status_file/test/data/vm.status b/pkg/status_file/test/data/vm.status
index e446356..726d64e 100644
--- a/pkg/status_file/test/data/vm.status
+++ b/pkg/status_file/test/data/vm.status
@@ -217,6 +217,7 @@
cc/IsolateReload_KernelIncrementalCompile: Skip
cc/IsolateReload_KernelIncrementalCompileAppAndLib: Skip
cc/IsolateReload_KernelIncrementalCompileGenerics: Skip
+cc/IsolateReload_KernelIncrementalCompileExpression: Skip
cc/Mixin_PrivateSuperResolution: Skip
cc/Mixin_PrivateSuperResolutionCrossLibraryShouldFail: Skip
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index 0a2e4a2..16212bf 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -8,14 +8,14 @@
import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:front_end/src/api_prototype/front_end.dart';
import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/kernel.dart' show Component;
import 'package:kernel/src/tool/batch_util.dart' as batch_util;
import 'package:kernel/target/targets.dart' show TargetFlags;
import 'package:kernel/target/vm.dart' show VmTarget;
import 'package:kernel/text/ast_to_text.dart'
show globalDebuggingNames, NameSystem;
import 'package:vm/bytecode/gen_bytecode.dart' show isKernelBytecodeEnabled;
-import 'package:vm/kernel_front_end.dart' show compileToKernel, ErrorDetector;
+import 'package:vm/kernel_front_end.dart'
+ show compileToKernel, ErrorDetector, ErrorPrinter;
final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
..addOption('platform',
@@ -36,10 +36,20 @@
help:
'Enable global type flow analysis and related transformations in AOT mode.',
defaultsTo: true)
+ ..addMultiOption('define',
+ abbr: 'D',
+ help: 'The values for the environment constants (e.g. -Dkey=value).')
+ ..addFlag('enable-asserts',
+ help: 'Whether asserts will be enabled.', defaultsTo: false)
+ ..addFlag('enable-constant-evaluation',
+ help: 'Whether kernel constant evaluation will be enabled.',
+ defaultsTo: true)
..addMultiOption('entry-points',
help: 'Path to JSON file with the list of entry points')
..addFlag('gen-bytecode',
- help: 'Generate bytecode', defaultsTo: isKernelBytecodeEnabled);
+ help: 'Generate bytecode', defaultsTo: isKernelBytecodeEnabled)
+ ..addFlag('drop-ast',
+ help: 'Drop AST for members with bytecode', defaultsTo: false);
final String _usage = '''
Usage: dart pkg/vm/bin/gen_kernel.dart --platform vm_platform_strong.dill [options] input.dart
@@ -77,6 +87,14 @@
final bool syncAsync = options['sync-async'];
final bool tfa = options['tfa'];
final bool genBytecode = options['gen-bytecode'];
+ final bool dropAST = options['drop-ast'];
+ final bool enableAsserts = options['enable-asserts'];
+ final bool enableConstantEvaluation = options['enable-constant-evaluation'];
+ final Map<String, String> environmentDefines = {};
+
+ if (!_parseDefines(options['define'], environmentDefines)) {
+ return _badUsageExitCode;
+ }
final List<String> entryPoints = options['entry-points'] ?? <String>[];
if (entryPoints.isEmpty) {
@@ -87,7 +105,8 @@
]);
}
- ErrorDetector errorDetector = new ErrorDetector();
+ final errorPrinter = new ErrorPrinter();
+ final errorDetector = new ErrorDetector(previousErrorHandler: errorPrinter);
final CompilerOptions compilerOptions = new CompilerOptions()
..strongMode = strongMode
@@ -99,15 +118,22 @@
..packagesFileUri =
packages != null ? Uri.base.resolveUri(new Uri.file(packages)) : null
..reportMessages = true
- ..onError = errorDetector
+ ..onProblem = errorDetector
..embedSourceText = options['embed-sources'];
- Component component = await compileToKernel(
- Uri.base.resolveUri(new Uri.file(filename)), compilerOptions,
+ final inputUri = new Uri.file(filename);
+ final component = await compileToKernel(
+ Uri.base.resolveUri(inputUri), compilerOptions,
aot: aot,
useGlobalTypeFlowAnalysis: tfa,
entryPoints: entryPoints,
- genBytecode: genBytecode);
+ environmentDefines: environmentDefines,
+ genBytecode: genBytecode,
+ dropAST: dropAST,
+ enableAsserts: enableAsserts,
+ enableConstantEvaluation: enableConstantEvaluation);
+
+ errorPrinter.printCompilationMessages(inputUri);
if (errorDetector.hasCompilationErrors || (component == null)) {
return _compileTimeErrorExitCode;
@@ -152,3 +178,22 @@
}
});
}
+
+bool _parseDefines(
+ List<String> dFlags, Map<String, String> environmentDefines) {
+ for (final String dflag in dFlags) {
+ final equalsSignIndex = dflag.indexOf('=');
+ if (equalsSignIndex < 0) {
+ environmentDefines[dflag] = '';
+ } else if (equalsSignIndex > 0) {
+ final key = dflag.substring(0, equalsSignIndex);
+ final value = dflag.substring(equalsSignIndex + 1);
+ environmentDefines[key] = value;
+ } else {
+ print('The environment constant options must have a key (was: "$dflag")');
+ print(_usage);
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 329b554..0590e39 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -33,7 +33,7 @@
show computePlatformBinariesLocation;
import 'package:front_end/src/fasta/kernel/utils.dart';
import 'package:front_end/src/fasta/hybrid_file_system.dart';
-import 'package:kernel/kernel.dart' show Component;
+import 'package:kernel/kernel.dart' show Component, Procedure;
import 'package:kernel/target/targets.dart' show TargetFlags;
import 'package:kernel/target/vm.dart' show VmTarget;
import 'package:vm/incremental_compiler.dart';
@@ -49,10 +49,15 @@
// 1 - Update in-memory file system with in-memory sources (used by tests).
// 2 - Accept last compilation result.
// 3 - APP JIT snapshot training run for kernel_service.
+// 4 - Compile an individual expression in some context (for debugging
+// purposes).
const int kCompileTag = 0;
const int kUpdateSourcesTag = 1;
const int kAcceptTag = 2;
const int kTrainTag = 3;
+const int kCompileExpressionTag = 4;
+
+bool allowDartInternalImport = false;
abstract class Compiler {
final FileSystem fileSystem;
@@ -177,9 +182,10 @@
}
}
-final Map<int, Compiler> isolateCompilers = new Map<int, Compiler>();
+final Map<int, IncrementalCompilerWrapper> isolateCompilers =
+ new Map<int, IncrementalCompilerWrapper>();
-Compiler lookupIncrementalCompiler(int isolateId) {
+IncrementalCompilerWrapper lookupIncrementalCompiler(int isolateId) {
return isolateCompilers[isolateId];
}
@@ -242,10 +248,60 @@
// Process a request from the runtime. See KernelIsolate::CompileToKernel in
// kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
+Future _processExpressionCompilationRequest(request) async {
+ final SendPort port = request[1];
+ final int isolateId = request[2];
+ final String expression = request[3];
+ final List definitions = request[4];
+ final List typeDefinitions = request[5];
+ final String libraryUri = request[6];
+ final String klass = request[7]; // might be null
+ final bool isStatic = request[8];
+
+ IncrementalCompilerWrapper compiler = isolateCompilers[isolateId];
+
+ if (compiler == null) {
+ port.send(new CompilationResult.errors(
+ ["No incremental compiler available for this isolate."]).toResponse());
+ return;
+ }
+
+ compiler.errors.clear();
+
+ CompilationResult result;
+ try {
+ Procedure procedure = await compiler.generator.compileExpression(
+ expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
+
+ if (procedure == null) {
+ port.send(new CompilationResult.errors(["Invalid scope."]).toResponse());
+ return;
+ }
+
+ if (compiler.errors.isNotEmpty) {
+ // TODO(sigmund): the compiler prints errors to the console, so we
+ // shouldn't print those messages again here.
+ result = new CompilationResult.errors(compiler.errors);
+ } else {
+ result = new CompilationResult.ok(serializeProcedure(procedure));
+ }
+ } catch (error, stack) {
+ result = new CompilationResult.crash(error, stack);
+ }
+
+ port.send(result.toResponse());
+}
+
Future _processLoadRequest(request) async {
if (verbose) print("DFE: request: $request");
int tag = request[0];
+
+ if (tag == kCompileExpressionTag) {
+ await _processExpressionCompilationRequest(request);
+ return;
+ }
+
final SendPort port = request[1];
final String inputFileUri = request[2];
final Uri script =
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index ac3b157..fdf239e 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -7,6 +7,7 @@
import 'dart:typed_data';
import 'package:vm/bytecode/dbc.dart';
+import 'package:vm/bytecode/exceptions.dart' show ExceptionsTable;
class Label {
List<int> _jumps = <int>[];
@@ -42,6 +43,7 @@
final List<int> bytecode = new List<int>();
final Uint32List _encodeBufferIn;
final Uint8List _encodeBufferOut;
+ final ExceptionsTable exceptionsTable = new ExceptionsTable();
BytecodeAssembler._(this._encodeBufferIn, this._encodeBufferOut);
@@ -51,6 +53,7 @@
}
int get offset => bytecode.length;
+ int get offsetInWords => bytecode.length >> kLog2BytesPerBytecode;
void bind(Label label) {
final List<int> jumps = label.bind(offset);
@@ -819,8 +822,8 @@
emitWord(_encode0(Opcode.kCloneContext));
}
- void emitMoveSpecial(int ra, int rd) {
- emitWord(_encodeAD(Opcode.kMoveSpecial, ra, rd));
+ void emitMoveSpecial(int ra, SpecialIndex rd) {
+ emitWord(_encodeAD(Opcode.kMoveSpecial, ra, rd.index));
}
void emitInstantiateType(int rd) {
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
index 958c7c6..0b3cb58 100644
--- a/pkg/vm/lib/bytecode/constant_pool.dart
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -7,6 +7,7 @@
import 'dart:typed_data';
import 'package:kernel/ast.dart' hide MapEntry;
+import 'package:kernel/text/ast_to_text.dart' show Printer;
/*
@@ -95,24 +96,24 @@
type ConstantType extends ConstantPoolEntry {
Byte tag = 14;
- NodeReference type;
+ DartType type;
}
type ConstantTypeArguments extends ConstantPoolEntry {
Byte tag = 15;
- List<NodeReference> types;
+ List<DartType> types;
}
type ConstantList extends ConstantPoolEntry {
Byte tag = 16;
- NodeReference typeArg;
+ DartType typeArg;
List<ConstantIndex> entries;
}
type ConstantInstance extends ConstantPoolEntry {
Byte tag = 17;
CanonicalNameReference class;
- UInt typeArgumentsConstantIndex;
+ ConstantIndex typeArguments;
List<Pair<CanonicalNameReference, ConstantIndex>> fieldValues;
}
@@ -127,6 +128,23 @@
ConstantIndex typeArguments;
}
+type ConstantContextOffset extends ConstantPoolEntry {
+ Byte tag = 20;
+ // 0 = Offset of 'parent' field in Context object.
+ // 1 + i = Offset of i-th variable in Context object.
+ UInt index;
+}
+
+type ConstantClosureFunction extends ConstantPoolEntry {
+ Byte tag = 21;
+ StringReference name;
+ FunctionNode function; // Doesn't have a body.
+}
+
+type ConstantEndClosureFunctionScope extends ConstantPoolEntry {
+ Byte tag = 22;
+}
+
*/
enum ConstantTag {
@@ -150,6 +168,9 @@
kInstance,
kSymbol,
kTypeArgumentsForInstanceAllocation,
+ kContextOffset,
+ kClosureFunction,
+ kEndClosureFunctionScope,
}
abstract class ConstantPoolEntry {
@@ -208,6 +229,12 @@
case ConstantTag.kTypeArgumentsForInstanceAllocation:
return new ConstantTypeArgumentsForInstanceAllocation.readFromBinary(
source);
+ case ConstantTag.kContextOffset:
+ return new ConstantContextOffset.readFromBinary(source);
+ case ConstantTag.kClosureFunction:
+ return new ConstantClosureFunction.readFromBinary(source);
+ case ConstantTag.kEndClosureFunctionScope:
+ return new ConstantEndClosureFunctionScope.readFromBinary(source);
}
throw 'Unexpected constant tag $tag';
}
@@ -641,11 +668,11 @@
@override
void writeValueToBinary(BinarySink sink) {
- sink.writeNodeReference(type);
+ sink.writeDartType(type);
}
ConstantType.readFromBinary(BinarySource source)
- : type = source.readNodeReference() as DartType;
+ : type = source.readDartType();
@override
String toString() => 'Type $type';
@@ -668,12 +695,12 @@
@override
void writeValueToBinary(BinarySink sink) {
sink.writeUInt30(typeArgs.length);
- typeArgs.forEach(sink.writeNodeReference);
+ typeArgs.forEach(sink.writeDartType);
}
ConstantTypeArguments.readFromBinary(BinarySource source)
: typeArgs = new List<DartType>.generate(
- source.readUInt(), (_) => source.readNodeReference() as DartType);
+ source.readUInt(), (_) => source.readDartType());
@override
String toString() => 'TypeArgs $typeArgs';
@@ -698,13 +725,13 @@
@override
void writeValueToBinary(BinarySink sink) {
- sink.writeNodeReference(typeArg);
+ sink.writeDartType(typeArg);
sink.writeUInt30(entries.length);
entries.forEach(sink.writeUInt30);
}
ConstantList.readFromBinary(BinarySource source)
- : typeArg = source.readNodeReference() as DartType,
+ : typeArg = source.readDartType(),
entries =
new List<int>.generate(source.readUInt(), (_) => source.readUInt());
@@ -853,6 +880,90 @@
this._typeArgumentsConstantIndex == other._typeArgumentsConstantIndex;
}
+class ConstantContextOffset extends ConstantPoolEntry {
+ static const int kParent = 0;
+ static const int kVariableBase = 1;
+
+ final int _index;
+
+ ConstantContextOffset._(this._index);
+ ConstantContextOffset.parent() : this._(kParent);
+ ConstantContextOffset.variable(int index) : this._(index + kVariableBase);
+
+ @override
+ ConstantTag get tag => ConstantTag.kContextOffset;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeUInt30(_index);
+ }
+
+ ConstantContextOffset.readFromBinary(BinarySource source)
+ : _index = source.readUInt();
+
+ @override
+ String toString() =>
+ 'ContextOffset ${_index == kParent ? 'parent' : 'var [${_index - kVariableBase}]'}';
+
+ @override
+ int get hashCode => _index;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantContextOffset && this._index == other._index;
+}
+
+class ConstantClosureFunction extends ConstantPoolEntry {
+ final String name;
+ final FunctionNode function;
+
+ ConstantClosureFunction(this.name, this.function);
+
+ @override
+ ConstantTag get tag => ConstantTag.kClosureFunction;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ assert(function.body == null);
+ sink.writeStringReference(name);
+ sink.writeNode(function);
+ }
+
+ ConstantClosureFunction.readFromBinary(BinarySource source)
+ : name = source.readStringReference(),
+ function = source.readFunctionNode();
+
+ @override
+ String toString() {
+ StringBuffer buffer = new StringBuffer();
+ new Printer(buffer).writeFunction(function);
+ return 'ClosureFunction $name ${buffer.toString().trim()}';
+ }
+
+ // ConstantClosureFunction entries are created per closure and should not
+ // be merged, so ConstantClosureFunction class uses identity [hashCode] and
+ // [operator ==].
+}
+
+class ConstantEndClosureFunctionScope extends ConstantPoolEntry {
+ ConstantEndClosureFunctionScope();
+
+ @override
+ ConstantTag get tag => ConstantTag.kEndClosureFunctionScope;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {}
+
+ ConstantEndClosureFunctionScope.readFromBinary(BinarySource source) {}
+
+ @override
+ String toString() => 'EndClosureFunctionScope';
+
+ // ConstantEndClosureFunctionScope entries are created per closure and should
+ // not be merged, so ConstantEndClosureFunctionScope class uses identity
+ // [hashCode] and [operator ==].
+}
+
class ConstantPool {
final List<ConstantPoolEntry> entries = <ConstantPoolEntry>[];
final Map<ConstantPoolEntry, int> _canonicalizationCache =
@@ -868,17 +979,58 @@
});
}
- void writeToBinary(BinarySink sink) {
+ void writeToBinary(Node node, BinarySink sink) {
+ final function = (node as Member).function;
+ sink.enterScope(
+ typeParameters: function?.typeParameters, memberScope: true);
+
+ final closureStack = <ConstantClosureFunction>[];
+
sink.writeUInt30(entries.length);
entries.forEach((e) {
e.writeToBinary(sink);
+
+ if (e is ConstantClosureFunction) {
+ sink.enterScope(typeParameters: e.function.typeParameters);
+ closureStack.add(e);
+ } else if (e is ConstantEndClosureFunctionScope) {
+ sink.leaveScope(
+ typeParameters: closureStack.removeLast().function.typeParameters);
+ }
});
+
+ assert(closureStack.isEmpty);
+
+ sink.leaveScope(
+ typeParameters: function?.typeParameters, memberScope: true);
}
- ConstantPool.readFromBinary(BinarySource source) {
+ ConstantPool.readFromBinary(Node node, BinarySource source) {
+ final function = (node as Member).function;
+ if (function != null) {
+ source.enterScope(typeParameters: function.typeParameters);
+ }
+
+ final closureStack = <ConstantClosureFunction>[];
+
int len = source.readUInt();
for (int i = 0; i < len; i++) {
- entries.add(new ConstantPoolEntry.readFromBinary(source));
+ final e = new ConstantPoolEntry.readFromBinary(source);
+ entries.add(e);
+
+ if (e is ConstantClosureFunction) {
+ source.enterScope(typeParameters: e.function.typeParameters);
+ closureStack.add(e);
+ } else if (e is ConstantEndClosureFunctionScope) {
+ source.leaveScope(
+ typeParameters: closureStack.removeLast().function.typeParameters);
+ }
+ }
+
+ assert(closureStack.isEmpty);
+
+ if (function != null) {
+ source.leaveScope(typeParameters: function.typeParameters);
}
}
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 17c68c3..6f48e18 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -7,8 +7,9 @@
// List of changes from original DBC (described in runtime/vm/constants_dbc.h):
//
// 1. StoreFieldTOS, LoadFieldTOS instructions:
-// D = index of constant pool entry with FieldOffset or
-// TypeArgumentsFieldOffset tags (instead of field offset in words).
+// D = index of constant pool entry with FieldOffset,
+// TypeArgumentsFieldOffset or ConstantContextOffset tags
+// (instead of field offset in words).
//
// 2. EntryOptional instruction is revived in order to re-shuffle optional
// parameters. This DBC instruction was removed at
@@ -182,6 +183,7 @@
kBooleanNegate,
kThrow,
kEntry,
+ kEntryOptional,
kEntryOptimized,
kFrame,
kSetFrame,
@@ -212,7 +214,6 @@
kDebugBreak,
kDeopt,
kDeoptRewind,
- kEntryOptional,
}
enum Encoding {
@@ -234,6 +235,7 @@
reg, // register (unsigned FP relative local)
xeg, // x-register (signed FP relative local)
tgt, // jump target relative to the PC of the current instruction
+ spe, // SpecialIndex
}
class Format {
@@ -588,7 +590,7 @@
Opcode.kCloneContext: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kMoveSpecial: const Format(
- Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+ Encoding.kAD, const [Operand.reg, Operand.spe, Operand.none]),
Opcode.kInstantiateType: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
Opcode.kInstantiateTypeArgumentsTOS: const Format(
@@ -649,3 +651,8 @@
// Prefix used to distinguish setters in ICData target names.
// Should match constant in runtime/vm/object.cc.
const String kSetterPrefix = 'set:';
+
+enum SpecialIndex {
+ exception,
+ stackTrace,
+}
diff --git a/pkg/vm/lib/bytecode/disassembler.dart b/pkg/vm/lib/bytecode/disassembler.dart
index 9230268..279d492 100644
--- a/pkg/vm/lib/bytecode/disassembler.dart
+++ b/pkg/vm/lib/bytecode/disassembler.dart
@@ -7,6 +7,7 @@
import 'dart:typed_data';
import 'package:vm/bytecode/dbc.dart';
+import 'package:vm/bytecode/exceptions.dart';
class _Instruction {
final Opcode opcode;
@@ -20,11 +21,13 @@
List<_Instruction> _instructions;
int _labelCount;
- Map<int, int> _labels;
+ Map<int, String> _labels;
+ Map<int, List<String>> _markers;
- String disassemble(List<int> bytecode) {
+ String disassemble(List<int> bytecode, ExceptionsTable exceptionsTable) {
_init(bytecode);
_scanForJumpTargets();
+ _markTryBlocks(exceptionsTable);
return _disasm();
}
@@ -39,7 +42,8 @@
}
_labelCount = 0;
- _labels = <int, int>{};
+ _labels = <int, String>{};
+ _markers = <int, List<String>>{};
}
_Instruction _decodeInstruction(int word) {
@@ -94,17 +98,35 @@
if (instr.opcode == Opcode.kJump) {
final target = i + instr.operands[0];
assert(0 <= target && target < _instructions.length);
- _labels[target] ??= (++_labelCount);
+ if (!_labels.containsKey(target)) {
+ final label = 'L${++_labelCount}';
+ _labels[target] = label;
+ _addMarker(target, '$label:');
+ }
}
}
}
+ void _markTryBlocks(ExceptionsTable exceptionsTable) {
+ for (var tryBlock in exceptionsTable.blocks) {
+ final int tryIndex = tryBlock.tryIndex;
+ _addMarker(tryBlock.startPC, 'Try #$tryIndex start:');
+ _addMarker(tryBlock.endPC, 'Try #$tryIndex end:');
+ _addMarker(tryBlock.handlerPC, 'Try #$tryIndex handler:');
+ }
+ }
+
+ void _addMarker(int pc, String marker) {
+ final markers = (_markers[pc] ??= <String>[]);
+ markers.add(marker);
+ }
+
String _disasm() {
StringBuffer out = new StringBuffer();
for (int i = 0; i < _instructions.length; i++) {
- int label = _labels[i];
- if (label != null) {
- out.writeln('L$label:');
+ List<String> markers = _markers[i];
+ if (markers != null) {
+ markers.forEach(out.writeln);
}
_writeInstruction(out, i, _instructions[i]);
}
@@ -158,7 +180,11 @@
case Operand.xeg:
return (value < 0) ? 'FP[$value]' : 'r$value';
case Operand.tgt:
- return 'L${_labels[bci + value] ?? (throw 'Label not found')}';
+ return _labels[bci + value] ?? (throw 'Label not found');
+ case Operand.spe:
+ return SpecialIndex.values[value]
+ .toString()
+ .substring('SpecialIndex.'.length);
}
throw 'Unexpected operand format $fmt';
}
diff --git a/pkg/vm/lib/bytecode/exceptions.dart b/pkg/vm/lib/bytecode/exceptions.dart
new file mode 100644
index 0000000..7c955a3
--- /dev/null
+++ b/pkg/vm/lib/bytecode/exceptions.dart
@@ -0,0 +1,139 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library vm.bytecode.exceptions;
+
+import 'package:kernel/ast.dart' show BinarySink, BinarySource;
+
+/*
+
+In kernel binary, try blocks are encoded in the following way
+(using notation from pkg/kernel/binary.md):
+
+// Offset of a bytecode instruction, in DBC words.
+type BytecodeOffset = UInt;
+
+type TryBlock {
+ UInt outerTryIndexPlus1;
+ BytecodeOffset startPC; // Inclusive.
+ BytecodeOffset endPC; // Exclusive.
+ BytecodeOffset handlerPC;
+ Byte flags (needsStackTrace, isSynthetic);
+ List<ConstantIndex> types;
+}
+
+type ExceptionsTable {
+ // Ordered by startPC, then by nesting (outer precedes inner).
+ // Try blocks are properly nested. It means there are no partially
+ // overlapping try blocks - each pair of try block regions either
+ // has no intersection or one try block region encloses another.
+ List<TryBlock> tryBlocks;
+}
+
+*/
+
+class TryBlock {
+ static const int flagNeedsStackTrace = 1 << 0;
+ static const int flagIsSynthetic = 1 << 1;
+
+ final int tryIndex;
+ final int outerTryIndex;
+ final int startPC;
+ int endPC;
+ int handlerPC;
+ int flags = 0;
+ List<int> types = <int>[];
+
+ TryBlock._(this.tryIndex, this.outerTryIndex, this.startPC);
+
+ bool get needsStackTrace => (flags & flagNeedsStackTrace) != 0;
+
+ void set needsStackTrace(bool value) {
+ flags = (flags & ~flagNeedsStackTrace) | (value ? flagNeedsStackTrace : 0);
+ }
+
+ bool get isSynthetic => (flags & flagIsSynthetic) != 0;
+
+ void set isSynthetic(bool value) {
+ flags = (flags & ~flagIsSynthetic) | (value ? flagIsSynthetic : 0);
+ }
+
+ void writeToBinary(BinarySink sink) {
+ sink.writeUInt30(outerTryIndex + 1);
+ sink.writeUInt30(startPC);
+ sink.writeUInt30(endPC);
+ sink.writeUInt30(handlerPC);
+ sink.writeByte(flags);
+ sink.writeUInt30(types.length);
+ types.forEach(sink.writeUInt30);
+ }
+
+ factory TryBlock.readFromBinary(BinarySource source, int tryIndex) {
+ final outerTryIndex = source.readUInt() - 1;
+ final startPC = source.readUInt();
+ final tryBlock = new TryBlock._(tryIndex, outerTryIndex, startPC);
+
+ tryBlock.endPC = source.readUInt();
+ tryBlock.handlerPC = source.readUInt();
+ tryBlock.flags = source.readByte();
+ tryBlock.types =
+ new List<int>.generate(source.readUInt(), (_) => source.readUInt());
+
+ return tryBlock;
+ }
+
+ @override
+ String toString() => 'try-index $tryIndex, outer $outerTryIndex, '
+ 'start $startPC, end $endPC, handler $handlerPC, '
+ '${needsStackTrace ? 'needs-stack-trace, ' : ''}'
+ '${isSynthetic ? 'synthetic, ' : ''}'
+ 'types ${types.map((t) => 'CP#$t').toList()}';
+}
+
+class ExceptionsTable {
+ List<TryBlock> blocks = <TryBlock>[];
+
+ ExceptionsTable();
+
+ TryBlock enterTryBlock(int startPC) {
+ assert(blocks.isEmpty || blocks.last.startPC <= startPC);
+ final tryBlock =
+ new TryBlock._(blocks.length, _outerTryBlockIndex(startPC), startPC);
+ blocks.add(tryBlock);
+ return tryBlock;
+ }
+
+ int _outerTryBlockIndex(int startPC) {
+ for (int i = blocks.length - 1; i >= 0; --i) {
+ final tryBlock = blocks[i];
+ if (tryBlock.endPC == null || tryBlock.endPC > startPC) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ void writeToBinary(BinarySink sink) {
+ sink.writeUInt30(blocks.length);
+ blocks.forEach((b) => b.writeToBinary(sink));
+ }
+
+ ExceptionsTable.readFromBinary(BinarySource source)
+ : blocks = new List<TryBlock>.generate(source.readUInt(),
+ (int index) => new TryBlock.readFromBinary(source, index));
+
+ @override
+ String toString() {
+ if (blocks.isEmpty) {
+ return '';
+ }
+ StringBuffer sb = new StringBuffer();
+ sb.writeln('ExceptionsTable {');
+ for (var tryBlock in blocks) {
+ sb.writeln(' $tryBlock');
+ }
+ sb.writeln('}');
+ return sb.toString();
+ }
+}
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 988a721..8d189b7 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -6,6 +6,7 @@
import 'package:kernel/ast.dart' hide MapEntry;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/clone.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/library_index.dart' show LibraryIndex;
import 'package:kernel/transformations/constants.dart'
@@ -16,6 +17,7 @@
import 'package:vm/bytecode/assembler.dart';
import 'package:vm/bytecode/constant_pool.dart';
import 'package:vm/bytecode/dbc.dart';
+import 'package:vm/bytecode/exceptions.dart';
import 'package:vm/bytecode/local_vars.dart' show LocalVariables;
import 'package:vm/metadata/bytecode.dart';
@@ -27,7 +29,8 @@
const bool isTraceEnabled = false;
-void generateBytecode(Component component, {bool strongMode: true}) {
+void generateBytecode(Component component,
+ {bool strongMode: true, bool dropAST: false}) {
final coreTypes = new CoreTypes(component);
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
final hierarchy = new ClassHierarchy(component,
@@ -38,6 +41,9 @@
new BytecodeGenerator(component, coreTypes, hierarchy, typeEnvironment,
constantsBackend, strongMode)
.visitComponent(component);
+ if (dropAST) {
+ new DropAST().visitComponent(component);
+ }
}
class BytecodeGenerator extends RecursiveVisitor<Null> {
@@ -51,13 +57,18 @@
Class enclosingClass;
Member enclosingMember;
- BytecodeAssembler asm;
- ConstantPool cp;
LocalVariables locals;
- ConstantEmitter constantEmitter;
ConstantEvaluator constantEvaluator;
Map<LabeledStatement, Label> labeledStatements;
Map<SwitchCase, Label> switchCases;
+ Map<TryCatch, TryBlock> tryCatches;
+ Map<TryFinally, List<FinallyBlock>> finallyBlocks;
+ Map<TreeNode, int> contextLevels;
+ List<ClosureBytecode> closures;
+ ConstantPool cp;
+ ConstantEmitter constantEmitter;
+ BytecodeAssembler asm;
+ List<BytecodeAssembler> savedAssemblers;
BytecodeGenerator(this.component, this.coreTypes, this.hierarchy,
this.typeEnvironment, this.constantsBackend, this.strongMode) {
@@ -140,6 +151,32 @@
Procedure get interpolate => _interpolate ??=
libraryIndex.getMember('dart:core', '_StringBase', '_interpolate');
+ Class _closureClass;
+ Class get closureClass =>
+ _closureClass ??= libraryIndex.getClass('dart:core', '_Closure');
+
+ Field _closureInstantiatorTypeArguments;
+ Field get closureInstantiatorTypeArguments =>
+ _closureInstantiatorTypeArguments ??= libraryIndex.getMember(
+ 'dart:core', '_Closure', '_instantiator_type_arguments');
+
+ Field _closureFunctionTypeArguments;
+ Field get closureFunctionTypeArguments =>
+ _closureFunctionTypeArguments ??= libraryIndex.getMember(
+ 'dart:core', '_Closure', '_function_type_arguments');
+
+ Field _closureFunction;
+ Field get closureFunction => _closureFunction ??=
+ libraryIndex.getMember('dart:core', '_Closure', '_function');
+
+ Field _closureContext;
+ Field get closureContext => _closureContext ??=
+ libraryIndex.getMember('dart:core', '_Closure', '_context');
+
+ Procedure _prependTypeArguments;
+ Procedure get prependTypeArguments => _prependTypeArguments ??=
+ libraryIndex.getTopLevelMember('dart:_internal', '_prependTypeArguments');
+
void _genConstructorInitializers(Constructor node) {
bool isRedirecting =
node.initializers.any((init) => init is RedirectingInitializer);
@@ -161,7 +198,7 @@
return;
}
- asm.emitPush(locals.thisVarIndex);
+ _genPushReceiver();
initializer.accept(this);
// TODO(alexmarkov): assignability check
@@ -233,11 +270,6 @@
(c.superclass != null && hasInstantiatorTypeArguments(c.superclass));
}
- bool isGenericFunction(Member member) {
- final function = member.function;
- return function != null && function.typeParameters.isNotEmpty;
- }
-
void _genTypeArguments(List<DartType> typeArgs, {Class instantiatingClass}) {
int typeArgsCPIndex = cp.add(new ConstantTypeArguments(typeArgs));
if (instantiatingClass != null) {
@@ -261,10 +293,10 @@
}
void _genPushInstantiatorTypeArguments() {
- // TODO(alexmarkov): access from closures to up-level type arguments.
+ // TODO(alexmarkov): access to type arguments in factory constructors.
if ((enclosingMember.isInstanceMember || enclosingMember is Constructor) &&
hasInstantiatorTypeArguments(enclosingClass)) {
- asm.emitPush(locals.thisVarIndex);
+ _genPushReceiver();
final int cpIndex =
cp.add(new ConstantTypeArgumentsFieldOffset(enclosingClass));
asm.emitLoadFieldTOS(cpIndex);
@@ -274,14 +306,62 @@
}
void _genPushFunctionTypeArguments() {
- // TODO(alexmarkov): closures
- if (isGenericFunction(enclosingMember)) {
- asm.emitPush(locals.functionTypeArgsVarIndex);
+ if (locals.hasTypeArgsVar) {
+ asm.emitPush(locals.typeArgsVarIndexInFrame);
} else {
_genPushNull();
}
}
+ void _genPushContextForVariable(VariableDeclaration variable) {
+ int depth =
+ locals.currentContextLevel - locals.getContextLevelOfVar(variable);
+ assert(depth >= 0);
+
+ asm.emitPush(locals.contextVarIndexInFrame);
+ if (depth > 0) {
+ int cpIndex = cp.add(new ConstantContextOffset.parent());
+ for (; depth > 0; --depth) {
+ asm.emitLoadFieldTOS(cpIndex);
+ }
+ }
+ }
+
+ void _genPushContextIfCaptured(VariableDeclaration variable) {
+ if (locals.isCaptured(variable)) {
+ _genPushContextForVariable(variable);
+ }
+ }
+
+ void _genLoadVar(VariableDeclaration v) {
+ if (locals.isCaptured(v)) {
+ _genPushContextForVariable(v);
+ final int cpIndex = cp.add(
+ new ConstantContextOffset.variable(locals.getVarIndexInContext(v)));
+ asm.emitLoadFieldTOS(cpIndex);
+ } else {
+ asm.emitPush(locals.getVarIndexInFrame(v));
+ }
+ }
+
+ void _genPushReceiver() {
+ // TODO(alexmarkov): generate more efficient access to receiver
+ // even if it is captured.
+ _genLoadVar(locals.receiverVar);
+ }
+
+ // Stores value into variable.
+ // If variable is captured, context should be pushed before value.
+ void _genStoreVar(VariableDeclaration variable) {
+ if (locals.isCaptured(variable)) {
+ final int cpIndex = cp.add(new ConstantContextOffset.variable(
+ locals.getVarIndexInContext(variable)));
+ asm.emitStoreFieldTOS(cpIndex);
+ } else {
+ asm.emitPopLocal(locals.getVarIndexInFrame(variable));
+ }
+ }
+
/// Generates bool condition. Returns `true` if condition is negated.
bool _genCondition(Node condition) {
bool negated = false;
@@ -304,34 +384,116 @@
asm.emitJump(dest); // ... then jump dest
}
- // Duplicates value on top of the stack using temporary variable
- // corresponding to [node].
- void _genDupTOS(TreeNode node) {
+ void _genJumpIfTrue(bool negated, Label dest) {
+ _genJumpIfFalse(!negated, dest);
+ }
+
+ int _getDefaultParamConstIndex(VariableDeclaration param) {
+ if (param.initializer == null) {
+ return cp.add(const ConstantNull());
+ }
+ final constant = constantEvaluator.evaluate(param.initializer);
+ return constant.accept(constantEmitter);
+ }
+
+ // Duplicates value on top of the stack using temporary variable with
+ // given index.
+ void _genDupTOS(int tempIndexInFrame) {
// TODO(alexmarkov): Consider introducing Dup bytecode or keeping track of
// expression stack depth.
- final int temp = locals.tempIndex(node);
- asm.emitStoreLocal(temp);
- asm.emitPush(temp);
+ asm.emitStoreLocal(tempIndexInFrame);
+ asm.emitPush(tempIndexInFrame);
+ }
+
+ /// Generates is-test for the value at TOS.
+ void _genInstanceOf(DartType type) {
+ // TODO(alexmarkov): generate _simpleInstanceOf if possible
+
+ if (hasTypeParameters([type])) {
+ _genPushInstantiatorAndFunctionTypeArguments([type]);
+ } else {
+ _genPushNull(); // Instantiator type arguments.
+ _genPushNull(); // Function type arguments.
+ }
+ asm.emitPushConstant(cp.add(new ConstantType(type)));
+ final argDescIndex = cp.add(new ConstantArgDesc(4));
+ final icdataIndex = cp.add(new ConstantICData('_instanceOf', argDescIndex));
+ asm.emitInstanceCall1(4, icdataIndex);
}
void start(Member node) {
- enclosingMember = node;
enclosingClass = node.enclosingClass;
- asm = new BytecodeAssembler();
- cp = new ConstantPool();
- locals = new LocalVariables();
- constantEmitter = new ConstantEmitter(cp);
+ enclosingMember = node;
+ locals = new LocalVariables(node);
// TODO(alexmarkov): improve caching in ConstantEvaluator and reuse it
constantEvaluator = new ConstantEvaluator(constantsBackend, typeEnvironment,
coreTypes, strongMode, /* enableAsserts = */ true)
..env = new EvaluationEnvironment();
labeledStatements = <LabeledStatement, Label>{};
switchCases = <SwitchCase, Label>{};
+ tryCatches = <TryCatch, TryBlock>{};
+ finallyBlocks = <TryFinally, List<FinallyBlock>>{};
+ contextLevels = <TreeNode, int>{};
+ closures = <ClosureBytecode>[];
+ cp = new ConstantPool();
+ constantEmitter = new ConstantEmitter(cp);
+ asm = new BytecodeAssembler();
+ savedAssemblers = <BytecodeAssembler>[];
- node.accept(locals);
+ locals.enterScope(node);
+ _genPrologue(node, node.function);
+
+ _genEqualsOperatorNullHandling(node);
+ }
+
+ // Generate additional code for 'operator ==' to handle nulls.
+ void _genEqualsOperatorNullHandling(Member member) {
+ if (member.name.name != '==' ||
+ locals.numParameters != 2 ||
+ member.enclosingClass != coreTypes.objectClass) {
+ return;
+ }
+
+ Label done = new Label();
+
+ _genLoadVar(member.function.positionalParameters[0]);
+ _genPushNull();
+ asm.emitIfNeStrictTOS();
+ asm.emitJump(done);
+
+ asm.emitPushConstant(cp.add(new ConstantBool(false)));
+ _genReturnTOS();
+
+ asm.bind(done);
+ }
+
+ void end(Member node) {
+ metadata.mapping[node] =
+ new BytecodeMetadata(asm.bytecode, asm.exceptionsTable, cp, closures);
+
+ if (isTraceEnabled) {
+ print('Generated bytecode for $node');
+ }
+
+ enclosingClass = null;
+ enclosingMember = null;
+ locals = null;
+ constantEvaluator = null;
+ labeledStatements = null;
+ switchCases = null;
+ tryCatches = null;
+ finallyBlocks = null;
+ contextLevels = null;
+ closures = null;
+ cp = null;
+ constantEmitter = null;
+ asm = null;
+ savedAssemblers = null;
+ }
+
+ void _genPrologue(Node node, FunctionNode function) {
if (locals.hasOptionalParameters) {
- final function = node.function;
final int numOptionalPositional = function.positionalParameters.length -
function.requiredParameterCount;
final int numOptionalNamed = function.namedParameters.length;
@@ -364,27 +526,219 @@
asm.emitCheckStack();
// TODO(alexmarkov): add type checks for parameters
- }
- int _getDefaultParamConstIndex(VariableDeclaration param) {
- if (param.initializer == null) {
- return cp.add(const ConstantNull());
+ final bool isClosure =
+ node is FunctionDeclaration || node is FunctionExpression;
+ if (isClosure) {
+ asm.emitPush(locals.closureVarIndexInFrame);
+ asm.emitLoadFieldTOS(cp.add(new ConstantFieldOffset(closureContext)));
+ asm.emitPopLocal(locals.contextVarIndexInFrame);
}
- final constant = constantEvaluator.evaluate(param.initializer);
- return constant.accept(constantEmitter);
- }
- void _genJumpIfTrue(bool negated, Label dest) {
- _genJumpIfFalse(!negated, dest);
- }
+ _allocateContextIfNeeded();
- void end(Member node) {
- enclosingMember = null;
- enclosingClass = null;
- metadata.mapping[node] = new BytecodeMetadata(asm.bytecode, cp);
- if (isTraceEnabled) {
- print('Generated bytecode for $node');
+ if (locals.hasCapturedParameters) {
+ // Copy captured parameters to their respective locations in the context.
+ if (locals.hasReceiver) {
+ _copyParamIfCaptured(locals.receiverVar);
+ }
+ function.positionalParameters.forEach(_copyParamIfCaptured);
+ function.namedParameters.forEach(_copyParamIfCaptured);
}
+
+ if (locals.hasTypeArgsVar && isClosure) {
+ if (function.typeParameters.isNotEmpty) {
+ final int numParentTypeArgs = locals.numParentTypeArguments;
+ asm.emitPush(locals.typeArgsVarIndexInFrame);
+ asm.emitPush(locals.closureVarIndexInFrame);
+ asm.emitLoadFieldTOS(
+ cp.add(new ConstantFieldOffset(closureFunctionTypeArguments)));
+ asm.emitPushConstant(cp.add(new ConstantInt(numParentTypeArgs)));
+ asm.emitPushConstant(cp.add(new ConstantInt(
+ numParentTypeArgs + function.typeParameters.length)));
+ _genStaticCall(prependTypeArguments, new ConstantArgDesc(4), 4);
+ asm.emitPopLocal(locals.typeArgsVarIndexInFrame);
+ } else {
+ asm.emitPush(locals.closureVarIndexInFrame);
+ asm.emitLoadFieldTOS(
+ cp.add(new ConstantFieldOffset(closureFunctionTypeArguments)));
+ asm.emitPopLocal(locals.typeArgsVarIndexInFrame);
+ }
+ }
+ }
+
+ void _copyParamIfCaptured(VariableDeclaration variable) {
+ if (locals.isCaptured(variable)) {
+ _genPushContextForVariable(variable);
+ asm.emitPush(locals.getOriginalParamSlotIndex(variable));
+ _genStoreVar(variable);
+ // TODO(alexmarkov): Do we need to store null at the original parameter
+ // location?
+ }
+ }
+
+ void _pushAssemblerState() {
+ savedAssemblers.add(asm);
+ asm = new BytecodeAssembler();
+ }
+
+ void _popAssemblerState() {
+ asm = savedAssemblers.removeLast();
+ }
+
+ int _genClosureBytecode(TreeNode node, String name, FunctionNode function) {
+ _pushAssemblerState();
+
+ locals.enterScope(node);
+
+ final int closureFunctionIndex = cp.add(new ConstantClosureFunction(
+ name, new CloneWithoutBody().visitFunctionNode(function)));
+
+ _genPrologue(node, function);
+ function.body.accept(this);
+
+ // TODO(alexmarkov): figure out when 'return null' should be generated.
+ _genPushNull();
+ _genReturnTOS();
+
+ cp.add(new ConstantEndClosureFunctionScope());
+
+ locals.leaveScope();
+
+ closures.add(new ClosureBytecode(
+ closureFunctionIndex, asm.bytecode, asm.exceptionsTable));
+ _popAssemblerState();
+
+ return closureFunctionIndex;
+ }
+
+ void _genAllocateClosureInstance(
+ TreeNode node, int closureFunctionIndex, FunctionNode function) {
+ // TODO(alexmarkov): Consider adding a bytecode to allocate closure.
+
+ assert(closureClass.typeParameters.isEmpty);
+ asm.emitAllocate(cp.add(new ConstantClass(closureClass)));
+
+ final int temp = locals.tempIndexInFrame(node);
+ asm.emitStoreLocal(temp);
+
+ // TODO(alexmarkov): We need to fill _instantiator_type_arguments field
+ // only if function signature uses instantiator type arguments.
+ asm.emitPush(temp);
+ _genPushInstantiatorTypeArguments();
+ asm.emitStoreFieldTOS(
+ cp.add(new ConstantFieldOffset(closureInstantiatorTypeArguments)));
+
+ asm.emitPush(temp);
+ _genPushFunctionTypeArguments();
+ asm.emitStoreFieldTOS(
+ cp.add(new ConstantFieldOffset(closureFunctionTypeArguments)));
+
+ // TODO(alexmarkov): How to put Object::empty_type_arguments()
+ // to _delayed_type_arguments?
+
+ asm.emitPush(temp);
+ asm.emitPushConstant(closureFunctionIndex);
+ asm.emitStoreFieldTOS(cp.add(new ConstantFieldOffset(closureFunction)));
+
+ asm.emitPush(temp);
+ asm.emitPush(locals.contextVarIndexInFrame);
+ asm.emitStoreFieldTOS(cp.add(new ConstantFieldOffset(closureContext)));
+ }
+
+ void _genClosure(TreeNode node, String name, FunctionNode function) {
+ final int closureFunctionIndex = _genClosureBytecode(node, name, function);
+ _genAllocateClosureInstance(node, closureFunctionIndex, function);
+ }
+
+ void _allocateContextIfNeeded() {
+ final int contextSize = locals.currentContextSize;
+ if (contextSize > 0) {
+ asm.emitAllocateContext(contextSize);
+
+ _genDupTOS(locals.scratchVarIndexInFrame);
+ asm.emitPush(locals.contextVarIndexInFrame);
+ asm.emitStoreFieldTOS(cp.add(new ConstantContextOffset.parent()));
+
+ asm.emitPopLocal(locals.contextVarIndexInFrame);
+ }
+ }
+
+ void _enterScope(TreeNode node) {
+ locals.enterScope(node);
+ _allocateContextIfNeeded();
+ }
+
+ void _leaveScope() {
+ if (locals.currentContextSize > 0) {
+ _genUnwindContext(locals.currentContextLevel - 1);
+ }
+ locals.leaveScope();
+ }
+
+ void _genUnwindContext(int targetContextLevel) {
+ int currentContextLevel = locals.currentContextLevel;
+ assert(currentContextLevel >= targetContextLevel);
+ while (currentContextLevel > targetContextLevel) {
+ asm.emitPush(locals.contextVarIndexInFrame);
+ asm.emitLoadFieldTOS(cp.add(new ConstantContextOffset.parent()));
+ asm.emitPopLocal(locals.contextVarIndexInFrame);
+ --currentContextLevel;
+ }
+ }
+
+ /// Returns the list of try-finally blocks between [from] and [to],
+ /// ordered from inner to outer. If [to] is null, returns all enclosing
+ /// try-finally blocks up to the function boundary.
+ List<TryFinally> _getEnclosingTryFinallyBlocks(TreeNode from, TreeNode to) {
+ List<TryFinally> blocks = <TryFinally>[];
+ TreeNode node = from;
+ for (;;) {
+ if (node == to) {
+ return blocks;
+ }
+ if (node == null || node is FunctionNode || node is Member) {
+ if (to == null) {
+ return blocks;
+ } else {
+ throw 'Unable to find node $to up from $from';
+ }
+ }
+ // Inspect parent as we only need try-finally blocks enclosing [node]
+ // in the body, and not in the finally-block.
+ final parent = node.parent;
+ if (parent is TryFinally && parent.body == node) {
+ blocks.add(parent);
+ }
+ node = parent;
+ }
+ }
+
+ /// Generates non-local transfer from inner node [from] into the outer
+ /// node, executing finally blocks on the way out. [to] can be null,
+ /// in such case all enclosing finally blocks are executed.
+ /// [continuation] is invoked to generate control transfer code following
+ /// the last finally block.
+ void _generateNonLocalControlTransfer(
+ TreeNode from, TreeNode to, GenerateContinuation continuation) {
+ List<TryFinally> tryFinallyBlocks = _getEnclosingTryFinallyBlocks(from, to);
+
+ // Add finally blocks to all try-finally from outer to inner.
+ // The outermost finally block should generate continuation, each inner
+ // finally block should proceed to a corresponding outer block.
+ for (var tryFinally in tryFinallyBlocks.reversed) {
+ final finallyBlock = new FinallyBlock(continuation);
+ finallyBlocks[tryFinally].add(finallyBlock);
+
+ final Label nextFinally = finallyBlock.entry;
+ continuation = () {
+ asm.emitJump(nextFinally);
+ };
+ }
+
+ // Generate jump to the innermost finally (or to the original
+ // continuation if there are no try-finally blocks).
+ continuation();
}
@override
@@ -437,7 +791,7 @@
visitConditionalExpression(ConditionalExpression node) {
final Label otherwisePart = new Label();
final Label done = new Label();
- final int temp = locals.tempIndex(node);
+ final int temp = locals.tempIndexInFrame(node);
final bool negated = _genCondition(node.condition);
_genJumpIfFalse(negated, otherwisePart);
@@ -474,7 +828,7 @@
asm.emitAllocate(classIndex);
}
- _genDupTOS(node);
+ _genDupTOS(locals.tempIndexInFrame(node));
// Remove type arguments as they are only passed to instance allocation,
// and not passed to a constructor.
@@ -504,11 +858,12 @@
// @override
// visitDirectPropertySet(DirectPropertySet node) {
// }
-//
-// @override
-// visitFunctionExpression(FunctionExpression node) {
-// }
-//
+
+ @override
+ visitFunctionExpression(FunctionExpression node) {
+ _genClosure(node, '<anonymous closure>', node.function);
+ }
+
// @override
// visitInstantiation(Instantiation node) {
// }
@@ -520,26 +875,15 @@
@override
visitIsExpression(IsExpression node) {
node.operand.accept(this);
-
- // TODO(alexmarkov): generate _simpleInstanceOf if possible
-
- if (hasTypeParameters([node.type])) {
- _genPushInstantiatorAndFunctionTypeArguments([node.type]);
- } else {
- _genPushNull(); // Instantiator type arguments.
- _genPushNull(); // Function type arguments.
- }
- final typeIndex = cp.add(new ConstantType(node.type));
- asm.emitPushConstant(typeIndex);
- final argDescIndex = cp.add(new ConstantArgDesc(4));
- final icdataIndex = cp.add(new ConstantICData('_instanceOf', argDescIndex));
- asm.emitInstanceCall1(4, icdataIndex);
+ _genInstanceOf(node.type);
}
@override
visitLet(Let node) {
+ _enterScope(node);
node.variable.accept(this);
node.body.accept(this);
+ _leaveScope();
}
@override
@@ -551,12 +895,12 @@
_genTypeArguments([node.typeArgument]);
- _genDupTOS(node);
+ _genDupTOS(locals.tempIndexInFrame(node));
// TODO(alexmarkov): gen more efficient code for empty array
_genPushInt(node.expressions.length);
asm.emitCreateArrayTOS();
- final int temp = locals.tempIndex(node);
+ final int temp = locals.tempIndexInFrame(node);
asm.emitStoreLocal(temp);
for (int i = 0; i < node.expressions.length; i++) {
@@ -576,7 +920,7 @@
final Label shortCircuit = new Label();
final Label done = new Label();
- final int temp = locals.tempIndex(node);
+ final int temp = locals.tempIndexInFrame(node);
final isOR = (node.operator == '||');
bool negated = _genCondition(node.left);
@@ -624,7 +968,7 @@
_genPushInt(node.entries.length * 2);
asm.emitCreateArrayTOS();
- final int temp = locals.tempIndex(node);
+ final int temp = locals.tempIndexInFrame(node);
asm.emitStoreLocal(temp);
for (int i = 0; i < node.entries.length; i++) {
@@ -669,7 +1013,7 @@
@override
visitPropertySet(PropertySet node) {
- final int temp = locals.tempIndex(node);
+ final int temp = locals.tempIndexInFrame(node);
node.receiver.accept(this);
node.value.accept(this);
asm.emitStoreLocal(temp);
@@ -701,7 +1045,7 @@
@override
visitSuperPropertyGet(SuperPropertyGet node) {
- asm.emitPush(locals.thisVarIndex);
+ _genPushReceiver();
Member target =
hierarchy.getDispatchTarget(enclosingClass.superclass, node.name);
if (target == null) {
@@ -734,9 +1078,21 @@
asm.emitPushConstant(cpIndex);
}
-// @override
-// visitRethrow(Rethrow node) {
-// }
+ @override
+ visitRethrow(Rethrow node) {
+ TryCatch tryCatch;
+ for (var parent = node.parent;; parent = parent.parent) {
+ if (parent is Catch) {
+ tryCatch = parent.parent as TryCatch;
+ break;
+ }
+ if (parent == null || parent is FunctionNode) {
+ throw 'Unable to find enclosing catch for $node';
+ }
+ }
+ tryCatches[tryCatch].needsStackTrace = true;
+ _genRethrow(tryCatch);
+ }
bool _hasTrivialInitializer(Field field) =>
(field.initializer == null) ||
@@ -789,7 +1145,7 @@
@override
visitStaticSet(StaticSet node) {
node.value.accept(this);
- _genDupTOS(node);
+ _genDupTOS(locals.tempIndexInFrame(node));
final target = node.target;
if (target is Field) {
// TODO(alexmarkov): assignable check
@@ -811,7 +1167,7 @@
_genPushInt(node.expressions.length);
asm.emitCreateArrayTOS();
- final int temp = locals.tempIndex(node);
+ final int temp = locals.tempIndexInFrame(node);
asm.emitStoreLocal(temp);
for (int i = 0; i < node.expressions.length; i++) {
@@ -839,8 +1195,7 @@
@override
visitThisExpression(ThisExpression node) {
- // TODO(alexmarkov): access to captured this from closures.
- asm.emitPush(locals.thisVarIndex);
+ _genPushReceiver();
}
@override
@@ -863,19 +1218,33 @@
@override
visitVariableGet(VariableGet node) {
- if (node.variable.isConst) {
- _genPushConstExpr(node.variable.initializer);
+ final v = node.variable;
+ if (v.isConst) {
+ _genPushConstExpr(v.initializer);
} else {
- // TODO(alexmarkov): access to captured variables.
- asm.emitPush(locals.varIndex(node.variable));
+ _genLoadVar(v);
}
}
@override
visitVariableSet(VariableSet node) {
- node.value.accept(this);
- // TODO(alexmarkov): access to captured variables.
- asm.emitStoreLocal(locals.varIndex(node.variable));
+ final v = node.variable;
+ if (locals.isCaptured(v)) {
+ _genPushContextForVariable(v);
+
+ node.value.accept(this);
+
+ // Preserve value.
+ final int temp = locals.tempIndexInFrame(node);
+ asm.emitStoreLocal(temp);
+
+ _genStoreVar(v);
+
+ asm.emitPush(temp);
+ } else {
+ node.value.accept(this);
+ asm.emitStoreLocal(locals.getVarIndexInFrame(v));
+ }
}
// @override
@@ -913,7 +1282,9 @@
@override
visitBlock(Block node) {
+ _enterScope(node);
visitList(node.statements, this);
+ _leaveScope();
}
@override
@@ -923,18 +1294,26 @@
@override
visitBreakStatement(BreakStatement node) {
- // TODO(alexmarkov): execute all finally blocks on the way out.
- final label = labeledStatements[node.target] ??
+ final targetLabel = labeledStatements[node.target] ??
(throw 'Target label ${node.target} was not registered for break $node');
- asm.emitJump(label);
+ final targetContextLevel = contextLevels[node.target];
+
+ _generateNonLocalControlTransfer(node, node.target, () {
+ _genUnwindContext(targetContextLevel);
+ asm.emitJump(targetLabel);
+ });
}
@override
visitContinueSwitchStatement(ContinueSwitchStatement node) {
- // TODO(alexmarkov): execute all finally blocks on the way out.
- final label = switchCases[node.target] ??
+ final targetLabel = switchCases[node.target] ??
(throw 'Target label ${node.target} was not registered for continue-switch $node');
- asm.emitJump(label);
+ final targetContextLevel = contextLevels[node.target.parent];
+
+ _generateNonLocalControlTransfer(node, node.target.parent, () {
+ _genUnwindContext(targetContextLevel);
+ asm.emitJump(targetLabel);
+ });
}
@override
@@ -975,13 +1354,13 @@
cp.add(new ConstantICData(
'$kGetterPrefix$kIterator', cp.add(new ConstantArgDesc(1)))));
- final iteratorTemp = locals.tempIndex(node);
+ final iteratorTemp = locals.tempIndexInFrame(node);
asm.emitPopLocal(iteratorTemp);
final Label done = new Label();
final Label join = new Label();
- asm.bind(join);
+ asm.bind(join);
asm.emitCheckStack();
asm.emitPush(iteratorTemp);
@@ -989,13 +1368,21 @@
cp.add(new ConstantICData(kMoveNext, cp.add(new ConstantArgDesc(1)))));
_genJumpIfFalse(/* negated = */ false, done);
+ _enterScope(node);
+
+ _genPushContextIfCaptured(node.variable);
+
asm.emitPush(iteratorTemp);
- asm.emitInstanceCall1(1,
- cp.add(new ConstantICData(kCurrent, cp.add(new ConstantArgDesc(1)))));
- asm.emitPopLocal(locals.varIndex(node.variable));
+ asm.emitInstanceCall1(
+ 1,
+ cp.add(new ConstantICData(
+ '$kGetterPrefix$kCurrent', cp.add(new ConstantArgDesc(1)))));
+
+ _genStoreVar(node.variable);
node.body.accept(this);
+ _leaveScope();
asm.emitJump(join);
asm.bind(done);
@@ -1003,6 +1390,8 @@
@override
visitForStatement(ForStatement node) {
+ _enterScope(node);
+
visitList(node.variables, this);
final Label done = new Label();
@@ -1018,6 +1407,12 @@
node.body.accept(this);
+ if (locals.currentContextSize > 0) {
+ asm.emitPush(locals.contextVarIndexInFrame);
+ asm.emitCloneContext();
+ asm.emitPopLocal(locals.contextVarIndexInFrame);
+ }
+
for (var update in node.updates) {
update.accept(this);
asm.emitDrop1();
@@ -1026,11 +1421,15 @@
asm.emitJump(join);
asm.bind(done);
+ _leaveScope();
}
-// @override
-// visitFunctionDeclaration(FunctionDeclaration node) {
-// }
+ @override
+ visitFunctionDeclaration(FunctionDeclaration node) {
+ _genPushContextIfCaptured(node.variable);
+ _genClosure(node, node.variable.name, node.function);
+ _genStoreVar(node.variable);
+ }
@override
visitIfStatement(IfStatement node) {
@@ -1056,9 +1455,11 @@
visitLabeledStatement(LabeledStatement node) {
final label = new Label();
labeledStatements[node] = label;
+ contextLevels[node] = locals.currentContextLevel;
node.body.accept(this);
asm.bind(label);
- labeledStatements[node] = null;
+ labeledStatements.remove(node);
+ contextLevels.remove(node);
}
@override
@@ -1068,14 +1469,21 @@
} else {
_genPushNull();
}
- asm.emitReturnTOS();
+
+ // TODO(alexmarkov): Do we need to save return value
+ // to a variable?
+ _generateNonLocalControlTransfer(node, null, () {
+ asm.emitReturnTOS();
+ });
}
@override
visitSwitchStatement(SwitchStatement node) {
+ contextLevels[node] = locals.currentContextLevel;
+
node.expression.accept(this);
- final int temp = locals.tempIndex(node);
+ final int temp = locals.tempIndexInFrame(node);
asm.emitPopLocal(temp);
final Label done = new Label();
@@ -1117,15 +1525,169 @@
asm.bind(done);
node.cases.forEach(switchCases.remove);
+ contextLevels.remove(node);
}
-// @override
-// visitTryCatch(TryCatch node) {
-// }
-//
-// @override
-// visitTryFinally(TryFinally node) {
-// }
+ bool _isTryBlock(TreeNode node) => node is TryCatch || node is TryFinally;
+
+ int _savedContextVar(TreeNode node) {
+ assert(_isTryBlock(node));
+ return locals.tempIndexInFrame(node, tempIndex: 0);
+ }
+
+ // Exception var occupies the same slot as saved context, so context
+ // should be restored first, before loading exception.
+ int _exceptionVar(TreeNode node) {
+ assert(_isTryBlock(node));
+ return locals.tempIndexInFrame(node, tempIndex: 0);
+ }
+
+ int _stackTraceVar(TreeNode node) {
+ assert(_isTryBlock(node));
+ return locals.tempIndexInFrame(node, tempIndex: 1);
+ }
+
+ _saveContextForTryBlock(TreeNode node) {
+ if (locals.hasContextVar) {
+ asm.emitPush(locals.contextVarIndexInFrame);
+ asm.emitPopLocal(_savedContextVar(node));
+ }
+ }
+
+ _restoreContextForTryBlock(TreeNode node) {
+ if (locals.hasContextVar) {
+ asm.emitPush(_savedContextVar(node));
+ asm.emitPopLocal(locals.contextVarIndexInFrame);
+ }
+ }
+
+ /// Start try block
+ TryBlock _startTryBlock(TreeNode node) {
+ assert(_isTryBlock(node));
+
+ _saveContextForTryBlock(node);
+
+ return asm.exceptionsTable.enterTryBlock(asm.offsetInWords);
+ }
+
+ /// End try block and start its handler.
+ void _endTryBlock(TreeNode node, TryBlock tryBlock) {
+ tryBlock.endPC = asm.offsetInWords;
+ tryBlock.handlerPC = asm.offsetInWords;
+
+ // TODO(alexmarkov): Consider emitting SetFrame to cut expression stack.
+ // In such case, we need to save return value to a variable in visitReturn.
+
+ _restoreContextForTryBlock(node);
+
+ asm.emitMoveSpecial(_exceptionVar(node), SpecialIndex.exception);
+ asm.emitMoveSpecial(_stackTraceVar(node), SpecialIndex.stackTrace);
+ }
+
+ void _genRethrow(TreeNode node) {
+ asm.emitPush(_exceptionVar(node));
+ asm.emitPush(_stackTraceVar(node));
+ asm.emitThrow(1);
+ }
+
+ @override
+ visitTryCatch(TryCatch node) {
+ final Label done = new Label();
+
+ final TryBlock tryBlock = _startTryBlock(node);
+ tryBlock.isSynthetic = node.isSynthetic;
+ tryCatches[node] = tryBlock; // Used by rethrow.
+
+ node.body.accept(this);
+ asm.emitJump(done);
+
+ _endTryBlock(node, tryBlock);
+
+ final int exception = _exceptionVar(node);
+ final int stackTrace = _stackTraceVar(node);
+
+ bool hasCatchAll = false;
+
+ for (Catch catchClause in node.catches) {
+ tryBlock.types.add(cp.add(new ConstantType(catchClause.guard)));
+
+ Label skipCatch;
+ if (catchClause.guard == const DynamicType()) {
+ hasCatchAll = true;
+ } else {
+ asm.emitPush(exception);
+ _genInstanceOf(catchClause.guard);
+
+ skipCatch = new Label();
+ _genJumpIfFalse(/* negated = */ false, skipCatch);
+ }
+
+ _enterScope(catchClause);
+
+ if (catchClause.exception != null) {
+ _genPushContextIfCaptured(catchClause.exception);
+ asm.emitPush(exception);
+ _genStoreVar(catchClause.exception);
+ }
+
+ if (catchClause.stackTrace != null) {
+ tryBlock.needsStackTrace = true;
+ _genPushContextIfCaptured(catchClause.stackTrace);
+ asm.emitPush(stackTrace);
+ _genStoreVar(catchClause.stackTrace);
+ }
+
+ catchClause.body.accept(this);
+
+ _leaveScope();
+ asm.emitJump(done);
+
+ if (skipCatch != null) {
+ asm.bind(skipCatch);
+ }
+ }
+
+ if (!hasCatchAll) {
+ tryBlock.needsStackTrace = true;
+ _genRethrow(node);
+ }
+
+ asm.bind(done);
+ tryCatches.remove(node);
+ }
+
+ @override
+ visitTryFinally(TryFinally node) {
+ final TryBlock tryBlock = _startTryBlock(node);
+ finallyBlocks[node] = <FinallyBlock>[];
+
+ node.body.accept(this);
+
+ // TODO(alexmarkov): Do not generate normal continuation if control
+ // does not return from body.
+ final normalContinuation =
+ new FinallyBlock(() {/* do nothing (fall through) */});
+ finallyBlocks[node].add(normalContinuation);
+ asm.emitJump(normalContinuation.entry);
+
+ _endTryBlock(node, tryBlock);
+
+ tryBlock.types.add(cp.add(new ConstantType(const DynamicType())));
+
+ node.finalizer.accept(this);
+
+ tryBlock.needsStackTrace = true; // For rethrowing.
+ _genRethrow(node);
+
+ for (var finallyBlock in finallyBlocks[node]) {
+ asm.bind(finallyBlock.entry);
+ _restoreContextForTryBlock(node);
+ node.finalizer.accept(this);
+ finallyBlock.generateContinuation();
+ }
+
+ finallyBlocks.remove(node);
+ }
@override
visitVariableDeclaration(VariableDeclaration node) {
@@ -1133,12 +1695,22 @@
final Constant constant = constantEvaluator.evaluate(node.initializer);
constantEvaluator.env.addVariableValue(node, constant);
} else {
+ final bool isCaptured = locals.isCaptured(node);
+ if (isCaptured) {
+ _genPushContextForVariable(node);
+ }
if (node.initializer != null) {
node.initializer.accept(this);
} else {
_genPushNull();
}
- asm.emitPopLocal(locals.varIndex(node));
+ if (isCaptured) {
+ final int cpIndex = cp.add(new ConstantContextOffset.variable(
+ locals.getVarIndexInContext(node)));
+ asm.emitStoreFieldTOS(cpIndex);
+ } else {
+ asm.emitPopLocal(locals.getVarIndexInFrame(node));
+ }
}
}
@@ -1310,3 +1882,55 @@
node.positionalParameters.any((t) => t.accept(this)) ||
node.namedParameters.any((p) => p.type.accept(this));
}
+
+// Drop kernel AST for members with bytecode.
+class DropAST extends Transformer {
+ BytecodeMetadataRepository metadata;
+
+ @override
+ TreeNode visitComponent(Component node) {
+ metadata = node.metadata[new BytecodeMetadataRepository().tag];
+ if (metadata != null) {
+ return super.visitComponent(node);
+ }
+ return node;
+ }
+
+ @override
+ TreeNode defaultMember(Member node) {
+ if (_hasBytecode(node)) {
+ if (node is Field) {
+ node.initializer = null;
+ } else if (node is Constructor) {
+ node.initializers = <Initializer>[];
+ node.function.body = null;
+ } else if (node.function != null) {
+ node.function.body = null;
+ }
+ }
+
+ // Instance field initializers do not form separate functions, and bytecode
+ // is not attached to instance fields (it is included into constructors).
+ // When VM reads a constructor from kernel, it also reads and translates
+ // instance field initializers. So, their ASTs can be dropped only if
+ // bytecode was generated for all generative constructors.
+ if (node is Field && !node.isStatic && node.initializer != null) {
+ if (node.enclosingClass.constructors.every(_hasBytecode)) {
+ node.initializer = null;
+ }
+ }
+
+ return node;
+ }
+
+ bool _hasBytecode(Member node) => metadata.mapping.containsKey(node);
+}
+
+typedef void GenerateContinuation();
+
+class FinallyBlock {
+ final Label entry = new Label();
+ final GenerateContinuation generateContinuation;
+
+ FinallyBlock(this.generateContinuation);
+}
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index 93789ad..1bae25a 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -9,166 +9,690 @@
import 'package:kernel/ast.dart';
import 'package:vm/bytecode/dbc.dart';
-class LocalVariables extends RecursiveVisitor<Null> {
- final Map<VariableDeclaration, int> _vars = <VariableDeclaration, int>{};
- final Map<TreeNode, int> _temps = <TreeNode, int>{};
- final List<int> _scopes = <int>[];
- int _localVars = 0;
- int _frameSize = 0;
- int _numParameters = 0;
- bool _hasOptionalParameters = false;
- int _thisVarIndex;
- int _functionTypeArgsVarIndex;
+class LocalVariables {
+ final Map<TreeNode, Scope> _scopes = <TreeNode, Scope>{};
+ final Map<VariableDeclaration, VarDesc> _vars =
+ <VariableDeclaration, VarDesc>{};
+ final Map<TreeNode, List<int>> _temps = <TreeNode, List<int>>{};
- int get thisVarIndex =>
- _thisVarIndex ?? (throw '\'this\' variable is not allocated');
+ Scope _currentScope;
+ Frame _currentFrame;
- int get functionTypeArgsVarIndex =>
- _functionTypeArgsVarIndex ??
- (throw '\'functionTypeArgs\' variable is not allocated');
+ VarDesc _getVarDesc(VariableDeclaration variable) =>
+ _vars[variable] ??
+ (throw 'Variable descriptor is not created for $variable');
- int get frameSize => _frameSize;
+ int _getVarIndex(VariableDeclaration variable, bool isCaptured) {
+ final v = _getVarDesc(variable);
+ if (v.isCaptured != isCaptured) {
+ throw 'Mismatch in captured state of $variable';
+ }
+ return v.index ?? (throw 'Variable $variable is not allocated');
+ }
- int get numParameters => _numParameters;
+ bool isCaptured(VariableDeclaration variable) =>
+ _getVarDesc(variable).isCaptured;
- bool get hasOptionalParameters => _hasOptionalParameters;
+ int getVarIndexInFrame(VariableDeclaration variable) =>
+ _getVarIndex(variable, false);
- int varIndex(VariableDeclaration variable) =>
- _vars[variable] ?? (throw '\'$variable\' variable is not allocated');
+ int getVarIndexInContext(VariableDeclaration variable) =>
+ _getVarIndex(variable, true);
- int tempIndex(TreeNode node) =>
- _temps[node] ??
- (throw 'Temp is not allocated for node ${node.runtimeType} $node');
+ int getOriginalParamSlotIndex(VariableDeclaration variable) =>
+ _getVarDesc(variable).originalParamSlotIndex ??
+ (throw 'Variablie $variable does not have originalParamSlotIndex');
- int _allocateVar(VariableDeclaration node, {int index}) {
- if (index == null) {
- index = _localVars++;
+ int tempIndexInFrame(TreeNode node, {int tempIndex: 0}) {
+ final temps = _temps[node];
+ if (temps == null) {
+ throw 'Temp is not allocated for node ${node.runtimeType} $node';
+ }
+ return temps[tempIndex];
+ }
+
+ int get currentContextSize => _currentScope.contextSize;
+ int get currentContextLevel => _currentScope.contextLevel;
+
+ int getContextLevelOfVar(VariableDeclaration variable) {
+ final v = _getVarDesc(variable);
+ assert(v.isCaptured);
+ return v.scope.contextLevel;
+ }
+
+ int get closureVarIndexInFrame => getVarIndexInFrame(_currentFrame
+ .closureVar ??
+ (throw 'Closure variable is not declared in ${_currentFrame.function}'));
+
+ int get contextVarIndexInFrame => getVarIndexInFrame(_currentFrame
+ .contextVar ??
+ (throw 'Context variable is not declared in ${_currentFrame.function}'));
+
+ bool get hasContextVar => _currentFrame.contextVar != null;
+
+ int get scratchVarIndexInFrame => getVarIndexInFrame(_currentFrame
+ .scratchVar ??
+ (throw 'Scratch variable is not declared in ${_currentFrame.function}'));
+
+ int get typeArgsVarIndexInFrame => getVarIndexInFrame(_currentFrame
+ .typeArgsVar ??
+ (throw 'TypeArgs variable is not declared in ${_currentFrame.function}'));
+
+ bool get hasTypeArgsVar => _currentFrame.typeArgsVar != null;
+
+ VariableDeclaration get receiverVar =>
+ _currentFrame.receiverVar ??
+ (throw 'Receiver variable is not declared in ${_currentFrame.function}');
+
+ bool get hasReceiver => _currentFrame.receiverVar != null;
+
+ int get frameSize => _currentFrame.frameSize;
+
+ int get numParameters => _currentFrame.numParameters;
+
+ int get numParentTypeArguments => _currentFrame.parent?.numTypeArguments ?? 0;
+
+ bool get hasOptionalParameters => _currentFrame.hasOptionalParameters;
+ bool get hasCapturedParameters => _currentFrame.hasCapturedParameters;
+
+ LocalVariables(Member node) {
+ final scopeBuilder = new _ScopeBuilder(this);
+ node.accept(scopeBuilder);
+
+ final allocator = new _Allocator(this);
+ node.accept(allocator);
+ }
+
+ void enterScope(TreeNode node) {
+ _currentScope = _scopes[node];
+ _currentFrame = _currentScope.frame;
+ }
+
+ void leaveScope() {
+ _currentScope = _currentScope.parent;
+ _currentFrame = _currentScope?.frame;
+ }
+}
+
+class VarDesc {
+ final VariableDeclaration declaration;
+ final Scope scope;
+ bool isCaptured = false;
+ int index;
+ int originalParamSlotIndex;
+
+ VarDesc(this.declaration, this.scope);
+
+ Frame get frame => scope.frame;
+
+ bool get isAllocated => index != null;
+
+ void capture() {
+ if (!isCaptured) {
+ assert(!isAllocated);
+ // TODO(alexmarkov): Consider sharing context between scopes.
+ index = scope.contextSize++;
+ isCaptured = true;
+ }
+ }
+}
+
+class Frame {
+ final TreeNode function;
+ final Frame parent;
+
+ int numParameters = 0;
+ int numTypeArguments = 0;
+ bool hasOptionalParameters = false;
+ bool hasCapturedParameters = false;
+ bool hasClosures = false;
+ VariableDeclaration receiverVar;
+ VariableDeclaration typeArgsVar;
+ VariableDeclaration closureVar;
+ VariableDeclaration contextVar;
+ VariableDeclaration scratchVar;
+ int frameSize = 0;
+ List<int> temporaries = <int>[];
+
+ Frame(this.function, this.parent);
+}
+
+class Scope {
+ final Scope parent;
+ final Frame frame;
+
+ int localsUsed;
+ int tempsUsed;
+ int contextSize = 0;
+ int contextLevel;
+
+ Scope(this.parent, this.frame);
+
+ bool get hasContext => contextSize > 0;
+}
+
+class _ScopeBuilder extends RecursiveVisitor<Null> {
+ final LocalVariables locals;
+
+ Scope _currentScope;
+ Frame _currentFrame;
+
+ _ScopeBuilder(this.locals);
+
+ void _sortNamedParameters(FunctionNode function) {
+ function.namedParameters.sort(
+ (VariableDeclaration a, VariableDeclaration b) =>
+ a.name.compareTo(b.name));
+ }
+
+ void _visitFunction(TreeNode node) {
+ _enterFrame(node);
+
+ if (node is Field) {
+ node.initializer.accept(this);
} else {
- // Should be a parameter.
- assert(index < 0 || (_hasOptionalParameters && index < _numParameters));
+ assert(node is Procedure ||
+ node is Constructor ||
+ node is FunctionDeclaration ||
+ node is FunctionExpression);
+
+ FunctionNode function = (node as dynamic).function;
+ assert(function != null);
+
+ _currentFrame.numTypeArguments =
+ (_currentFrame.parent?.numTypeArguments ?? 0) +
+ function.typeParameters.length;
+
+ if (_currentFrame.numTypeArguments > 0) {
+ _currentFrame.typeArgsVar =
+ new VariableDeclaration(':function_type_arguments_var');
+ _declareVariable(_currentFrame.typeArgsVar);
+ }
+ if (node is Constructor || (node is Procedure && !node.isStatic)) {
+ _currentFrame.receiverVar = new VariableDeclaration('this');
+ _declareVariable(_currentFrame.receiverVar);
+ } else if (_currentFrame.parent?.receiverVar != null) {
+ _currentFrame.receiverVar = _currentFrame.parent.receiverVar;
+ }
+ if (node is FunctionDeclaration || node is FunctionExpression) {
+ _currentFrame.closureVar = new VariableDeclaration(':closure');
+ _declareVariable(_currentFrame.closureVar);
+ }
+
+ _sortNamedParameters(function);
+
+ visitList(function.positionalParameters, this);
+ visitList(function.namedParameters, this);
+
+ if (node is Constructor) {
+ for (var field in node.enclosingClass.fields) {
+ if (!field.isStatic && field.initializer != null) {
+ field.initializer.accept(this);
+ }
+ }
+ visitList(node.initializers, this);
+ }
+
+ function.body?.accept(this);
}
- _frameSize = max(_frameSize, _localVars);
- if (node != null) {
- assert(_vars[node] == null);
- _vars[node] = index;
+
+ if (node is FunctionDeclaration ||
+ node is FunctionExpression ||
+ _currentFrame.hasClosures) {
+ _currentFrame.contextVar = new VariableDeclaration(':context');
+ _declareVariable(_currentFrame.contextVar);
+ _currentFrame.scratchVar = new VariableDeclaration(':scratch');
+ _declareVariable(_currentFrame.scratchVar);
}
- return index;
+
+ _leaveFrame();
}
- // TODO(alexmarkov): allocate temporaries more efficiently.
- void _allocateTemp(TreeNode node) {
- _temps[node] = _allocateVar(null);
+ _enterFrame(TreeNode node) {
+ _currentFrame = new Frame(node, _currentFrame);
+ _enterScope(node);
}
- int _allocateParameter(VariableDeclaration node, int i) {
- assert(0 <= i && i < _numParameters);
- int paramSlotIndex =
- _hasOptionalParameters ? i : -kParamEndSlotFromFp - _numParameters + i;
- return _allocateVar(node, index: paramSlotIndex);
+ _leaveFrame() {
+ _leaveScope();
+ _currentFrame = _currentFrame.parent;
}
- void _enterScope() {
- _scopes.add(_localVars);
+ void _enterScope(TreeNode node) {
+ _currentScope = new Scope(_currentScope, _currentFrame);
+ assert(locals._scopes[node] == null);
+ locals._scopes[node] = _currentScope;
}
void _leaveScope() {
- final int enclosingScopeLocalVars = _scopes.removeLast();
- assert(_localVars >= enclosingScopeLocalVars);
- _localVars = enclosingScopeLocalVars;
+ _currentScope = _currentScope.parent;
+ }
+
+ void _declareVariable(VariableDeclaration variable) {
+ final VarDesc v = new VarDesc(variable, _currentScope);
+ assert(locals._vars[variable] == null);
+ locals._vars[variable] = v;
+ }
+
+ void _useVariable(VariableDeclaration variable) {
+ assert(variable != null);
+ final VarDesc v = locals._vars[variable];
+ if (v == null) {
+ throw 'Variable $variable is used before declared';
+ }
+ if (v.frame != _currentFrame) {
+ v.capture();
+ }
+ }
+
+ void _useThis() {
+ assert(_currentFrame.receiverVar != null);
+ _useVariable(_currentFrame.receiverVar);
+ }
+
+ void _visitWithScope(TreeNode node) {
+ _enterScope(node);
+ node.visitChildren(this);
+ _leaveScope();
}
@override
- visitField(Field node) {
- if (node.initializer != null) {
- assert(_vars.isEmpty);
- assert(_localVars == 0);
+ defaultMember(Member node) {
+ _visitFunction(node);
+ }
- _enterScope();
+ @override
+ visitFunctionDeclaration(FunctionDeclaration node) {
+ _currentFrame.hasClosures = true;
+ node.variable.accept(this);
+ _visitFunction(node);
+ }
+
+ @override
+ visitFunctionExpression(FunctionExpression node) {
+ _currentFrame.hasClosures = true;
+ _visitFunction(node);
+ }
+
+ @override
+ visitVariableDeclaration(VariableDeclaration node) {
+ _declareVariable(node);
+ node.visitChildren(this);
+ }
+
+ @override
+ visitVariableGet(VariableGet node) {
+ _useVariable(node.variable);
+ }
+
+ @override
+ visitVariableSet(VariableSet node) {
+ _useVariable(node.variable);
+ node.visitChildren(this);
+ }
+
+ @override
+ visitThisExpression(ThisExpression node) {
+ _useThis();
+ }
+
+ @override
+ visitSuperMethodInvocation(SuperMethodInvocation node) {
+ _useThis();
+ node.visitChildren(this);
+ }
+
+ @override
+ visitSuperPropertyGet(SuperPropertyGet node) {
+ _useThis();
+ node.visitChildren(this);
+ }
+
+ @override
+ visitSuperPropertySet(SuperPropertySet node) {
+ _useThis();
+ node.visitChildren(this);
+ }
+
+ @override
+ visitTypeParameterType(TypeParameterType node) {
+ if (node.parameter.parent is Class) {
+ _useThis();
+ }
+ node.visitChildren(this);
+ }
+
+ @override
+ visitBlock(Block node) {
+ _visitWithScope(node);
+ }
+
+ @override
+ visitAssertBlock(AssertBlock node) {
+ _visitWithScope(node);
+ }
+
+ @override
+ visitForStatement(ForStatement node) {
+ _visitWithScope(node);
+ }
+
+ @override
+ visitForInStatement(ForInStatement node) {
+ node.iterable.accept(this);
+
+ _enterScope(node);
+ node.variable.accept(this);
+ node.body.accept(this);
+ _leaveScope();
+ }
+
+ @override
+ visitCatch(Catch node) {
+ _visitWithScope(node);
+ }
+
+ @override
+ visitLet(Let node) {
+ _visitWithScope(node);
+ }
+}
+
+class _Allocator extends RecursiveVisitor<Null> {
+ final LocalVariables locals;
+
+ Scope _currentScope;
+ Frame _currentFrame;
+ int _contextLevel = 0;
+
+ _Allocator(this.locals);
+
+ void _enterScope(TreeNode node) {
+ final scope = locals._scopes[node];
+ assert(scope != null);
+ assert(scope.parent == _currentScope);
+ _currentScope = scope;
+
+ if (_currentScope.frame != _currentFrame) {
+ _currentFrame = _currentScope.frame;
+
+ _currentScope.localsUsed = 0;
+ _currentScope.tempsUsed = 0;
+ } else {
+ _currentScope.localsUsed = _currentScope.parent.localsUsed;
+ _currentScope.tempsUsed = _currentScope.parent.tempsUsed;
+ }
+
+ if (_currentScope.parent == null || _currentScope.hasContext) {
+ _currentScope.contextLevel = _contextLevel++;
+ } else {
+ _currentScope.contextLevel = _currentScope.parent.contextLevel;
+ }
+ }
+
+ void _leaveScope() {
+ if (_currentScope.hasContext) {
+ --_contextLevel;
+ }
+
+ _currentScope = _currentScope.parent;
+ _currentFrame = _currentScope?.frame;
+
+ // Remove temporary variables which are out of scope.
+ if (_currentScope != null) {
+ int tempsToRetain = _currentFrame.temporaries.length;
+ while (tempsToRetain > 0 &&
+ _currentFrame.temporaries[tempsToRetain - 1] >=
+ _currentScope.localsUsed) {
+ --tempsToRetain;
+ }
+ assert(tempsToRetain >= _currentScope.tempsUsed);
+ _currentFrame.temporaries.length = tempsToRetain;
+ assert(_currentFrame.temporaries
+ .every((index) => index < _currentScope.localsUsed));
+ }
+ }
+
+ void _updateFrameSize() {
+ _currentFrame.frameSize =
+ max(_currentFrame.frameSize, _currentScope.localsUsed);
+ }
+
+ void _allocateTemp(TreeNode node, {int count: 1}) {
+ assert(locals._temps[node] == null);
+ if (_currentScope.tempsUsed + count > _currentFrame.temporaries.length) {
+ // Allocate new local slots for temporary variables.
+ final int newSlots =
+ (_currentScope.tempsUsed + count) - _currentFrame.temporaries.length;
+ int local = _currentScope.localsUsed;
+ _currentScope.localsUsed += newSlots;
+ _updateFrameSize();
+ for (int i = 0; i < newSlots; i++) {
+ _currentFrame.temporaries.add(local + i);
+ }
+ }
+ locals._temps[node] = _currentFrame.temporaries
+ .sublist(_currentScope.tempsUsed, _currentScope.tempsUsed + count);
+ _currentScope.tempsUsed += count;
+ }
+
+ void _freeTemp(TreeNode node, {int count: 1}) {
+ assert(_currentScope.tempsUsed >= count);
+ _currentScope.tempsUsed -= count;
+ assert(listEquals(
+ locals._temps[node],
+ _currentFrame.temporaries.sublist(
+ _currentScope.tempsUsed, _currentScope.tempsUsed + count)));
+ }
+
+ void _allocateVariable(VariableDeclaration variable, {int paramSlotIndex}) {
+ final VarDesc v = locals._getVarDesc(variable);
+ if (v.isCaptured) {
+ assert(v.isAllocated);
+ v.originalParamSlotIndex = paramSlotIndex;
+ return;
+ }
+
+ assert(!v.isAllocated);
+ assert(v.scope == _currentScope);
+
+ if (paramSlotIndex != null) {
+ assert(paramSlotIndex < 0 ||
+ (_currentFrame.hasOptionalParameters &&
+ paramSlotIndex < _currentFrame.numParameters));
+ v.index = paramSlotIndex;
+ } else {
+ v.index = _currentScope.localsUsed++;
+ }
+ _updateFrameSize();
+ }
+
+ void _ensureVariableAllocated(VariableDeclaration variable) {
+ if (variable != null) {
+ final VarDesc v = locals._getVarDesc(variable);
+ if (!v.isAllocated) {
+ _allocateVariable(variable);
+ }
+ }
+ }
+
+ void _allocateParameter(VariableDeclaration node, int i) {
+ final numParameters = _currentFrame.numParameters;
+ assert(0 <= i && i < numParameters);
+ int paramSlotIndex = _currentFrame.hasOptionalParameters
+ ? i
+ : -kParamEndSlotFromFp - numParameters + i;
+ _allocateVariable(node, paramSlotIndex: paramSlotIndex);
+ }
+
+ void _allocateParameters(TreeNode node, FunctionNode function) {
+ final bool hasTypeArgs = function.typeParameters.isNotEmpty;
+ final bool hasReceiver =
+ node is Constructor || (node is Procedure && !node.isStatic);
+ final bool hasClosureArg =
+ node is FunctionDeclaration || node is FunctionExpression;
+
+ _currentFrame.numParameters = function.positionalParameters.length +
+ function.namedParameters.length +
+ (hasTypeArgs ? 1 : 0) +
+ (hasReceiver ? 1 : 0) +
+ (hasClosureArg ? 1 : 0);
+
+ _currentFrame.hasOptionalParameters = function.requiredParameterCount <
+ function.positionalParameters.length ||
+ function.namedParameters.isNotEmpty;
+
+ _currentFrame.hasCapturedParameters =
+ (hasReceiver && locals.isCaptured(_currentFrame.receiverVar)) ||
+ function.positionalParameters.any(locals.isCaptured) ||
+ function.namedParameters.any(locals.isCaptured);
+
+ int count = 0;
+ if (hasTypeArgs) {
+ assert(!locals.isCaptured(_currentFrame.typeArgsVar));
+ _allocateParameter(_currentFrame.typeArgsVar, count++);
+ }
+ if (hasReceiver) {
+ _allocateParameter(_currentFrame.receiverVar, count++);
+ }
+ if (hasClosureArg) {
+ assert(!locals.isCaptured(_currentFrame.closureVar));
+ _allocateParameter(_currentFrame.closureVar, count++);
+ }
+ for (var param in function.positionalParameters) {
+ _allocateParameter(param, count++);
+ }
+ for (var param in function.namedParameters) {
+ _allocateParameter(param, count++);
+ }
+ assert(count == _currentFrame.numParameters);
+
+ if (_currentFrame.hasOptionalParameters) {
+ _currentScope.localsUsed = _currentFrame.numParameters;
+ _updateFrameSize();
+ }
+ }
+
+ void _allocateSpecialVariables() {
+ _ensureVariableAllocated(_currentFrame.typeArgsVar);
+ _ensureVariableAllocated(_currentFrame.contextVar);
+ _ensureVariableAllocated(_currentFrame.scratchVar);
+ }
+
+ void _visitFunction(TreeNode node) {
+ _enterScope(node);
+
+ if (node is Field) {
+ _allocateSpecialVariables();
node.initializer.accept(this);
- _leaveScope();
+ } else {
+ assert(node is Procedure ||
+ node is Constructor ||
+ node is FunctionDeclaration ||
+ node is FunctionExpression);
- assert(_scopes.isEmpty);
+ final FunctionNode function = (node as dynamic).function;
+ assert(function != null);
+
+ _allocateParameters(node, function);
+ _allocateSpecialVariables();
+
+ if (node is Constructor) {
+ for (var field in node.enclosingClass.fields) {
+ if (!field.isStatic && field.initializer != null) {
+ field.initializer.accept(this);
+ }
+ }
+ visitList(node.initializers, this);
+ }
+
+ function.body?.accept(this);
+ }
+
+ _leaveScope();
+ }
+
+ void _visit(TreeNode node, {bool scope: false, int temps: 0}) {
+ if (scope) {
+ _enterScope(node);
+ }
+ if (temps > 0) {
+ _allocateTemp(node, count: temps);
+ }
+
+ node.visitChildren(this);
+
+ if (temps > 0) {
+ _freeTemp(node, count: temps);
+ }
+ if (scope) {
+ _leaveScope();
}
}
@override
defaultMember(Member node) {
- assert(_vars.isEmpty);
- assert(_localVars == 0);
-
- final function = node.function;
- final bool hasTypeArgs = function.typeParameters.isNotEmpty;
- final bool hasReceiver =
- node is Constructor || ((node is Procedure) && !node.isStatic);
- _numParameters = function.positionalParameters.length +
- function.namedParameters.length +
- (hasTypeArgs ? 1 : 0) +
- (hasReceiver ? 1 : 0);
- _hasOptionalParameters = function.requiredParameterCount <
- function.positionalParameters.length ||
- function.namedParameters.isNotEmpty;
- int count = 0;
-
- if (hasTypeArgs) {
- _functionTypeArgsVarIndex = _allocateParameter(null, count++);
- }
-
- if (hasReceiver) {
- _thisVarIndex = _allocateParameter(null, count++);
- }
-
- for (var param in function.positionalParameters) {
- _allocateParameter(param, count++);
- }
-
- List<VariableDeclaration> namedParams = function.namedParameters;
- namedParams.sort((VariableDeclaration a, VariableDeclaration b) =>
- a.name.compareTo(b.name));
- for (var param in namedParams) {
- _allocateParameter(param, count++);
- }
-
- if (_hasOptionalParameters) {
- _localVars = _numParameters;
- _frameSize = _numParameters;
- }
-
- _enterScope();
- if (node is Constructor) {
- _enterScope();
- for (var field in node.enclosingClass.fields) {
- if (!field.isStatic && field.initializer != null) {
- field.initializer.accept(this);
- }
- }
- visitList(node.initializers, this);
- _leaveScope();
- }
- function.body?.accept(this);
- _leaveScope();
-
- assert(_scopes.isEmpty);
+ _visitFunction(node);
}
@override
- visitBlock(Block node) {
- _enterScope();
- node.visitChildren(this);
- _leaveScope();
+ visitFunctionDeclaration(FunctionDeclaration node) {
+ _allocateVariable(node.variable);
+ _allocateTemp(node);
+ _visitFunction(node);
+ _freeTemp(node);
+ }
+
+ @override
+ visitFunctionExpression(FunctionExpression node) {
+ _allocateTemp(node);
+ _visitFunction(node);
+ _freeTemp(node);
}
@override
visitVariableDeclaration(VariableDeclaration node) {
- _allocateVar(node);
+ _allocateVariable(node);
node.visitChildren(this);
}
@override
- visitLet(Let node) {
- _enterScope();
+ visitBlock(Block node) {
+ _visit(node, scope: true);
+ }
+
+ @override
+ visitAssertBlock(AssertBlock node) {
+ _visit(node, scope: true);
+ }
+
+ @override
+ visitForStatement(ForStatement node) {
+ _visit(node, scope: true);
+ }
+
+ @override
+ visitForInStatement(ForInStatement node) {
+ _allocateTemp(node);
+
+ node.iterable.accept(this);
+
+ _enterScope(node);
node.variable.accept(this);
node.body.accept(this);
_leaveScope();
+
+ _freeTemp(node);
+ }
+
+ @override
+ visitCatch(Catch node) {
+ _visit(node, scope: true);
+ }
+
+ @override
+ visitLet(Let node) {
+ _visit(node, scope: true);
}
// -------------- Allocation of temporaries --------------
@@ -178,8 +702,7 @@
if (node.isConst) {
return;
}
- _allocateTemp(node);
- super.visitConstructorInvocation(node);
+ _visit(node, temps: 1);
}
@override
@@ -187,8 +710,7 @@
if (node.isConst) {
return;
}
- _allocateTemp(node);
- super.visitListLiteral(node);
+ _visit(node, temps: 1);
}
@override
@@ -196,44 +718,37 @@
if (node.isConst) {
return;
}
- _allocateTemp(node);
- super.visitMapLiteral(node);
+ _visit(node, temps: 1);
}
@override
visitStringConcatenation(StringConcatenation node) {
- _allocateTemp(node);
- super.visitStringConcatenation(node);
+ _visit(node, temps: 1);
}
@override
visitConditionalExpression(ConditionalExpression node) {
- _allocateTemp(node);
- super.visitConditionalExpression(node);
+ _visit(node, temps: 1);
}
@override
visitLogicalExpression(LogicalExpression node) {
- _allocateTemp(node);
- super.visitLogicalExpression(node);
+ _visit(node, temps: 1);
}
@override
visitPropertySet(PropertySet node) {
- _allocateTemp(node);
- super.visitPropertySet(node);
- }
-
- @override
- visitForInStatement(ForInStatement node) {
- _allocateTemp(node);
- super.visitForInStatement(node);
+ _visit(node, temps: 1);
}
@override
visitSwitchStatement(SwitchStatement node) {
- _allocateTemp(node);
- super.visitSwitchStatement(node);
+ _visit(node, temps: 1);
+ }
+
+ @override
+ visitVariableSet(VariableSet node) {
+ _visit(node, temps: locals.isCaptured(node.variable) ? 1 : 0);
}
@override
@@ -241,4 +756,14 @@
_allocateTemp(node);
super.visitStaticSet(node);
}
+
+ @override
+ visitTryCatch(TryCatch node) {
+ _visit(node, temps: 2);
+ }
+
+ @override
+ visitTryFinally(TryFinally node) {
+ _visit(node, temps: 2);
+ }
}
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index d950c1e..c38213d 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -25,7 +25,8 @@
import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/binary/limited_ast_to_binary.dart';
-import 'package:kernel/kernel.dart' show Component, loadComponentFromBytes;
+import 'package:kernel/kernel.dart'
+ show Component, loadComponentSourceFromBytes;
import 'package:kernel/target/targets.dart';
import 'package:path/path.dart' as path;
import 'package:usage/uuid/uuid.dart';
@@ -88,7 +89,12 @@
' option',
defaultsTo: 'org-dartlang-root',
hide: true)
- ..addFlag('verbose', help: 'Enables verbose output from the compiler.');
+ ..addFlag('verbose', help: 'Enables verbose output from the compiler.')
+ ..addOption('initialize-from-dill',
+ help: 'Normally the output dill is used to specify which dill to '
+ 'initialize from, but it can be overwritten here.',
+ defaultsTo: null,
+ hide: true);
String usage = '''
Usage: server [options] [input.dart]
@@ -179,6 +185,7 @@
String _kernelBinaryFilename;
String _kernelBinaryFilenameIncremental;
String _kernelBinaryFilenameFull;
+ String _initializeFromDill;
final ProgramTransformer transformer;
@@ -203,6 +210,8 @@
? '${_options["output-dill"]}.incremental.dill'
: '$filename.incremental.dill');
_kernelBinaryFilename = _kernelBinaryFilenameFull;
+ _initializeFromDill =
+ _options['initialize-from-dill'] ?? _kernelBinaryFilenameFull;
final String boundaryKey = new Uuid().generateV4();
_outputStream.writeln('result $boundaryKey');
final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
@@ -270,9 +279,9 @@
Component component;
if (options['incremental']) {
_compilerOptions = compilerOptions;
- _generator = generator ??
- _createGenerator(new Uri.file(_kernelBinaryFilenameFull));
- await invalidateIfBootstrapping();
+ _generator =
+ generator ?? _createGenerator(new Uri.file(_initializeFromDill));
+ await invalidateIfInitializingFromDill();
component = await _runWithPrintRedirection(() => _generator.compile());
} else {
if (options['link-platform']) {
@@ -321,18 +330,19 @@
await sink.close();
}
- Future<Null> invalidateIfBootstrapping() async {
+ Future<Null> invalidateIfInitializingFromDill() async {
if (_kernelBinaryFilename != _kernelBinaryFilenameFull) return null;
- // If the generator is initialized bootstrapping is not in effect anyway,
- // so there's no reason to spend time invalidating what should be
- // invalidated by the normal approach anyway.
+ // If the generator is initialized, it's not going to initialize from dill
+ // again anyway, so there's no reason to spend time invalidating what should
+ // be invalidated by the normal approach anyway.
if (_generator.initialized) return null;
try {
- final File f = new File(_kernelBinaryFilenameFull);
+ final File f = new File(_initializeFromDill);
if (!f.existsSync()) return null;
- final Component component = loadComponentFromBytes(f.readAsBytesSync());
+ final Component component =
+ loadComponentSourceFromBytes(f.readAsBytesSync());
for (Uri uri in component.uriToSource.keys) {
if ('$uri' == '') continue;
@@ -357,8 +367,8 @@
}
} catch (e) {
// If there's a failure in the above block we might not have invalidated
- // correctly. Create a new generator that doesn't bootstrap to avoid missing
- // any changes.
+ // correctly. Create a new generator that doesn't initialize from dill to
+ // avoid missing any changes.
_generator = _createGenerator(null);
}
}
@@ -367,7 +377,7 @@
Future<Null> recompileDelta({String filename}) async {
final String boundaryKey = new Uuid().generateV4();
_outputStream.writeln('result $boundaryKey');
- await invalidateIfBootstrapping();
+ await invalidateIfInitializingFromDill();
if (filename != null) {
setMainSourceFilename(filename);
}
@@ -421,9 +431,9 @@
return Uri.base.resolveUri(new Uri.file(fileOrUri));
}
- IncrementalCompiler _createGenerator(Uri bootstrapDill) {
+ IncrementalCompiler _createGenerator(Uri initializeFromDillUri) {
return new IncrementalCompiler(_compilerOptions, _mainSource,
- bootstrapDill: bootstrapDill);
+ initializeFromDillUri: initializeFromDillUri);
}
Uri _ensureFolderPath(String path) {
@@ -454,6 +464,7 @@
file.write(_escapePath(output));
file.write(':');
for (Uri dep in component.uriToSource.keys) {
+ if (dep == null) continue;
file.write(' ');
file.write(_escapePath(dep.toFilePath()));
}
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index 91d9426..f52a72a 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -10,6 +10,8 @@
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart';
import 'package:kernel/kernel.dart';
+const String kDebugProcedureName = ":Eval";
+
/// Wrapper around [IncrementalKernelGenerator] that keeps track of rejected
/// deltas and combines them together into resultant program until it is
/// accepted.
@@ -19,11 +21,12 @@
CompilerOptions _compilerOptions;
bool initialized = false;
bool fullComponent = false;
+ Uri initializeFromDillUri;
IncrementalCompiler(this._compilerOptions, Uri entryPoint,
- {Uri bootstrapDill}) {
+ {this.initializeFromDillUri}) {
_generator = new IncrementalKernelGenerator(
- _compilerOptions, entryPoint, bootstrapDill);
+ _compilerOptions, entryPoint, initializeFromDillUri);
_pendingDeltas = <Component>[];
}
@@ -74,4 +77,30 @@
_pendingDeltas.clear();
fullComponent = true;
}
+
+ Future<Procedure> compileExpression(
+ String expression,
+ List<String> definitions,
+ List<String> typeDefinitions,
+ String libraryUri,
+ String klass,
+ bool isStatic) {
+ Map<String, DartType> completeDefinitions = {};
+ for (String name in definitions) {
+ if (!isLegalIdentifier(name)) continue;
+ completeDefinitions[name] = new DynamicType();
+ }
+
+ List<TypeParameter> typeParameters = [];
+ for (String name in typeDefinitions) {
+ if (!isLegalIdentifier(name)) continue;
+ typeParameters.add(new TypeParameter(name, new DynamicType()));
+ }
+
+ Uri library = Uri.parse(libraryUri);
+ if (library == null) return null;
+
+ return _generator.compileExpression(expression, completeDefinitions,
+ typeParameters, kDebugProcedureName, library, klass, isStatic);
+ }
}
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 8bf56e0..7d3cec8 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -7,16 +7,34 @@
import 'dart:async';
+import 'package:front_end/src/base/processed_options.dart'
+ show ProcessedOptions;
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+import 'package:front_end/src/fasta/fasta_codes.dart' as codes;
+
import 'package:front_end/src/api_prototype/compiler_options.dart'
- show CompilerOptions, ErrorHandler;
+ show CompilerOptions, ProblemHandler;
import 'package:front_end/src/api_prototype/kernel_generator.dart'
show kernelForProgram;
import 'package:front_end/src/api_prototype/compilation_message.dart'
- show CompilationMessage, Severity;
-import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Component, StaticGet, Field;
+ show Severity;
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/ast.dart'
+ show
+ Component,
+ Constant,
+ DartType,
+ Field,
+ FileUriNode,
+ Procedure,
+ StaticGet,
+ TreeNode;
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+import 'package:kernel/transformations/constants.dart' as constants;
+import 'package:kernel/vm/constants_native_effects.dart' as vm_constants;
+
+import 'bytecode/gen_bytecode.dart' show generateBytecode;
import 'transformations/devirtualization.dart' as devirtualization
show transformComponent;
@@ -36,35 +54,59 @@
{bool aot: false,
bool useGlobalTypeFlowAnalysis: false,
List<String> entryPoints,
- bool genBytecode: false}) async {
+ Map<String, String> environmentDefines,
+ bool genBytecode: false,
+ bool dropAST: false,
+ bool enableAsserts: false,
+ bool enableConstantEvaluation: true}) async {
// Replace error handler to detect if there are compilation errors.
final errorDetector =
- new ErrorDetector(previousErrorHandler: options.onError);
- options.onError = errorDetector;
+ new ErrorDetector(previousErrorHandler: options.onProblem);
+ options.onProblem = errorDetector;
final component = await kernelForProgram(source, options);
- // Restore error handler (in case 'options' are reused).
- options.onError = errorDetector.previousErrorHandler;
-
// Run global transformations only if component is correct.
- if (aot && (component != null) && !errorDetector.hasCompilationErrors) {
- _runGlobalTransformations(
- component, options.strongMode, useGlobalTypeFlowAnalysis, entryPoints);
+ if (aot && component != null) {
+ await _runGlobalTransformations(
+ source,
+ options,
+ component,
+ options.strongMode,
+ useGlobalTypeFlowAnalysis,
+ entryPoints,
+ environmentDefines,
+ enableAsserts,
+ enableConstantEvaluation,
+ errorDetector);
}
+ // Restore error handler (in case 'options' are reused).
+ options.onProblem = errorDetector.previousErrorHandler;
+
if (genBytecode && component != null) {
- generateBytecode(component, strongMode: options.strongMode);
+ generateBytecode(component,
+ strongMode: options.strongMode, dropAST: dropAST);
}
return component;
}
-_runGlobalTransformations(Component component, bool strongMode,
- bool useGlobalTypeFlowAnalysis, List<String> entryPoints) {
+Future _runGlobalTransformations(
+ Uri source,
+ CompilerOptions compilerOptions,
+ Component component,
+ bool strongMode,
+ bool useGlobalTypeFlowAnalysis,
+ List<String> entryPoints,
+ Map<String, String> environmentDefines,
+ bool enableAsserts,
+ bool enableConstantEvaluation,
+ ErrorDetector errorDetector) async {
if (strongMode) {
- final coreTypes = new CoreTypes(component);
+ if (errorDetector.hasCompilationErrors) return;
+ final coreTypes = new CoreTypes(component);
_patchVmConstants(coreTypes);
// TODO(alexmarkov, dmitryas): Consider doing canonicalization of identical
@@ -81,10 +123,56 @@
devirtualization.transformComponent(coreTypes, component);
}
+ if (enableConstantEvaluation) {
+ await _performConstantEvaluation(source, compilerOptions, component,
+ coreTypes, environmentDefines, strongMode, enableAsserts);
+
+ if (errorDetector.hasCompilationErrors) return;
+ }
+
no_dynamic_invocations_annotator.transformComponent(component);
}
}
+Future _performConstantEvaluation(
+ Uri source,
+ CompilerOptions compilerOptions,
+ Component component,
+ CoreTypes coreTypes,
+ Map<String, String> environmentDefines,
+ bool strongMode,
+ bool enableAsserts) async {
+ final vmConstants =
+ new vm_constants.VmConstantsBackend(environmentDefines, coreTypes);
+
+ final processedOptions =
+ new ProcessedOptions(compilerOptions, false, [source]);
+
+ // Run within the context, so we have uri source tokens...
+ await CompilerContext.runWithOptions(processedOptions,
+ (CompilerContext context) async {
+ // To make the fileUri/fileOffset -> line/column mapping, we need to
+ // pre-fill the map.
+ context.uriToSource.addAll(component.uriToSource);
+
+ final hierarchy = new ClassHierarchy(component);
+ final typeEnvironment =
+ new TypeEnvironment(coreTypes, hierarchy, strongMode: strongMode);
+
+ // NOTE: Currently we keep fields, because there are certain constant
+ // fields which the VM accesses (e.g. `_Random._A` needs to be preserved).
+ // TODO(kustermann): We should use the entrypoints manifest to find out
+ // which fields need to be preserved and remove the rest.
+ constants.transformComponent(component, vmConstants,
+ keepFields: true,
+ strongMode: true,
+ evaluateAnnotations: false,
+ enableAsserts: enableAsserts,
+ errorReporter:
+ new ForwardConstantEvaluationErrors(context, typeEnvironment));
+ });
+}
+
void _patchVmConstants(CoreTypes coreTypes) {
// Fix Endian.host to be a const field equal to Endial.little instead of
// a final field. VM does not support big-endian architectures at the
@@ -101,16 +189,147 @@
}
class ErrorDetector {
- final ErrorHandler previousErrorHandler;
+ final ProblemHandler previousErrorHandler;
bool hasCompilationErrors = false;
ErrorDetector({this.previousErrorHandler});
- void call(CompilationMessage message) {
- if (message.severity == Severity.error) {
+ void call(codes.FormattedMessage problem, Severity severity,
+ List<codes.FormattedMessage> context) {
+ if (severity == Severity.error) {
hasCompilationErrors = true;
}
- previousErrorHandler?.call(message);
+ previousErrorHandler?.call(problem, severity, context);
+ }
+}
+
+class ErrorPrinter {
+ final ProblemHandler previousErrorHandler;
+ final compilationMessages = <Uri, List<List>>{};
+
+ ErrorPrinter({this.previousErrorHandler});
+
+ void call(codes.FormattedMessage problem, Severity severity,
+ List<codes.FormattedMessage> context) {
+ final sourceUri = problem.locatedMessage.uri;
+ compilationMessages.putIfAbsent(sourceUri, () => [])
+ ..add([problem, context]);
+ previousErrorHandler?.call(problem, severity, context);
+ }
+
+ void printCompilationMessages(Uri baseUri) {
+ final sortedUris = compilationMessages.keys.toList()
+ ..sort((a, b) => '$a'.compareTo('$b'));
+ for (final Uri sourceUri in sortedUris) {
+ for (final List errorTuple in compilationMessages[sourceUri]) {
+ final codes.FormattedMessage message = errorTuple.first;
+ print(message.formatted);
+
+ final List context = errorTuple.last;
+ for (final codes.FormattedMessage message in context?.reversed) {
+ print(message.formatted);
+ }
+ }
+ }
+ }
+}
+
+class ForwardConstantEvaluationErrors implements constants.ErrorReporter {
+ final CompilerContext compilerContext;
+ final TypeEnvironment typeEnvironment;
+
+ ForwardConstantEvaluationErrors(this.compilerContext, this.typeEnvironment);
+
+ duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
+ final message = codes.templateConstEvalDuplicateKey.withArguments(key);
+ reportIt(context, message, node);
+ }
+
+ invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
+ DartType expectedType) {
+ final message = codes.templateConstEvalInvalidType.withArguments(
+ receiver, expectedType, receiver.getType(typeEnvironment));
+ reportIt(context, message, node);
+ }
+
+ invalidBinaryOperandType(
+ List<TreeNode> context,
+ TreeNode node,
+ Constant receiver,
+ String op,
+ DartType expectedType,
+ DartType actualType) {
+ final message = codes.templateConstEvalInvalidBinaryOperandType
+ .withArguments(op, receiver, expectedType, actualType);
+ reportIt(context, message, node);
+ }
+
+ invalidMethodInvocation(
+ List<TreeNode> context, TreeNode node, Constant receiver, String op) {
+ final message = codes.templateConstEvalInvalidMethodInvocation
+ .withArguments(op, receiver);
+ reportIt(context, message, node);
+ }
+
+ invalidStaticInvocation(
+ List<TreeNode> context, TreeNode node, Procedure target) {
+ final message = codes.templateConstEvalInvalidStaticInvocation
+ .withArguments(target.name.toString());
+ reportIt(context, message, node);
+ }
+
+ invalidStringInterpolationOperand(
+ List<TreeNode> context, TreeNode node, Constant constant) {
+ final message = codes.templateConstEvalInvalidStringInterpolationOperand
+ .withArguments(constant);
+ reportIt(context, message, node);
+ }
+
+ nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+ final message =
+ codes.templateConstEvalNonConstantLiteral.withArguments(klass);
+ reportIt(context, message, node);
+ }
+
+ failedAssertion(List<TreeNode> context, TreeNode node, String string) {
+ final message = string == null
+ ? codes.messageConstEvalFailedAssertion
+ : codes.templateConstEvalFailedAssertionWithMessage
+ .withArguments(string);
+ reportIt(context, message, node);
+ }
+
+ reportIt(List<TreeNode> context, codes.Message message, TreeNode node) {
+ final Uri uri = getFileUri(node);
+ final int fileOffset = getFileOffset(node);
+
+ final contextMessages = <codes.LocatedMessage>[];
+ for (final TreeNode node in context) {
+ final Uri uri = getFileUri(node);
+ final int fileOffset = getFileOffset(node);
+ contextMessages.add(codes.messageConstEvalContext
+ .withLocation(uri, fileOffset, codes.noLength));
+ }
+
+ final locatedMessage =
+ message.withLocation(uri, fileOffset, codes.noLength);
+
+ compilerContext.options
+ .report(locatedMessage, Severity.error, context: contextMessages);
+ }
+
+ getFileUri(TreeNode node) {
+ while (node is! FileUriNode) {
+ node = node.parent;
+ }
+ return (node as FileUriNode).fileUri;
+ }
+
+ getFileOffset(TreeNode node) {
+ while (node.fileOffset == TreeNode.noOffset) {
+ node = node.parent;
+ }
+ return node == null ? TreeNode.noOffset : node.fileOffset;
}
}
diff --git a/pkg/vm/lib/metadata/bytecode.dart b/pkg/vm/lib/metadata/bytecode.dart
index 1c28c0e..3d5261f 100644
--- a/pkg/vm/lib/metadata/bytecode.dart
+++ b/pkg/vm/lib/metadata/bytecode.dart
@@ -7,17 +7,82 @@
import 'package:kernel/ast.dart';
import 'package:vm/bytecode/constant_pool.dart' show ConstantPool;
import 'package:vm/bytecode/disassembler.dart' show BytecodeDisassembler;
+import 'package:vm/bytecode/exceptions.dart' show ExceptionsTable;
/// Metadata containing bytecode.
+///
+/// In kernel binary, bytecode metadata is encoded as following:
+///
+/// type BytecodeMetadata {
+/// List<Byte> bytecodes
+/// ExceptionsTable exceptionsTable
+/// ConstantPool constantPool
+/// List<ClosureBytecode> closures
+/// }
+///
+/// type ClosureBytecode {
+/// ConstantIndex closureFunction
+/// List<Byte> bytecodes
+/// ExceptionsTable exceptionsTable
+/// }
+///
+/// Encoding of ExceptionsTable is described in
+/// pkg/vm/lib/bytecode/exceptions.dart.
+///
+/// Encoding of ConstantPool is described in
+/// pkg/vm/lib/bytecode/constant_pool.dart.
+///
class BytecodeMetadata {
final List<int> bytecodes;
+ final ExceptionsTable exceptionsTable;
final ConstantPool constantPool;
+ final List<ClosureBytecode> closures;
- BytecodeMetadata(this.bytecodes, this.constantPool);
+ BytecodeMetadata(
+ this.bytecodes, this.exceptionsTable, this.constantPool, this.closures);
@override
- String toString() =>
- "\nBytecode {\n${new BytecodeDisassembler().disassemble(bytecodes)}}\n$constantPool";
+ String toString() => "\n"
+ "Bytecode {\n"
+ "${new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable)}}\n"
+ "$exceptionsTable"
+ "$constantPool"
+ "${closures.join('\n')}";
+}
+
+/// Bytecode of a nested function (closure).
+/// Closures share the constant pool of a top-level member.
+class ClosureBytecode {
+ final int closureFunctionConstantIndex;
+ final List<int> bytecodes;
+ final ExceptionsTable exceptionsTable;
+
+ ClosureBytecode(
+ this.closureFunctionConstantIndex, this.bytecodes, this.exceptionsTable);
+
+ void writeToBinary(BinarySink sink) {
+ sink.writeUInt30(closureFunctionConstantIndex);
+ sink.writeByteList(bytecodes);
+ exceptionsTable.writeToBinary(sink);
+ }
+
+ factory ClosureBytecode.readFromBinary(BinarySource source) {
+ final closureFunctionConstantIndex = source.readUInt();
+ final List<int> bytecodes = source.readByteList();
+ final exceptionsTable = new ExceptionsTable.readFromBinary(source);
+ return new ClosureBytecode(
+ closureFunctionConstantIndex, bytecodes, exceptionsTable);
+ }
+
+ @override
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.writeln('Closure CP#$closureFunctionConstantIndex {');
+ sb.writeln(
+ new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable));
+ sb.writeln('}');
+ return sb.toString();
+ }
}
/// Repository for [BytecodeMetadata].
@@ -30,15 +95,23 @@
<TreeNode, BytecodeMetadata>{};
@override
- void writeToBinary(BytecodeMetadata metadata, BinarySink sink) {
+ void writeToBinary(BytecodeMetadata metadata, Node node, BinarySink sink) {
sink.writeByteList(metadata.bytecodes);
- metadata.constantPool.writeToBinary(sink);
+ metadata.exceptionsTable.writeToBinary(sink);
+ metadata.constantPool.writeToBinary(node, sink);
+ sink.writeUInt30(metadata.closures.length);
+ metadata.closures.forEach((c) => c.writeToBinary(sink));
}
@override
- BytecodeMetadata readFromBinary(BinarySource source) {
+ BytecodeMetadata readFromBinary(Node node, BinarySource source) {
final List<int> bytecodes = source.readByteList();
- final ConstantPool constantPool = new ConstantPool.readFromBinary(source);
- return new BytecodeMetadata(bytecodes, constantPool);
+ final exceptionsTable = new ExceptionsTable.readFromBinary(source);
+ final ConstantPool constantPool =
+ new ConstantPool.readFromBinary(node, source);
+ final List<ClosureBytecode> closures = new List<ClosureBytecode>.generate(
+ source.readUInt(), (_) => new ClosureBytecode.readFromBinary(source));
+ return new BytecodeMetadata(
+ bytecodes, exceptionsTable, constantPool, closures);
}
}
diff --git a/pkg/vm/lib/metadata/direct_call.dart b/pkg/vm/lib/metadata/direct_call.dart
index 570e303..dd9348c 100644
--- a/pkg/vm/lib/metadata/direct_call.dart
+++ b/pkg/vm/lib/metadata/direct_call.dart
@@ -34,13 +34,13 @@
<TreeNode, DirectCallMetadata>{};
@override
- void writeToBinary(DirectCallMetadata metadata, BinarySink sink) {
+ void writeToBinary(DirectCallMetadata metadata, Node node, BinarySink sink) {
sink.writeCanonicalNameReference(getCanonicalNameOfMember(metadata.target));
sink.writeByte(metadata.checkReceiverForNull ? 1 : 0);
}
@override
- DirectCallMetadata readFromBinary(BinarySource source) {
+ DirectCallMetadata readFromBinary(Node node, BinarySource source) {
final targetReference = source.readCanonicalNameReference()?.getReference();
if (targetReference == null) {
throw 'DirectCallMetadata should have a non-null target';
diff --git a/pkg/vm/lib/metadata/inferred_type.dart b/pkg/vm/lib/metadata/inferred_type.dart
index dafb370..17daf11 100644
--- a/pkg/vm/lib/metadata/inferred_type.dart
+++ b/pkg/vm/lib/metadata/inferred_type.dart
@@ -32,14 +32,14 @@
final Map<TreeNode, InferredType> mapping = <TreeNode, InferredType>{};
@override
- void writeToBinary(InferredType metadata, BinarySink sink) {
+ void writeToBinary(InferredType metadata, Node node, BinarySink sink) {
sink.writeCanonicalNameReference(
getCanonicalNameOfClass(metadata.concreteClass));
sink.writeByte(metadata.nullable ? 1 : 0);
}
@override
- InferredType readFromBinary(BinarySource source) {
+ InferredType readFromBinary(Node node, BinarySource source) {
final concreteClassReference =
source.readCanonicalNameReference()?.getReference();
final nullable = (source.readByte() != 0);
diff --git a/pkg/vm/lib/metadata/procedure_attributes.dart b/pkg/vm/lib/metadata/procedure_attributes.dart
index 5581074..531f7d2 100644
--- a/pkg/vm/lib/metadata/procedure_attributes.dart
+++ b/pkg/vm/lib/metadata/procedure_attributes.dart
@@ -39,7 +39,8 @@
<TreeNode, ProcedureAttributesMetadata>{};
@override
- void writeToBinary(ProcedureAttributesMetadata metadata, BinarySink sink) {
+ void writeToBinary(
+ ProcedureAttributesMetadata metadata, Node node, BinarySink sink) {
int flags = 0;
if (metadata.hasDynamicUses) {
flags |= kDynamicUsesBit;
@@ -54,7 +55,7 @@
}
@override
- ProcedureAttributesMetadata readFromBinary(BinarySource source) {
+ ProcedureAttributesMetadata readFromBinary(Node node, BinarySource source) {
final int flags = source.readByte();
final bool hasDynamicUses = (flags & kDynamicUsesBit) == kDynamicUsesBit;
diff --git a/pkg/vm/lib/metadata/unreachable.dart b/pkg/vm/lib/metadata/unreachable.dart
index aff77e2..a4c44e0 100644
--- a/pkg/vm/lib/metadata/unreachable.dart
+++ b/pkg/vm/lib/metadata/unreachable.dart
@@ -26,10 +26,10 @@
final Map<TreeNode, UnreachableNode> mapping = <TreeNode, UnreachableNode>{};
@override
- void writeToBinary(UnreachableNode metadata, BinarySink sink) {}
+ void writeToBinary(UnreachableNode metadata, Node node, BinarySink sink) {}
@override
- UnreachableNode readFromBinary(BinarySource source) {
+ UnreachableNode readFromBinary(Node node, BinarySource source) {
return const UnreachableNode();
}
}
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
index 479755d..b83c1cf 100644
--- a/pkg/vm/lib/transformations/devirtualization.dart
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -7,7 +7,7 @@
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/class_hierarchy.dart'
- show ClassHierarchy, ClosedWorldClassHierarchy;
+ show ClassHierarchy, ClassHierarchySubtypes, ClosedWorldClassHierarchy;
import '../metadata/direct_call.dart';
@@ -15,9 +15,10 @@
/// analysis. Assumes strong mode and closed world.
Component transformComponent(CoreTypes coreTypes, Component component) {
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
- final hierarchy = new ClassHierarchy(component,
+ ClosedWorldClassHierarchy hierarchy = new ClassHierarchy(component,
onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
- new CHADevirtualization(coreTypes, component, hierarchy)
+ final hierarchySubtypes = hierarchy.computeSubtypesInformation();
+ new CHADevirtualization(coreTypes, component, hierarchy, hierarchySubtypes)
.visitComponent(component);
return component;
}
@@ -140,15 +141,16 @@
/// Devirtualization based on the closed-world class hierarchy analysis.
class CHADevirtualization extends Devirtualization {
- final ClosedWorldClassHierarchy _hierarchy;
+ final ClassHierarchySubtypes _hierarchySubtype;
- CHADevirtualization(CoreTypes coreTypes, Component component, this._hierarchy)
- : super(coreTypes, component, _hierarchy);
+ CHADevirtualization(CoreTypes coreTypes, Component component,
+ ClosedWorldClassHierarchy hierarchy, this._hierarchySubtype)
+ : super(coreTypes, component, hierarchy);
@override
DirectCallMetadata getDirectCall(TreeNode node, Member target,
{bool setter = false}) {
- Member singleTarget = _hierarchy
+ Member singleTarget = _hierarchySubtype
.getSingleTargetForInterfaceInvocation(target, setter: setter);
if (singleTarget == null) {
return null;
diff --git a/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
index aff93fa..9806c89 100644
--- a/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
+++ b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
@@ -164,13 +164,6 @@
}
@override
- visitConstantExpression(ConstantExpression node) {
- // We run the kernel2kernel "constants" transformation before running the
- // this transformation, so we will encounter constant expressions.
- // We don't need to do anything here, because there are no invocations.
- }
-
- @override
visitMethodInvocation(MethodInvocation node) {
super.visitMethodInvocation(node);
diff --git a/pkg/vm/lib/transformations/type_flow/entry_points.json b/pkg/vm/lib/transformations/type_flow/entry_points.json
index 95d1f01..5465003 100644
--- a/pkg/vm/lib/transformations/type_flow/entry_points.json
+++ b/pkg/vm/lib/transformations/type_flow/entry_points.json
@@ -619,6 +619,12 @@
},
{
"library": "dart:core",
+ "class": "_InvocationMirror",
+ "name": "_allocateInvocationMirrorForClosure",
+ "action": "call"
+ },
+ {
+ "library": "dart:core",
"class": "_TypeError",
"name": "_TypeError._create",
"action": "call"
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 73e1194..ce9998f 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -379,7 +379,9 @@
void addUsedTypedef(Typedef typedef) {
if (_usedTypedefs.add(typedef)) {
- typedef.visitChildren(typeVisitor);
+ transformList(typedef.annotations, _pass1, typedef);
+ visitList(typedef.typeParameters, typeVisitor);
+ typedef.type?.accept(typeVisitor);
}
}
}
@@ -417,6 +419,14 @@
shaker.addUsedTypedef(typedef);
}
}
+
+ @override
+ visitTypeParameterType(TypeParameterType node) {
+ final parent = node.parameter.parent;
+ if (parent is Class) {
+ shaker.addClassUsedInType(parent);
+ }
+ }
}
/// The first pass of [TreeShaker].
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index 20b0126..f31cb60 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -10,6 +10,7 @@
show computePlatformBinariesLocation;
import 'package:kernel/ast.dart';
import 'package:kernel/text/ast_to_text.dart' show Printer;
+import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
import 'package:kernel/target/targets.dart';
import 'package:kernel/target/vm.dart';
import 'package:test/test.dart';
@@ -44,6 +45,18 @@
return buffer.toString();
}
+class DevNullSink<T> extends Sink<T> {
+ @override
+ void add(T data) {}
+
+ @override
+ void close() {}
+}
+
+void ensureKernelCanBeSerializedToBinary(Component component) {
+ new BinaryPrinter(new DevNullSink<List<int>>()).writeComponentFile(component);
+}
+
void compareResultWithExpectationsFile(Uri source, String actual) {
final expectFile = new File(source.toFilePath() + '.expect');
final expected = expectFile.existsSync() ? expectFile.readAsStringSync() : '';
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 07dcb37..009110a 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -30,6 +30,8 @@
final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
compareResultWithExpectationsFile(source, actual);
+
+ ensureKernelCanBeSerializedToBinary(component);
}
main() {
diff --git a/pkg/vm/testcases/bytecode/boostrapping.dart.expect b/pkg/vm/testcases/bytecode/boostrapping.dart.expect
index 264ed59..ba4d29e 100644
--- a/pkg/vm/testcases/bytecode/boostrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/boostrapping.dart.expect
@@ -451,7 +451,7 @@
}
[@vm.bytecode=
Bytecode {
- Entry 2
+ Entry 1
CheckStack
PushConstant CP#0
PushStatic CP#0
@@ -478,8 +478,8 @@
PushConstant CP#5
PushStatic CP#5
InstanceCall1 1, CP#9
- StoreLocal r1
- Push r1
+ StoreLocal r0
+ Push r0
StoreStaticTOS CP#0
Drop1
L3:
diff --git a/pkg/vm/testcases/bytecode/closures.dart b/pkg/vm/testcases/bytecode/closures.dart
new file mode 100644
index 0000000..102cb0f
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/closures.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+int simpleClosure() {
+ int x = 5;
+ var inc = (int y) {
+ x = x + y;
+ };
+ inc(3);
+ return x;
+}
+
+class C1 {}
+
+class C2 {}
+
+class C3 {}
+
+class C4 {}
+
+class C5 {}
+
+class C6 {}
+
+class C7 {}
+
+class C8 {}
+
+class A<T1, T2> {
+ void foo<T3, T4>() {
+ void nested1<T5, T6>() {
+ void nested2<T7, T8>() {
+ var nested3 = () {
+ print([T1, T2, T3, T4, T5, T6, T7, T8]);
+ callWithArgs<T1, T2, T3, T4, T5, T6, T7, T8>();
+ };
+ nested3();
+ }
+
+ nested2<C7, C8>();
+ nested2<List<C7>, List<C8>>();
+ }
+
+ nested1<C5, C6>();
+ nested1<List<C5>, List<C6>>();
+ }
+}
+
+void callWithArgs<T1, T2, T3, T4, T5, T6, T7, T8>() {
+ print([T1, T2, T3, T4, T5, T6, T7, T8]);
+}
+
+void callA() {
+ new A<C1, C2>().foo<C3, C4>();
+ new A<C1, C2>().foo<List<C3>, List<C4>>();
+ new A<List<C1>, List<C2>>().foo<List<C3>, List<C4>>();
+}
+
+class B {
+ int foo;
+
+ void topLevel() {
+ {
+ int x = 1;
+
+ {
+ int y = 2;
+ int z = 3;
+
+ var closure1 = (int y) {
+ x = y + 1;
+
+ if (x > 5) {
+ int w = 4;
+
+ void closure2() {
+ z = x + 2;
+ w = foo + y;
+ }
+
+ closure2();
+
+ print(w);
+ }
+ };
+
+ closure1(10);
+ closure1(11);
+
+ print(y);
+ print(z);
+ }
+
+ print(x);
+ }
+
+ {
+ int x = 42;
+
+ var closure3 = () {
+ foo = x;
+ };
+
+ closure3();
+ }
+ }
+}
+
+class C {
+ void testForLoop() {
+ int delta = 0;
+ List<Function> getI = <Function>[];
+ List<Function> setI = <Function>[];
+ for (int i = 0; i < 10; i++) {
+ getI.add(() => i + delta);
+ setI.add((int ii) {
+ i = ii + delta;
+ });
+ }
+ }
+
+ void testForInLoop(List<int> list) {
+ for (var i in list) {
+ var inc = () {
+ i = i + 1;
+ };
+ inc();
+ print(i);
+ }
+ }
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
new file mode 100644
index 0000000..2f1906c
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -0,0 +1,1394 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class C1 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class C2 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class C3 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class C4 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class C5 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class C6 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class C7 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class C8 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class A<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic> extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 4
+ CheckStack
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ Push FP[-5]
+ StoreFieldTOS CP#1
+ Allocate CP#38
+ StoreLocal r3
+ Push r3
+ Push r0
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ StoreFieldTOS CP#39
+ Push r3
+ Push FP[-6]
+ StoreFieldTOS CP#4
+ Push r3
+ PushConstant CP#2
+ StoreFieldTOS CP#40
+ Push r3
+ Push r0
+ StoreFieldTOS CP#3
+ PopLocal r2
+ PushConstant CP#49
+ Push r2
+ InstanceCall1 1, CP#50
+ Drop1
+ PushConstant CP#51
+ Push r2
+ InstanceCall1 1, CP#52
+ Drop1
+ PushConstant CP#36
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ContextOffset parent
+ [1] = ContextOffset var [0]
+ [2] = ClosureFunction nested1 <T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void;
+ [3] = FieldOffset dart.core::_Closure::_context
+ [4] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [5] = Int 2
+ [6] = Int 4
+ [7] = ArgDesc num-args 4, num-type-args 0, names []
+ [8] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#7
+ [9] = ClosureFunction nested2 <T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void;
+ [10] = Int 6
+ [11] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#7
+ [12] = ClosureFunction <anonymous closure> () → dart.core::Null;
+ [13] = TypeArgs [dart.core::Type]
+ [14] = Int 8
+ [15] = Int 0
+ [16] = Type #lib::A::T1
+ [17] = TypeArgumentsFieldOffset #lib::A
+ [18] = Int 1
+ [19] = Type #lib::A::T2
+ [20] = Type #lib::A::foo::T3
+ [21] = Int 3
+ [22] = Type #lib::A::foo::T4
+ [23] = Type T5
+ [24] = Int 5
+ [25] = Type T6
+ [26] = Type T7
+ [27] = Int 7
+ [28] = Type T8
+ [29] = ArgDesc num-args 1, num-type-args 1, names []
+ [30] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#29
+ [31] = ArgDesc num-args 1, num-type-args 0, names []
+ [32] = StaticICData target 'dart.core::print', arg-desc CP#31
+ [33] = TypeArgs [#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8]
+ [34] = ArgDesc num-args 0, num-type-args 8, names []
+ [35] = StaticICData target '#lib::callWithArgs', arg-desc CP#34
+ [36] = Null
+ [37] = EndClosureFunctionScope
+ [38] = Class dart.core::_Closure
+ [39] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [40] = FieldOffset dart.core::_Closure::_function
+ [41] = ICData target-name 'call', arg-desc CP#31
+ [42] = EndClosureFunctionScope
+ [43] = TypeArgs [#lib::C7, #lib::C8]
+ [44] = ArgDesc num-args 1, num-type-args 2, names []
+ [45] = ICData target-name 'call', arg-desc CP#44
+ [46] = TypeArgs [dart.core::List<#lib::C7>, dart.core::List<#lib::C8>]
+ [47] = ICData target-name 'call', arg-desc CP#44
+ [48] = EndClosureFunctionScope
+ [49] = TypeArgs [#lib::C5, #lib::C6]
+ [50] = ICData target-name 'call', arg-desc CP#44
+ [51] = TypeArgs [dart.core::List<#lib::C5>, dart.core::List<#lib::C6>]
+ [52] = ICData target-name 'call', arg-desc CP#44
+}
+Closure CP#12 {
+ Entry 4
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#3
+ PopLocal r1
+ Push FP[-5]
+ LoadFieldTOS CP#4
+ PopLocal r0
+ PushConstant CP#13
+ StoreLocal r3
+ Push r3
+ PushConstant CP#14
+ CreateArrayTOS
+ StoreLocal r3
+ Push r3
+ PushConstant CP#15
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#16
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#18
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#19
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#5
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#20
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#21
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#22
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#6
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#23
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#24
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#25
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#10
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#26
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#27
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateType CP#28
+ StoreIndexedTOS
+ PushConstant CP#30
+ IndirectStaticCall 2, CP#29
+ PushConstant CP#32
+ IndirectStaticCall 1, CP#31
+ Drop1
+ Push r1
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ Push r0
+ InstantiateTypeArgumentsTOS 1, CP#33
+ PushConstant CP#35
+ IndirectStaticCall 1, CP#34
+ Drop1
+ PushConstant CP#36
+ ReturnTOS
+
+}
+
+Closure CP#9 {
+ Entry 4
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#3
+ PopLocal r0
+ Push FP[-6]
+ Push FP[-5]
+ LoadFieldTOS CP#4
+ PushConstant CP#6
+ PushConstant CP#10
+ PushConstant CP#11
+ IndirectStaticCall 4, CP#7
+ PopLocal FP[-6]
+ Allocate CP#38
+ StoreLocal r3
+ Push r3
+ Push r0
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ StoreFieldTOS CP#39
+ Push r3
+ Push FP[-6]
+ StoreFieldTOS CP#4
+ Push r3
+ PushConstant CP#12
+ StoreFieldTOS CP#40
+ Push r3
+ Push r0
+ StoreFieldTOS CP#3
+ PopLocal r2
+ Push r2
+ InstanceCall1 1, CP#41
+ Drop1
+ PushConstant CP#36
+ ReturnTOS
+
+}
+
+Closure CP#2 {
+ Entry 4
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#3
+ PopLocal r0
+ Push FP[-6]
+ Push FP[-5]
+ LoadFieldTOS CP#4
+ PushConstant CP#5
+ PushConstant CP#6
+ PushConstant CP#8
+ IndirectStaticCall 4, CP#7
+ PopLocal FP[-6]
+ Allocate CP#38
+ StoreLocal r3
+ Push r3
+ Push r0
+ LoadFieldTOS CP#1
+ LoadFieldTOS CP#17
+ StoreFieldTOS CP#39
+ Push r3
+ Push FP[-6]
+ StoreFieldTOS CP#4
+ Push r3
+ PushConstant CP#9
+ StoreFieldTOS CP#40
+ Push r3
+ Push r0
+ StoreFieldTOS CP#3
+ PopLocal r2
+ PushConstant CP#43
+ Push r2
+ InstanceCall1 1, CP#45
+ Drop1
+ PushConstant CP#46
+ Push r2
+ InstanceCall1 1, CP#47
+ Drop1
+ PushConstant CP#36
+ ReturnTOS
+
+}
+] method foo<T3 extends core::Object = dynamic, T4 extends core::Object = dynamic>() → void {
+ function nested1<T5 extends core::Object = dynamic, T6 extends core::Object = dynamic>() → void {
+ function nested2<T7 extends core::Object = dynamic, T8 extends core::Object = dynamic>() → void {
+ () → core::Null nested3 = () → core::Null {
+ core::print(<core::Type>[self::A::T1, self::A::T2, self::A::foo::T3, self::A::foo::T4, T5, T6, T7, T8]);
+ self::callWithArgs<self::A::T1, self::A::T2, self::A::foo::T3, self::A::foo::T4, T5, T6, T7, T8>();
+ };
+ nested3.call();
+ }
+ nested2.call<self::C7, self::C8>();
+ nested2.call<core::List<self::C7>, core::List<self::C8>>();
+ }
+ nested1.call<self::C5, self::C6>();
+ nested1.call<core::List<self::C5>, core::List<self::C6>>();
+ }
+}
+class B extends core::Object {
+ field core::int foo = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 5
+ CheckStack
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ Push FP[-5]
+ StoreFieldTOS CP#1
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#2
+ StoreFieldTOS CP#1
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ PushConstant CP#3
+ PopLocal r2
+ Push r0
+ PushConstant CP#4
+ StoreFieldTOS CP#1
+ Allocate CP#20
+ StoreLocal r4
+ Push r4
+ PushConstant CP#18
+ StoreFieldTOS CP#21
+ Push r4
+ PushConstant CP#18
+ StoreFieldTOS CP#22
+ Push r4
+ PushConstant CP#5
+ StoreFieldTOS CP#23
+ Push r4
+ Push r0
+ StoreFieldTOS CP#6
+ PopLocal r3
+ Push r3
+ PushConstant CP#27
+ InstanceCall1 2, CP#28
+ Drop1
+ Push r3
+ PushConstant CP#29
+ InstanceCall1 2, CP#30
+ Drop1
+ Push r2
+ PushConstant CP#31
+ IndirectStaticCall 1, CP#15
+ Drop1
+ Push r0
+ LoadFieldTOS CP#1
+ PushConstant CP#32
+ IndirectStaticCall 1, CP#15
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#1
+ PushConstant CP#33
+ IndirectStaticCall 1, CP#15
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#34
+ StoreFieldTOS CP#1
+ Allocate CP#20
+ StoreLocal r3
+ Push r3
+ PushConstant CP#18
+ StoreFieldTOS CP#21
+ Push r3
+ PushConstant CP#18
+ StoreFieldTOS CP#22
+ Push r3
+ PushConstant CP#35
+ StoreFieldTOS CP#23
+ Push r3
+ Push r0
+ StoreFieldTOS CP#6
+ PopLocal r2
+ Push r2
+ InstanceCall1 1, CP#38
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ PushConstant CP#18
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ContextOffset parent
+ [1] = ContextOffset var [0]
+ [2] = Int 1
+ [3] = Int 2
+ [4] = Int 3
+ [5] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
+ [6] = FieldOffset dart.core::_Closure::_context
+ [7] = ArgDesc num-args 2, num-type-args 0, names []
+ [8] = ICData target-name '+', arg-desc CP#7
+ [9] = Int 5
+ [10] = ICData target-name '>', arg-desc CP#7
+ [11] = Bool true
+ [12] = Int 4
+ [13] = ClosureFunction closure2 () → void;
+ [14] = ICData target-name '+', arg-desc CP#7
+ [15] = ArgDesc num-args 1, num-type-args 0, names []
+ [16] = ICData target-name 'get:foo', arg-desc CP#15
+ [17] = ICData target-name '+', arg-desc CP#7
+ [18] = Null
+ [19] = EndClosureFunctionScope
+ [20] = Class dart.core::_Closure
+ [21] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [22] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [23] = FieldOffset dart.core::_Closure::_function
+ [24] = ICData target-name 'call', arg-desc CP#15
+ [25] = StaticICData target 'dart.core::print', arg-desc CP#15
+ [26] = EndClosureFunctionScope
+ [27] = Int 10
+ [28] = ICData target-name 'call', arg-desc CP#7
+ [29] = Int 11
+ [30] = ICData target-name 'call', arg-desc CP#7
+ [31] = StaticICData target 'dart.core::print', arg-desc CP#15
+ [32] = StaticICData target 'dart.core::print', arg-desc CP#15
+ [33] = StaticICData target 'dart.core::print', arg-desc CP#15
+ [34] = Int 42
+ [35] = ClosureFunction <anonymous closure> () → dart.core::Null;
+ [36] = ICData target-name 'set:foo', arg-desc CP#7
+ [37] = EndClosureFunctionScope
+ [38] = ICData target-name 'call', arg-desc CP#15
+}
+Closure CP#13 {
+ Entry 3
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#6
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#1
+ PushConstant CP#3
+ InstanceCall1 2, CP#14
+ StoreLocal r2
+ StoreFieldTOS CP#1
+ Push r2
+ Drop1
+ Push r0
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#1
+ InstanceCall1 1, CP#16
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#1
+ InstanceCall1 2, CP#17
+ StoreLocal r2
+ StoreFieldTOS CP#1
+ Push r2
+ Drop1
+ PushConstant CP#18
+ ReturnTOS
+
+}
+
+Closure CP#5 {
+ Entry 4
+ CheckStack
+ Push FP[-6]
+ LoadFieldTOS CP#6
+ PopLocal r0
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ Push FP[-5]
+ StoreFieldTOS CP#1
+ Push r0
+ Push FP[-5]
+ StoreFieldTOS CP#1
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ Push r0
+ LoadFieldTOS CP#1
+ PushConstant CP#2
+ InstanceCall1 2, CP#8
+ StoreLocal r2
+ StoreFieldTOS CP#1
+ Push r2
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#1
+ PushConstant CP#9
+ InstanceCall1 2, CP#10
+ PushConstant CP#11
+ IfNeStrictTOS
+ Jump L1
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#12
+ StoreFieldTOS CP#1
+ Allocate CP#20
+ StoreLocal r2
+ Push r2
+ PushConstant CP#18
+ StoreFieldTOS CP#21
+ Push r2
+ PushConstant CP#18
+ StoreFieldTOS CP#22
+ Push r2
+ PushConstant CP#13
+ StoreFieldTOS CP#23
+ Push r2
+ Push r0
+ StoreFieldTOS CP#6
+ PopLocal r3
+ Push r3
+ InstanceCall1 1, CP#24
+ Drop1
+ Push r0
+ LoadFieldTOS CP#1
+ PushConstant CP#25
+ IndirectStaticCall 1, CP#15
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+L1:
+ PushConstant CP#18
+ ReturnTOS
+
+}
+
+Closure CP#35 {
+ Entry 3
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#6
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#1
+ Push r0
+ LoadFieldTOS CP#1
+ StoreLocal r2
+ InstanceCall1 2, CP#36
+ Drop1
+ Push r2
+ Drop1
+ PushConstant CP#18
+ ReturnTOS
+
+}
+] method topLevel() → void {
+ {
+ core::int x = 1;
+ {
+ core::int y = 2;
+ core::int z = 3;
+ (core::int) → core::Null closure1 = (core::int y) → core::Null {
+ x = y.{core::num::+}(1);
+ if(x.{core::num::>}(5)) {
+ core::int w = 4;
+ function closure2() → void {
+ z = x.{core::num::+}(2);
+ w = this.{self::B::foo}.{core::num::+}(y);
+ }
+ closure2.call();
+ core::print(w);
+ }
+ };
+ closure1.call(10);
+ closure1.call(11);
+ core::print(y);
+ core::print(z);
+ }
+ core::print(x);
+ }
+ {
+ core::int x = 42;
+ () → core::Null closure3 = () → core::Null {
+ this.{self::B::foo} = x;
+ };
+ closure3.call();
+ }
+ }
+}
+class C extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 5
+ CheckStack
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#1
+ StoreFieldTOS CP#2
+ PushConstant CP#3
+ StoreLocal r3
+ Push r3
+ PushConstant CP#1
+ CreateArrayTOS
+ StoreLocal r3
+ PushConstant CP#5
+ IndirectStaticCall 2, CP#4
+ PopLocal r2
+ PushConstant CP#3
+ StoreLocal r3
+ Push r3
+ PushConstant CP#1
+ CreateArrayTOS
+ StoreLocal r3
+ PushConstant CP#6
+ IndirectStaticCall 2, CP#4
+ PopLocal r4
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#1
+ StoreFieldTOS CP#2
+L2:
+ CheckStack
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#7
+ InstanceCall1 2, CP#9
+ PushConstant CP#10
+ IfNeStrictTOS
+ Jump L1
+ Push r2
+ Allocate CP#16
+ StoreLocal r3
+ Push r3
+ PushConstant CP#14
+ StoreFieldTOS CP#17
+ Push r3
+ PushConstant CP#14
+ StoreFieldTOS CP#18
+ Push r3
+ PushConstant CP#11
+ StoreFieldTOS CP#19
+ Push r3
+ Push r0
+ StoreFieldTOS CP#12
+ InstanceCall1 2, CP#20
+ Drop1
+ Push r4
+ Allocate CP#16
+ StoreLocal r3
+ Push r3
+ PushConstant CP#14
+ StoreFieldTOS CP#17
+ Push r3
+ PushConstant CP#14
+ StoreFieldTOS CP#18
+ Push r3
+ PushConstant CP#21
+ StoreFieldTOS CP#19
+ Push r3
+ Push r0
+ StoreFieldTOS CP#12
+ InstanceCall1 2, CP#24
+ Drop1
+ Push r0
+ CloneContext
+ PopLocal r0
+ Push r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#25
+ InstanceCall1 2, CP#26
+ StoreLocal r3
+ StoreFieldTOS CP#2
+ Push r3
+ Drop1
+ Jump L2
+L1:
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ PushConstant CP#14
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ContextOffset parent
+ [1] = Int 0
+ [2] = ContextOffset var [0]
+ [3] = TypeArgs [dart.core::Function]
+ [4] = ArgDesc num-args 1, num-type-args 1, names []
+ [5] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#4
+ [6] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#4
+ [7] = Int 10
+ [8] = ArgDesc num-args 2, num-type-args 0, names []
+ [9] = ICData target-name '<', arg-desc CP#8
+ [10] = Bool true
+ [11] = ClosureFunction <anonymous closure> () → dart.core::int;
+ [12] = FieldOffset dart.core::_Closure::_context
+ [13] = ICData target-name '+', arg-desc CP#8
+ [14] = Null
+ [15] = EndClosureFunctionScope
+ [16] = Class dart.core::_Closure
+ [17] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [18] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [19] = FieldOffset dart.core::_Closure::_function
+ [20] = ICData target-name 'add', arg-desc CP#8
+ [21] = ClosureFunction <anonymous closure> (dart.core::int ii) → dart.core::Null;
+ [22] = ICData target-name '+', arg-desc CP#8
+ [23] = EndClosureFunctionScope
+ [24] = ICData target-name 'add', arg-desc CP#8
+ [25] = Int 1
+ [26] = ICData target-name '+', arg-desc CP#8
+}
+Closure CP#11 {
+ Entry 2
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#12
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#2
+ InstanceCall1 2, CP#13
+ ReturnTOS
+ PushConstant CP#14
+ ReturnTOS
+
+}
+
+Closure CP#21 {
+ Entry 3
+ CheckStack
+ Push FP[-6]
+ LoadFieldTOS CP#12
+ PopLocal r0
+ Push r0
+ Push FP[-5]
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#2
+ InstanceCall1 2, CP#22
+ StoreLocal r2
+ StoreFieldTOS CP#2
+ Push r2
+ Drop1
+ PushConstant CP#14
+ ReturnTOS
+
+}
+] method testForLoop() → void {
+ core::int delta = 0;
+ core::List<core::Function> getI = <core::Function>[];
+ core::List<core::Function> setI = <core::Function>[];
+ for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+ getI.{core::List::add}(() → core::int => i.{core::num::+}(delta));
+ setI.{core::List::add}((core::int ii) → core::Null {
+ i = ii.{core::num::+}(delta);
+ });
+ }
+ }
+[@vm.bytecode=
+Bytecode {
+ Entry 5
+ CheckStack
+ Push FP[-5]
+ InstanceCall1 1, CP#1
+ PopLocal r2
+L2:
+ CheckStack
+ Push r2
+ InstanceCall1 1, CP#2
+ PushConstant CP#3
+ IfNeStrictTOS
+ Jump L1
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#4
+ PopLocal r0
+ Push r0
+ Push r2
+ InstanceCall1 1, CP#5
+ StoreFieldTOS CP#6
+ Allocate CP#14
+ StoreLocal r4
+ Push r4
+ PushConstant CP#12
+ StoreFieldTOS CP#15
+ Push r4
+ PushConstant CP#12
+ StoreFieldTOS CP#16
+ Push r4
+ PushConstant CP#7
+ StoreFieldTOS CP#17
+ Push r4
+ Push r0
+ StoreFieldTOS CP#8
+ PopLocal r3
+ Push r3
+ InstanceCall1 1, CP#18
+ Drop1
+ Push r0
+ LoadFieldTOS CP#6
+ PushConstant CP#19
+ IndirectStaticCall 1, CP#0
+ Drop1
+ Push r0
+ LoadFieldTOS CP#4
+ PopLocal r0
+ Jump L2
+L1:
+ PushConstant CP#12
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = ICData target-name 'get:iterator', arg-desc CP#0
+ [2] = ICData target-name 'moveNext', arg-desc CP#0
+ [3] = Bool true
+ [4] = ContextOffset parent
+ [5] = ICData target-name 'get:current', arg-desc CP#0
+ [6] = ContextOffset var [0]
+ [7] = ClosureFunction <anonymous closure> () → dart.core::Null;
+ [8] = FieldOffset dart.core::_Closure::_context
+ [9] = Int 1
+ [10] = ArgDesc num-args 2, num-type-args 0, names []
+ [11] = ICData target-name '+', arg-desc CP#10
+ [12] = Null
+ [13] = EndClosureFunctionScope
+ [14] = Class dart.core::_Closure
+ [15] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [16] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [17] = FieldOffset dart.core::_Closure::_function
+ [18] = ICData target-name 'call', arg-desc CP#0
+ [19] = StaticICData target 'dart.core::print', arg-desc CP#0
+}
+Closure CP#7 {
+ Entry 3
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#8
+ PopLocal r0
+ Push r0
+ Push r0
+ LoadFieldTOS CP#6
+ PushConstant CP#9
+ InstanceCall1 2, CP#11
+ StoreLocal r2
+ StoreFieldTOS CP#6
+ Push r2
+ Drop1
+ PushConstant CP#12
+ ReturnTOS
+
+}
+] method testForInLoop(core::List<core::int> list) → void {
+ for (core::int i in list) {
+ () → core::Null inc = () → core::Null {
+ i = i.{core::num::+}(1);
+ };
+ inc.call();
+ core::print(i);
+ }
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 4
+ CheckStack
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#1
+ StoreFieldTOS CP#2
+ Allocate CP#9
+ StoreLocal r3
+ Push r3
+ PushConstant CP#7
+ StoreFieldTOS CP#10
+ Push r3
+ PushConstant CP#7
+ StoreFieldTOS CP#11
+ Push r3
+ PushConstant CP#3
+ StoreFieldTOS CP#12
+ Push r3
+ Push r0
+ StoreFieldTOS CP#4
+ PopLocal r2
+ Push r2
+ PushConstant CP#13
+ InstanceCall1 2, CP#14
+ Drop1
+ Push r0
+ LoadFieldTOS CP#2
+ ReturnTOS
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ PushConstant CP#7
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ContextOffset parent
+ [1] = Int 5
+ [2] = ContextOffset var [0]
+ [3] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
+ [4] = FieldOffset dart.core::_Closure::_context
+ [5] = ArgDesc num-args 2, num-type-args 0, names []
+ [6] = ICData target-name '+', arg-desc CP#5
+ [7] = Null
+ [8] = EndClosureFunctionScope
+ [9] = Class dart.core::_Closure
+ [10] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [11] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [12] = FieldOffset dart.core::_Closure::_function
+ [13] = Int 3
+ [14] = ICData target-name 'call', arg-desc CP#5
+}
+Closure CP#3 {
+ Entry 3
+ CheckStack
+ Push FP[-6]
+ LoadFieldTOS CP#4
+ PopLocal r0
+ Push r0
+ Push r0
+ LoadFieldTOS CP#2
+ Push FP[-5]
+ InstanceCall1 2, CP#6
+ StoreLocal r2
+ StoreFieldTOS CP#2
+ Push r2
+ Drop1
+ PushConstant CP#7
+ ReturnTOS
+
+}
+]static method simpleClosure() → core::int {
+ core::int x = 5;
+ (core::int) → core::Null inc = (core::int y) → core::Null {
+ x = x.{core::num::+}(y);
+ };
+ inc.call(3);
+ return x;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ PushConstant CP#0
+ StoreLocal r0
+ Push r0
+ PushConstant CP#1
+ CreateArrayTOS
+ StoreLocal r0
+ Push r0
+ PushConstant CP#2
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#3
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#5
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#6
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#7
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#8
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#9
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#10
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#11
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#12
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#13
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#14
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#15
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#16
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#17
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#18
+ StoreIndexedTOS
+ PushConstant CP#20
+ IndirectStaticCall 2, CP#19
+ PushConstant CP#22
+ IndirectStaticCall 1, CP#21
+ Drop1
+ PushConstant CP#4
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs [dart.core::Type]
+ [1] = Int 8
+ [2] = Int 0
+ [3] = Type #lib::callWithArgs::T1
+ [4] = Null
+ [5] = Int 1
+ [6] = Type #lib::callWithArgs::T2
+ [7] = Int 2
+ [8] = Type #lib::callWithArgs::T3
+ [9] = Int 3
+ [10] = Type #lib::callWithArgs::T4
+ [11] = Int 4
+ [12] = Type #lib::callWithArgs::T5
+ [13] = Int 5
+ [14] = Type #lib::callWithArgs::T6
+ [15] = Int 6
+ [16] = Type #lib::callWithArgs::T7
+ [17] = Int 7
+ [18] = Type #lib::callWithArgs::T8
+ [19] = ArgDesc num-args 1, num-type-args 1, names []
+ [20] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#19
+ [21] = ArgDesc num-args 1, num-type-args 0, names []
+ [22] = StaticICData target 'dart.core::print', arg-desc CP#21
+}
+]static method callWithArgs<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic, T3 extends core::Object = dynamic, T4 extends core::Object = dynamic, T5 extends core::Object = dynamic, T6 extends core::Object = dynamic, T7 extends core::Object = dynamic, T8 extends core::Object = dynamic>() → void {
+ core::print(<core::Type>[self::callWithArgs::T1, self::callWithArgs::T2, self::callWithArgs::T3, self::callWithArgs::T4, self::callWithArgs::T5, self::callWithArgs::T6, self::callWithArgs::T7, self::callWithArgs::T8]);
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#3
+ PushConstant CP#1
+ AllocateT
+ StoreLocal r0
+ Push r0
+ PushConstant CP#5
+ IndirectStaticCall 1, CP#4
+ Drop1
+ InstanceCall1 1, CP#7
+ Drop1
+ PushConstant CP#8
+ PushConstant CP#3
+ PushConstant CP#1
+ AllocateT
+ StoreLocal r0
+ Push r0
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#4
+ Drop1
+ InstanceCall1 1, CP#10
+ Drop1
+ PushConstant CP#8
+ PushConstant CP#12
+ PushConstant CP#1
+ AllocateT
+ StoreLocal r0
+ Push r0
+ PushConstant CP#13
+ IndirectStaticCall 1, CP#4
+ Drop1
+ InstanceCall1 1, CP#14
+ Drop1
+ PushConstant CP#15
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs [#lib::C3, #lib::C4]
+ [1] = Class #lib::A
+ [2] = TypeArgs [#lib::C1, #lib::C2]
+ [3] = TypeArgumentsForInstanceAllocation #lib::A type-args CP#2
+ [4] = ArgDesc num-args 1, num-type-args 0, names []
+ [5] = StaticICData target '#lib::A::', arg-desc CP#4
+ [6] = ArgDesc num-args 1, num-type-args 2, names []
+ [7] = ICData target-name 'foo', arg-desc CP#6
+ [8] = TypeArgs [dart.core::List<#lib::C3>, dart.core::List<#lib::C4>]
+ [9] = StaticICData target '#lib::A::', arg-desc CP#4
+ [10] = ICData target-name 'foo', arg-desc CP#6
+ [11] = TypeArgs [dart.core::List<#lib::C1>, dart.core::List<#lib::C2>]
+ [12] = TypeArgumentsForInstanceAllocation #lib::A type-args CP#11
+ [13] = StaticICData target '#lib::A::', arg-desc CP#4
+ [14] = ICData target-name 'foo', arg-desc CP#6
+ [15] = Null
+}
+]static method callA() → void {
+ new self::A::•<self::C1, self::C2>().{self::A::foo}<self::C3, self::C4>();
+ new self::A::•<self::C1, self::C2>().{self::A::foo}<core::List<self::C3>, core::List<self::C4>>();
+ new self::A::•<core::List<self::C1>, core::List<self::C2>>().{self::A::foo}<core::List<self::C3>, core::List<self::C4>>();
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index ec7540c..239c9ac 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -211,7 +211,7 @@
return new self::C::•("hello");
[@vm.bytecode=
Bytecode {
- Entry 2
+ Entry 1
CheckStack
PushConstant CP#2
PushConstant CP#0
@@ -226,8 +226,8 @@
PushConstant CP#8
PushConstant CP#6
AllocateT
- StoreLocal r1
- Push r1
+ StoreLocal r0
+ Push r0
PushConstant CP#10
IndirectStaticCall 1, CP#9
Drop1
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index df1fe96..07727bf 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -420,7 +420,7 @@
}
[@vm.bytecode=
Bytecode {
- Entry 2
+ Entry 1
CheckStack
PushConstant CP#0
StoreLocal r0
@@ -446,21 +446,21 @@
IndirectStaticCall 1, CP#7
Drop1
PushConstant CP#9
- StoreLocal r1
- Push r1
+ StoreLocal r0
+ Push r0
PushConstant CP#1
CreateArrayTOS
- StoreLocal r1
- Push r1
+ StoreLocal r0
+ Push r0
PushConstant CP#2
PushConstant CP#10
StoreIndexedTOS
- Push r1
+ Push r0
PushConstant CP#3
Push FP[-5]
InstanceCall1 1, CP#11
StoreIndexedTOS
- Push r1
+ Push r0
PushConstant CP#4
PushConstant CP#12
StoreIndexedTOS
@@ -496,7 +496,7 @@
}
[@vm.bytecode=
Bytecode {
- Entry 4
+ Entry 1
CheckStack
PushConstant CP#0
PushConstant CP#1
@@ -528,21 +528,21 @@
PushConstant CP#1
PushConstant CP#2
CreateArrayTOS
- StoreLocal r1
- Push r1
+ StoreLocal r0
+ Push r0
PushConstant CP#3
PushConstant CP#12
StoreIndexedTOS
- Push r1
+ Push r0
PushConstant CP#4
Push FP[-7]
StoreIndexedTOS
- Push r1
+ Push r0
PushConstant CP#5
Push FP[-6]
InstanceCall1 1, CP#13
StoreIndexedTOS
- Push r1
+ Push r0
PushConstant CP#6
PushConstant CP#6
StoreIndexedTOS
@@ -566,12 +566,12 @@
PushConstant CP#1
PushConstant CP#5
CreateArrayTOS
- StoreLocal r3
- Push r3
+ StoreLocal r0
+ Push r0
PushConstant CP#3
Push FP[-5]
StoreIndexedTOS
- Push r3
+ Push r0
PushConstant CP#4
PushConstant CP#2
StoreIndexedTOS
diff --git a/pkg/vm/testcases/bytecode/loops.dart b/pkg/vm/testcases/bytecode/loops.dart
index a2d2d10..4d9dd1b 100644
--- a/pkg/vm/testcases/bytecode/loops.dart
+++ b/pkg/vm/testcases/bytecode/loops.dart
@@ -59,4 +59,13 @@
return sum;
}
+int test_for_in_with_outer_var(List<int> list) {
+ int sum = 0;
+ int e = 42;
+ for (e in list) {
+ sum = sum + e;
+ }
+ return sum;
+}
+
main() {}
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index a23aa00..635bc5b 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -354,7 +354,7 @@
[2] = ICData target-name 'get:iterator', arg-desc CP#1
[3] = ICData target-name 'moveNext', arg-desc CP#1
[4] = Bool true
- [5] = ICData target-name 'current', arg-desc CP#1
+ [5] = ICData target-name 'get:current', arg-desc CP#1
[6] = ArgDesc num-args 2, num-type-args 0, names []
[7] = ICData target-name '+', arg-desc CP#6
[8] = Null
@@ -368,6 +368,63 @@
}
[@vm.bytecode=
Bytecode {
+ Entry 4
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ PushConstant CP#1
+ PopLocal r1
+ Push FP[-5]
+ InstanceCall1 1, CP#3
+ PopLocal r2
+L2:
+ CheckStack
+ Push r2
+ InstanceCall1 1, CP#4
+ PushConstant CP#5
+ IfNeStrictTOS
+ Jump L1
+ Push r2
+ InstanceCall1 1, CP#6
+ PopLocal r3
+ Push r3
+ StoreLocal r1
+ Drop1
+ Push r0
+ Push r1
+ InstanceCall1 2, CP#8
+ StoreLocal r0
+ Drop1
+ Jump L2
+L1:
+ Push r0
+ ReturnTOS
+ PushConstant CP#9
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = Int 42
+ [2] = ArgDesc num-args 1, num-type-args 0, names []
+ [3] = ICData target-name 'get:iterator', arg-desc CP#2
+ [4] = ICData target-name 'moveNext', arg-desc CP#2
+ [5] = Bool true
+ [6] = ICData target-name 'get:current', arg-desc CP#2
+ [7] = ArgDesc num-args 2, num-type-args 0, names []
+ [8] = ICData target-name '+', arg-desc CP#7
+ [9] = Null
+}
+]static method test_for_in_with_outer_var(core::List<core::int> list) → core::int {
+ core::int sum = 0;
+ core::int e = 42;
+ for (final core::int #t3 in list) {
+ e = #t3;
+ sum = sum.{core::num::+}(e);
+ }
+ return sum;
+}
+[@vm.bytecode=
+Bytecode {
Entry 0
CheckStack
PushConstant CP#0
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index 36b3b1a..c85a618 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -7,7 +7,7 @@
EntryOptional 1, 2, 0
LoadConstant r1, CP#0
LoadConstant r2, CP#1
- Frame 3
+ Frame 1
CheckStack
PushConstant CP#2
PushConstant CP#3
@@ -29,12 +29,12 @@
PushConstant CP#2
PushConstant CP#3
CreateArrayTOS
- StoreLocal r4
- Push r4
+ StoreLocal r3
+ Push r3
PushConstant CP#4
PushConstant CP#10
StoreIndexedTOS
- Push r4
+ Push r3
PushConstant CP#6
Push r1
StoreIndexedTOS
@@ -46,12 +46,12 @@
PushConstant CP#2
PushConstant CP#3
CreateArrayTOS
- StoreLocal r5
- Push r5
+ StoreLocal r3
+ Push r3
PushConstant CP#4
PushConstant CP#13
StoreIndexedTOS
- Push r5
+ Push r3
PushConstant CP#6
Push r2
StoreIndexedTOS
@@ -95,7 +95,7 @@
LoadConstant r3, CP#4
LoadConstant r4, CP#5
LoadConstant r4, CP#6
- Frame 5
+ Frame 1
CheckStack
PushConstant CP#7
PushConstant CP#8
@@ -117,12 +117,12 @@
PushConstant CP#7
PushConstant CP#8
CreateArrayTOS
- StoreLocal r6
- Push r6
+ StoreLocal r5
+ Push r5
PushConstant CP#9
PushConstant CP#15
StoreIndexedTOS
- Push r6
+ Push r5
PushConstant CP#11
Push r1
StoreIndexedTOS
@@ -134,12 +134,12 @@
PushConstant CP#7
PushConstant CP#8
CreateArrayTOS
- StoreLocal r7
- Push r7
+ StoreLocal r5
+ Push r5
PushConstant CP#9
PushConstant CP#18
StoreIndexedTOS
- Push r7
+ Push r5
PushConstant CP#11
Push r2
StoreIndexedTOS
@@ -151,12 +151,12 @@
PushConstant CP#7
PushConstant CP#8
CreateArrayTOS
- StoreLocal r8
- Push r8
+ StoreLocal r5
+ Push r5
PushConstant CP#9
PushConstant CP#21
StoreIndexedTOS
- Push r8
+ Push r5
PushConstant CP#11
Push r3
StoreIndexedTOS
@@ -168,12 +168,12 @@
PushConstant CP#7
PushConstant CP#8
CreateArrayTOS
- StoreLocal r9
- Push r9
+ StoreLocal r5
+ Push r5
PushConstant CP#9
PushConstant CP#24
StoreIndexedTOS
- Push r9
+ Push r5
PushConstant CP#11
Push r4
StoreIndexedTOS
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart b/pkg/vm/testcases/bytecode/try_blocks.dart
new file mode 100644
index 0000000..d07c18f
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart
@@ -0,0 +1,153 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+testTryCatch1() {
+ try {
+ print('danger!');
+ } catch (e) {
+ print('caught $e');
+ }
+}
+
+testTryCatch2() {
+ try {
+ print('danger!');
+ } on TypeError {
+ print('caught type error');
+ } on AssertionError catch (e) {
+ print('caught assertion error $e');
+ } on Error catch (e, st) {
+ print('caught error $e $st');
+ } catch (e, st) {
+ print('caught something $e $st');
+ }
+}
+
+testTryCatch3() {
+ int x = 1;
+ try {
+ int y = 2;
+ void foo() {
+ try {
+ print('danger foo');
+ } catch (e) {
+ print(x);
+ y = 3;
+ }
+ }
+
+ foo();
+ print(y);
+ } catch (e, st) {
+ print('caught $e $st');
+
+ void bar() {
+ try {
+ print('danger bar');
+ } on Error catch (e) {
+ print('error $e, captured stack trace: $st');
+ }
+ }
+
+ return bar;
+ }
+}
+
+testRethrow(bool cond) {
+ try {
+ try {
+ print('try 1 > try 2');
+ } catch (e) {
+ try {
+ print('try 1 > catch 2 > try 3');
+ if (cond) {
+ rethrow;
+ }
+ } catch (e) {
+ print('try 1 > catch 2 > catch 3');
+ }
+ }
+ } catch (e, st) {
+ print('catch 1');
+ print(st);
+ }
+}
+
+testTryFinally1() {
+ for (int i = 0; i < 10; i++) {
+ try {
+ if (i > 5) {
+ break;
+ }
+ } finally {
+ print(i);
+ }
+ }
+}
+
+testTryFinally2(int x) {
+ switch (x) {
+ case 1:
+ try {
+ print('before try 1');
+ int y = 3;
+ try {
+ print('try');
+ void foo() {
+ print(x);
+ print(y);
+ }
+
+ foo();
+ continue L;
+ } finally {
+ print('finally 1');
+ }
+ print('after try 1');
+ } finally {
+ print('finally 2');
+ }
+ break;
+ L:
+ case 2:
+ print('case 2');
+ break;
+ }
+}
+
+testTryFinally3() {
+ int x = 11;
+ var y;
+ try {
+ y = () {
+ print(x);
+ try {
+ print('try 1');
+ return 42;
+ } finally {
+ try {
+ print('try 2');
+ return 43;
+ } finally {
+ print(x);
+ }
+ }
+ };
+ } finally {
+ print(x);
+ y();
+ }
+}
+
+testTryCatchFinally() {
+ try {
+ print('try');
+ } catch (e) {
+ print('catch');
+ } finally {
+ print('finally');
+ }
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
new file mode 100644
index 0000000..0dbaad8
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -0,0 +1,1379 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+[@vm.bytecode=
+Bytecode {
+ Entry 4
+ CheckStack
+Try #0 start:
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+Try #0 end:
+Try #0 handler:
+ MoveSpecial r0, exception
+ MoveSpecial r1, stackTrace
+ Push r0
+ PopLocal r2
+ PushConstant CP#4
+ PushConstant CP#5
+ CreateArrayTOS
+ StoreLocal r3
+ Push r3
+ PushConstant CP#6
+ PushConstant CP#7
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#8
+ Push r2
+ StoreIndexedTOS
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#1
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+L1:
+ PushConstant CP#4
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 2, end 7, handler 7, types [CP#3]
+}
+ConstantPool {
+ [0] = String 'danger!'
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = Type dynamic
+ [4] = Null
+ [5] = Int 2
+ [6] = Int 0
+ [7] = String 'caught '
+ [8] = Int 1
+ [9] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+ [10] = StaticICData target 'dart.core::print', arg-desc CP#1
+}
+]static method testTryCatch1() → dynamic {
+ try {
+ core::print("danger!");
+ }
+ on dynamic catch(final dynamic e) {
+ core::print("caught ${e}");
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 5
+ CheckStack
+Try #0 start:
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+Try #0 end:
+Try #0 handler:
+ MoveSpecial r0, exception
+ MoveSpecial r1, stackTrace
+ Push r0
+ PushConstant CP#4
+ PushConstant CP#4
+ PushConstant CP#3
+ InstanceCall1 4, CP#6
+ PushConstant CP#7
+ IfNeStrictTOS
+ Jump L2
+ PushConstant CP#8
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+L2:
+ Push r0
+ PushConstant CP#4
+ PushConstant CP#4
+ PushConstant CP#10
+ InstanceCall1 4, CP#11
+ PushConstant CP#7
+ IfNeStrictTOS
+ Jump L3
+ Push r0
+ PopLocal r2
+ PushConstant CP#4
+ PushConstant CP#12
+ CreateArrayTOS
+ StoreLocal r3
+ Push r3
+ PushConstant CP#13
+ PushConstant CP#14
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#15
+ Push r2
+ StoreIndexedTOS
+ PushConstant CP#16
+ IndirectStaticCall 1, CP#1
+ PushConstant CP#17
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+L3:
+ Push r0
+ PushConstant CP#4
+ PushConstant CP#4
+ PushConstant CP#18
+ InstanceCall1 4, CP#19
+ PushConstant CP#7
+ IfNeStrictTOS
+ Jump L4
+ Push r0
+ PopLocal r2
+ Push r1
+ PopLocal r3
+ PushConstant CP#4
+ PushConstant CP#20
+ CreateArrayTOS
+ StoreLocal r4
+ Push r4
+ PushConstant CP#13
+ PushConstant CP#21
+ StoreIndexedTOS
+ Push r4
+ PushConstant CP#15
+ Push r2
+ StoreIndexedTOS
+ Push r4
+ PushConstant CP#12
+ PushConstant CP#22
+ StoreIndexedTOS
+ Push r4
+ PushConstant CP#23
+ Push r3
+ StoreIndexedTOS
+ PushConstant CP#24
+ IndirectStaticCall 1, CP#1
+ PushConstant CP#25
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+L4:
+ Push r0
+ PopLocal r2
+ Push r1
+ PopLocal r3
+ PushConstant CP#4
+ PushConstant CP#20
+ CreateArrayTOS
+ StoreLocal r4
+ Push r4
+ PushConstant CP#13
+ PushConstant CP#27
+ StoreIndexedTOS
+ Push r4
+ PushConstant CP#15
+ Push r2
+ StoreIndexedTOS
+ Push r4
+ PushConstant CP#12
+ PushConstant CP#22
+ StoreIndexedTOS
+ Push r4
+ PushConstant CP#23
+ Push r3
+ StoreIndexedTOS
+ PushConstant CP#28
+ IndirectStaticCall 1, CP#1
+ PushConstant CP#29
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+L1:
+ PushConstant CP#4
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 2, end 7, handler 7, needs-stack-trace, types [CP#3, CP#10, CP#18, CP#26]
+}
+ConstantPool {
+ [0] = String 'danger!'
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = Type dart.core::TypeError
+ [4] = Null
+ [5] = ArgDesc num-args 4, num-type-args 0, names []
+ [6] = ICData target-name '_instanceOf', arg-desc CP#5
+ [7] = Bool true
+ [8] = String 'caught type error'
+ [9] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [10] = Type dart.core::AssertionError
+ [11] = ICData target-name '_instanceOf', arg-desc CP#5
+ [12] = Int 2
+ [13] = Int 0
+ [14] = String 'caught assertion error '
+ [15] = Int 1
+ [16] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+ [17] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [18] = Type dart.core::Error
+ [19] = ICData target-name '_instanceOf', arg-desc CP#5
+ [20] = Int 4
+ [21] = String 'caught error '
+ [22] = String ' '
+ [23] = Int 3
+ [24] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+ [25] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [26] = Type dynamic
+ [27] = String 'caught something '
+ [28] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+ [29] = StaticICData target 'dart.core::print', arg-desc CP#1
+}
+]static method testTryCatch2() → dynamic {
+ try {
+ core::print("danger!");
+ }
+ on core::TypeError catch(no-exception-var) {
+ core::print("caught type error");
+ }
+ on core::AssertionError catch(final core::AssertionError e) {
+ core::print("caught assertion error ${e}");
+ }
+ on core::Error catch(final core::Error e, final core::StackTrace st) {
+ core::print("caught error ${e} ${st}");
+ }
+ on dynamic catch(final dynamic e, final core::StackTrace st) {
+ core::print("caught something ${e} ${st}");
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 7
+ CheckStack
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#1
+ StoreFieldTOS CP#2
+ Push r0
+ PopLocal r2
+Try #0 start:
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#3
+ StoreFieldTOS CP#2
+ Allocate CP#14
+ StoreLocal r5
+ Push r5
+ PushConstant CP#12
+ StoreFieldTOS CP#15
+ Push r5
+ PushConstant CP#12
+ StoreFieldTOS CP#16
+ Push r5
+ PushConstant CP#4
+ StoreFieldTOS CP#17
+ Push r5
+ Push r0
+ StoreFieldTOS CP#5
+ PopLocal r4
+ Push r4
+ InstanceCall1 1, CP#18
+ Drop1
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#19
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ Jump L1
+Try #0 end:
+Try #0 handler:
+ Push r2
+ PopLocal r0
+ MoveSpecial r2, exception
+ MoveSpecial r3, stackTrace
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r2
+ PopLocal r4
+ Push r0
+ Push r3
+ StoreFieldTOS CP#2
+ PushConstant CP#12
+ PushConstant CP#20
+ CreateArrayTOS
+ StoreLocal r5
+ Push r5
+ PushConstant CP#21
+ PushConstant CP#22
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#1
+ Push r4
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#3
+ PushConstant CP#23
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#11
+ Push r0
+ LoadFieldTOS CP#2
+ StoreIndexedTOS
+ PushConstant CP#24
+ IndirectStaticCall 1, CP#7
+ PushConstant CP#25
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Allocate CP#14
+ StoreLocal r5
+ Push r5
+ PushConstant CP#12
+ StoreFieldTOS CP#15
+ Push r5
+ PushConstant CP#12
+ StoreFieldTOS CP#16
+ Push r5
+ PushConstant CP#26
+ StoreFieldTOS CP#17
+ Push r5
+ Push r0
+ StoreFieldTOS CP#5
+ PopLocal r6
+ Push r6
+ ReturnTOS
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ Jump L1
+L1:
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ PushConstant CP#12
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 13, end 49, handler 49, needs-stack-trace, types [CP#9]
+}
+ConstantPool {
+ [0] = ContextOffset parent
+ [1] = Int 1
+ [2] = ContextOffset var [0]
+ [3] = Int 2
+ [4] = ClosureFunction foo () → void;
+ [5] = FieldOffset dart.core::_Closure::_context
+ [6] = String 'danger foo'
+ [7] = ArgDesc num-args 1, num-type-args 0, names []
+ [8] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [9] = Type dynamic
+ [10] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [11] = Int 3
+ [12] = Null
+ [13] = EndClosureFunctionScope
+ [14] = Class dart.core::_Closure
+ [15] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [16] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [17] = FieldOffset dart.core::_Closure::_function
+ [18] = ICData target-name 'call', arg-desc CP#7
+ [19] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [20] = Int 4
+ [21] = Int 0
+ [22] = String 'caught '
+ [23] = String ' '
+ [24] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
+ [25] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [26] = ClosureFunction bar () → void;
+ [27] = String 'danger bar'
+ [28] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [29] = Type dart.core::Error
+ [30] = ArgDesc num-args 4, num-type-args 0, names []
+ [31] = ICData target-name '_instanceOf', arg-desc CP#30
+ [32] = Bool true
+ [33] = String 'error '
+ [34] = String ', captured stack trace: '
+ [35] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
+ [36] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [37] = EndClosureFunctionScope
+}
+Closure CP#4 {
+ Entry 6
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#5
+ PopLocal r0
+ Push r0
+ PopLocal r2
+Try #0 start:
+ PushConstant CP#6
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Jump L1
+Try #0 end:
+Try #0 handler:
+ Push r2
+ PopLocal r0
+ MoveSpecial r2, exception
+ MoveSpecial r3, stackTrace
+ Push r2
+ PopLocal r4
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#2
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Push r0
+ PushConstant CP#11
+ StoreLocal r5
+ StoreFieldTOS CP#2
+ Push r5
+ Drop1
+ Jump L1
+L1:
+ PushConstant CP#12
+ ReturnTOS
+
+}
+
+Closure CP#26 {
+ Entry 6
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#5
+ PopLocal r0
+ Push r0
+ PopLocal r2
+Try #0 start:
+ PushConstant CP#27
+ PushConstant CP#28
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Jump L1
+Try #0 end:
+Try #0 handler:
+ Push r2
+ PopLocal r0
+ MoveSpecial r2, exception
+ MoveSpecial r3, stackTrace
+ Push r2
+ PushConstant CP#12
+ PushConstant CP#12
+ PushConstant CP#29
+ InstanceCall1 4, CP#31
+ PushConstant CP#32
+ IfNeStrictTOS
+ Jump L2
+ Push r2
+ PopLocal r4
+ PushConstant CP#12
+ PushConstant CP#20
+ CreateArrayTOS
+ StoreLocal r5
+ Push r5
+ PushConstant CP#21
+ PushConstant CP#33
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#1
+ Push r4
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#3
+ PushConstant CP#34
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#11
+ Push r0
+ LoadFieldTOS CP#2
+ StoreIndexedTOS
+ PushConstant CP#35
+ IndirectStaticCall 1, CP#7
+ PushConstant CP#36
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Jump L1
+L2:
+ Push r2
+ Push r3
+ Throw 1
+L1:
+ PushConstant CP#12
+ ReturnTOS
+
+}
+]static method testTryCatch3() → dynamic {
+ core::int x = 1;
+ try {
+ core::int y = 2;
+ function foo() → void {
+ try {
+ core::print("danger foo");
+ }
+ on dynamic catch(final dynamic e) {
+ core::print(x);
+ y = 3;
+ }
+ }
+ foo.call();
+ core::print(y);
+ }
+ on dynamic catch(final dynamic e, final core::StackTrace st) {
+ core::print("caught ${e} ${st}");
+ function bar() → void {
+ try {
+ core::print("danger bar");
+ }
+ on core::Error catch(final core::Error e) {
+ core::print("error ${e}, captured stack trace: ${st}");
+ }
+ }
+ return bar;
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 8
+ CheckStack
+Try #0 start:
+Try #1 start:
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+Try #1 end:
+Try #1 handler:
+ MoveSpecial r2, exception
+ MoveSpecial r3, stackTrace
+ Push r2
+ PopLocal r4
+Try #2 start:
+ PushConstant CP#4
+ PushConstant CP#5
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Push FP[-5]
+ PushConstant CP#6
+ IfNeStrictTOS
+ Jump L2
+ Push r2
+ Push r3
+ Throw 1
+ Drop1
+L2:
+ Jump L3
+Try #2 end:
+Try #2 handler:
+ MoveSpecial r5, exception
+ MoveSpecial r6, stackTrace
+ Push r5
+ PopLocal r7
+ PushConstant CP#7
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L3
+L3:
+ Jump L1
+L1:
+ Jump L4
+Try #0 end:
+Try #0 handler:
+ MoveSpecial r0, exception
+ MoveSpecial r1, stackTrace
+ Push r0
+ PopLocal r2
+ Push r1
+ PopLocal r3
+ PushConstant CP#9
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Push r3
+ PushConstant CP#11
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L4
+L4:
+ PushConstant CP#12
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 2, end 35, handler 35, needs-stack-trace, types [CP#3]
+ try-index 1, outer 0, start 2, end 7, handler 7, needs-stack-trace, types [CP#3]
+ try-index 2, outer 0, start 11, end 24, handler 24, types [CP#3]
+}
+ConstantPool {
+ [0] = String 'try 1 > try 2'
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = Type dynamic
+ [4] = String 'try 1 > catch 2 > try 3'
+ [5] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [6] = Bool true
+ [7] = String 'try 1 > catch 2 > catch 3'
+ [8] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [9] = String 'catch 1'
+ [10] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [11] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [12] = Null
+}
+]static method testRethrow(core::bool cond) → dynamic {
+ try {
+ try {
+ core::print("try 1 > try 2");
+ }
+ on dynamic catch(final dynamic e) {
+ try {
+ core::print("try 1 > catch 2 > try 3");
+ if(cond) {
+ rethrow;
+ }
+ }
+ on dynamic catch(final dynamic e) {
+ core::print("try 1 > catch 2 > catch 3");
+ }
+ }
+ }
+ on dynamic catch(final dynamic e, final core::StackTrace st) {
+ core::print("catch 1");
+ core::print(st);
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 3
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+L5:
+ CheckStack
+ Push r0
+ PushConstant CP#1
+ InstanceCall1 2, CP#3
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L1
+Try #0 start:
+ Push r0
+ PushConstant CP#5
+ InstanceCall1 2, CP#6
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L2
+ Jump L3
+L2:
+ Jump L4
+Try #0 end:
+Try #0 handler:
+ MoveSpecial r1, exception
+ MoveSpecial r2, stackTrace
+ Push r0
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#8
+ Drop1
+ Push r1
+ Push r2
+ Throw 1
+L3:
+ Push r0
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#8
+ Drop1
+ Jump L1
+L4:
+ Push r0
+ PushConstant CP#11
+ IndirectStaticCall 1, CP#8
+ Drop1
+ Push r0
+ PushConstant CP#12
+ InstanceCall1 2, CP#13
+ StoreLocal r0
+ Drop1
+ Jump L5
+L1:
+ PushConstant CP#14
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 11, end 19, handler 19, needs-stack-trace, types [CP#7]
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = Int 10
+ [2] = ArgDesc num-args 2, num-type-args 0, names []
+ [3] = ICData target-name '<', arg-desc CP#2
+ [4] = Bool true
+ [5] = Int 5
+ [6] = ICData target-name '>', arg-desc CP#2
+ [7] = Type dynamic
+ [8] = ArgDesc num-args 1, num-type-args 0, names []
+ [9] = StaticICData target 'dart.core::print', arg-desc CP#8
+ [10] = StaticICData target 'dart.core::print', arg-desc CP#8
+ [11] = StaticICData target 'dart.core::print', arg-desc CP#8
+ [12] = Int 1
+ [13] = ICData target-name '+', arg-desc CP#2
+ [14] = Null
+}
+]static method testTryFinally1() → dynamic {
+ #L1:
+ for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+ try {
+ if(i.{core::num::>}(5)) {
+ break #L1;
+ }
+ }
+ finally {
+ core::print(i);
+ }
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 9
+ CheckStack
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ Push FP[-5]
+ StoreFieldTOS CP#1
+ Push r0
+ LoadFieldTOS CP#1
+ PopLocal r2
+ Push r2
+ PushConstant CP#3
+ InstanceCall2 2, CP#4
+ PushConstant CP#5
+ IfEqStrictTOS
+ Jump L1
+ Push r2
+ PushConstant CP#6
+ InstanceCall2 2, CP#7
+ PushConstant CP#5
+ IfEqStrictTOS
+ Jump L2
+ Jump L3
+L1:
+ Push r0
+ PopLocal r3
+Try #0 start:
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ PushConstant CP#8
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Push r0
+ PushConstant CP#11
+ StoreFieldTOS CP#1
+ Push r0
+ PopLocal r5
+Try #1 start:
+ PushConstant CP#12
+ PushConstant CP#13
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Allocate CP#20
+ StoreLocal r8
+ Push r8
+ PushConstant CP#18
+ StoreFieldTOS CP#21
+ Push r8
+ PushConstant CP#18
+ StoreFieldTOS CP#22
+ Push r8
+ PushConstant CP#14
+ StoreFieldTOS CP#23
+ Push r8
+ Push r0
+ StoreFieldTOS CP#15
+ PopLocal r7
+ Push r7
+ InstanceCall1 1, CP#24
+ Drop1
+ Jump L4
+ Jump L5
+Try #1 end:
+Try #1 handler:
+ Push r5
+ PopLocal r0
+ MoveSpecial r5, exception
+ MoveSpecial r6, stackTrace
+ PushConstant CP#26
+ PushConstant CP#27
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Push r5
+ Push r6
+ Throw 1
+L4:
+ Push r5
+ PopLocal r0
+ PushConstant CP#26
+ PushConstant CP#28
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Jump L6
+L5:
+ Push r5
+ PopLocal r0
+ PushConstant CP#26
+ PushConstant CP#29
+ IndirectStaticCall 1, CP#9
+ Drop1
+ PushConstant CP#30
+ PushConstant CP#31
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ Jump L7
+Try #0 end:
+Try #0 handler:
+ Push r3
+ PopLocal r0
+ MoveSpecial r3, exception
+ MoveSpecial r4, stackTrace
+ PushConstant CP#32
+ PushConstant CP#33
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Push r3
+ Push r4
+ Throw 1
+L6:
+ Push r3
+ PopLocal r0
+ PushConstant CP#32
+ PushConstant CP#34
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Jump L2
+L7:
+ Push r3
+ PopLocal r0
+ PushConstant CP#32
+ PushConstant CP#35
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Jump L3
+L2:
+ PushConstant CP#36
+ PushConstant CP#37
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Jump L3
+L3:
+ PushConstant CP#18
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 29, end 100, handler 100, needs-stack-trace, types [CP#25]
+ try-index 1, outer 0, start 44, end 68, handler 68, needs-stack-trace, types [CP#25]
+}
+ConstantPool {
+ [0] = ContextOffset parent
+ [1] = ContextOffset var [0]
+ [2] = ArgDesc num-args 2, num-type-args 0, names []
+ [3] = Int 1
+ [4] = ICData target-name '==', arg-desc CP#2
+ [5] = Bool true
+ [6] = Int 2
+ [7] = ICData target-name '==', arg-desc CP#2
+ [8] = String 'before try 1'
+ [9] = ArgDesc num-args 1, num-type-args 0, names []
+ [10] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [11] = Int 3
+ [12] = String 'try'
+ [13] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [14] = ClosureFunction foo () → void;
+ [15] = FieldOffset dart.core::_Closure::_context
+ [16] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [17] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [18] = Null
+ [19] = EndClosureFunctionScope
+ [20] = Class dart.core::_Closure
+ [21] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [22] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [23] = FieldOffset dart.core::_Closure::_function
+ [24] = ICData target-name 'call', arg-desc CP#9
+ [25] = Type dynamic
+ [26] = String 'finally 1'
+ [27] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [28] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [29] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [30] = String 'after try 1'
+ [31] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [32] = String 'finally 2'
+ [33] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [34] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [35] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [36] = String 'case 2'
+ [37] = StaticICData target 'dart.core::print', arg-desc CP#9
+}
+Closure CP#14 {
+ Entry 2
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#15
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#0
+ LoadFieldTOS CP#1
+ PushConstant CP#16
+ IndirectStaticCall 1, CP#9
+ Drop1
+ Push r0
+ LoadFieldTOS CP#1
+ PushConstant CP#17
+ IndirectStaticCall 1, CP#9
+ Drop1
+ PushConstant CP#18
+ ReturnTOS
+
+}
+]static method testTryFinally2(core::int x) → dynamic {
+ #L2:
+ switch(x) {
+ #L3:
+ case 1:
+ {
+ try {
+ core::print("before try 1");
+ core::int y = 3;
+ try {
+ core::print("try");
+ function foo() → void {
+ core::print(x);
+ core::print(y);
+ }
+ foo.call();
+ continue #L4;
+ }
+ finally {
+ core::print("finally 1");
+ }
+ core::print("after try 1");
+ }
+ finally {
+ core::print("finally 2");
+ }
+ break #L2;
+ }
+ #L4:
+ case 2:
+ {
+ core::print("case 2");
+ break #L2;
+ }
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 6
+ CheckStack
+ AllocateContext 1
+ StoreLocal r1
+ Push r1
+ Push r0
+ StoreFieldTOS CP#0
+ PopLocal r0
+ Push r0
+ PushConstant CP#1
+ StoreFieldTOS CP#2
+ PushConstant CP#3
+ PopLocal r2
+ Push r0
+ PopLocal r3
+Try #0 start:
+ Allocate CP#27
+ StoreLocal r5
+ Push r5
+ PushConstant CP#3
+ StoreFieldTOS CP#28
+ Push r5
+ PushConstant CP#3
+ StoreFieldTOS CP#29
+ Push r5
+ PushConstant CP#4
+ StoreFieldTOS CP#30
+ Push r5
+ Push r0
+ StoreFieldTOS CP#5
+ StoreLocal r2
+ Drop1
+ Jump L1
+Try #0 end:
+Try #0 handler:
+ Push r3
+ PopLocal r0
+ MoveSpecial r3, exception
+ MoveSpecial r4, stackTrace
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#31
+ IndirectStaticCall 1, CP#6
+ Drop1
+ Push r2
+ InstanceCall1 1, CP#32
+ Drop1
+ Push r3
+ Push r4
+ Throw 1
+L1:
+ Push r3
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#33
+ IndirectStaticCall 1, CP#6
+ Drop1
+ Push r2
+ InstanceCall1 1, CP#34
+ Drop1
+ Push r0
+ LoadFieldTOS CP#0
+ PopLocal r0
+ PushConstant CP#3
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 15, end 32, handler 32, needs-stack-trace, types [CP#11]
+}
+ConstantPool {
+ [0] = ContextOffset parent
+ [1] = Int 11
+ [2] = ContextOffset var [0]
+ [3] = Null
+ [4] = ClosureFunction <anonymous closure> () → dart.core::int;
+ [5] = FieldOffset dart.core::_Closure::_context
+ [6] = ArgDesc num-args 1, num-type-args 0, names []
+ [7] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [8] = String 'try 1'
+ [9] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [10] = Int 42
+ [11] = Type dynamic
+ [12] = String 'try 2'
+ [13] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [14] = Int 43
+ [15] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [16] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [17] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [18] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [19] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [20] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [21] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [22] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [23] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [24] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [25] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [26] = EndClosureFunctionScope
+ [27] = Class dart.core::_Closure
+ [28] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+ [29] = FieldOffset dart.core::_Closure::_function_type_arguments
+ [30] = FieldOffset dart.core::_Closure::_function
+ [31] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [32] = ICData target-name 'call', arg-desc CP#6
+ [33] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [34] = ICData target-name 'call', arg-desc CP#6
+}
+Closure CP#4 {
+ Entry 6
+ CheckStack
+ Push FP[-5]
+ LoadFieldTOS CP#5
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#6
+ Drop1
+ Push r0
+ PopLocal r2
+Try #0 start:
+ PushConstant CP#8
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#6
+ Drop1
+ PushConstant CP#10
+ Jump L1
+ Jump L2
+Try #0 end:
+Try #0 handler:
+ Push r2
+ PopLocal r0
+ MoveSpecial r2, exception
+ MoveSpecial r3, stackTrace
+ Push r0
+ PopLocal r4
+Try #1 start:
+ PushConstant CP#12
+ PushConstant CP#13
+ IndirectStaticCall 1, CP#6
+ Drop1
+ PushConstant CP#14
+ Jump L3
+ Jump L4
+Try #1 end:
+Try #1 handler:
+ Push r4
+ PopLocal r0
+ MoveSpecial r4, exception
+ MoveSpecial r5, stackTrace
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#15
+ IndirectStaticCall 1, CP#6
+ Drop1
+ Push r4
+ Push r5
+ Throw 1
+L3:
+ Push r4
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#16
+ IndirectStaticCall 1, CP#6
+ Drop1
+ ReturnTOS
+L4:
+ Push r4
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#17
+ IndirectStaticCall 1, CP#6
+ Drop1
+ Push r2
+ Push r3
+ Throw 1
+L1:
+ Push r2
+ PopLocal r0
+ Push r0
+ PopLocal r4
+Try #2 start:
+ PushConstant CP#12
+ PushConstant CP#18
+ IndirectStaticCall 1, CP#6
+ Drop1
+ PushConstant CP#14
+ Jump L5
+ Jump L6
+Try #2 end:
+Try #2 handler:
+ Push r4
+ PopLocal r0
+ MoveSpecial r4, exception
+ MoveSpecial r5, stackTrace
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#19
+ IndirectStaticCall 1, CP#6
+ Drop1
+ Push r4
+ Push r5
+ Throw 1
+L5:
+ Push r4
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#20
+ IndirectStaticCall 1, CP#6
+ Drop1
+ ReturnTOS
+L6:
+ Push r4
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#21
+ IndirectStaticCall 1, CP#6
+ Drop1
+ ReturnTOS
+L2:
+ Push r2
+ PopLocal r0
+ Push r0
+ PopLocal r4
+Try #3 start:
+ PushConstant CP#12
+ PushConstant CP#22
+ IndirectStaticCall 1, CP#6
+ Drop1
+ PushConstant CP#14
+ Jump L7
+ Jump L8
+Try #3 end:
+Try #3 handler:
+ Push r4
+ PopLocal r0
+ MoveSpecial r4, exception
+ MoveSpecial r5, stackTrace
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#23
+ IndirectStaticCall 1, CP#6
+ Drop1
+ Push r4
+ Push r5
+ Throw 1
+L7:
+ Push r4
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#24
+ IndirectStaticCall 1, CP#6
+ Drop1
+ ReturnTOS
+L8:
+ Push r4
+ PopLocal r0
+ Push r0
+ LoadFieldTOS CP#2
+ PushConstant CP#25
+ IndirectStaticCall 1, CP#6
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+
+}
+]static method testTryFinally3() → dynamic {
+ core::int x = 11;
+ dynamic y;
+ try {
+ y = () → core::int {
+ core::print(x);
+ try {
+ core::print("try 1");
+ return 42;
+ }
+ finally {
+ try {
+ core::print("try 2");
+ return 43;
+ }
+ finally {
+ core::print(x);
+ }
+ }
+ };
+ }
+ finally {
+ core::print(x);
+ y.call();
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 5
+ CheckStack
+Try #0 start:
+Try #1 start:
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+Try #1 end:
+Try #1 handler:
+ MoveSpecial r2, exception
+ MoveSpecial r3, stackTrace
+ Push r2
+ PopLocal r4
+ PushConstant CP#4
+ PushConstant CP#5
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Jump L1
+L1:
+ Jump L2
+Try #0 end:
+Try #0 handler:
+ MoveSpecial r0, exception
+ MoveSpecial r1, stackTrace
+ PushConstant CP#6
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Push r0
+ Push r1
+ Throw 1
+L2:
+ PushConstant CP#6
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#9
+ ReturnTOS
+}
+ExceptionsTable {
+ try-index 0, outer -1, start 2, end 17, handler 17, needs-stack-trace, types [CP#3]
+ try-index 1, outer 0, start 2, end 7, handler 7, types [CP#3]
+}
+ConstantPool {
+ [0] = String 'try'
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = Type dynamic
+ [4] = String 'catch'
+ [5] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [6] = String 'finally'
+ [7] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [8] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [9] = Null
+}
+]static method testTryCatchFinally() → dynamic {
+ try
+ try {
+ core::print("try");
+ }
+ on dynamic catch(final dynamic e) {
+ core::print("catch");
+ }
+ finally {
+ core::print("finally");
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart
new file mode 100644
index 0000000..b5b68eb
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class ClassAnnotation {
+ const ClassAnnotation();
+}
+
+const classAnnotation = const ClassAnnotation();
+
+class ClassAnnotation2 {
+ const ClassAnnotation2();
+}
+
+class MethodAnnotation {
+ final int x;
+ const MethodAnnotation(this.x);
+}
+
+class TypedefAnnotation {
+ final List<int> list;
+ const TypedefAnnotation(this.list);
+}
+
+class VarAnnotation {
+ const VarAnnotation();
+}
+
+class ParametrizedAnnotation<T> {
+ final T foo;
+ const ParametrizedAnnotation(this.foo);
+}
+
+@classAnnotation
+class A {
+ static void staticMethod() {}
+}
+
+@ClassAnnotation2()
+class B {
+ @MethodAnnotation(42)
+ void instanceMethod() {}
+}
+
+@TypedefAnnotation([1, 2, 3])
+typedef void SomeType<T>(List<T> arg);
+
+int foo(SomeType<int> a) {
+ @VarAnnotation()
+ int x = 2;
+ return x + 2;
+}
+
+@ParametrizedAnnotation(null)
+main(List<String> args) {
+ A.staticMethod();
+ new B().instanceMethod();
+ foo(null);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
new file mode 100644
index 0000000..34dfa36
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -0,0 +1,47 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+@self::TypedefAnnotation::•(const <core::int>[1, 2, 3])
+typedef SomeType<T extends core::Object = dynamic> = (core::List<T>) → void;
+abstract class ClassAnnotation2 extends core::Object {
+[@vm.unreachable.metadata=] const constructor •() → void
+ throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class MethodAnnotation extends core::Object {
+[@vm.unreachable.metadata=] const constructor •(core::int x) → void
+ throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class TypedefAnnotation extends core::Object {
+[@vm.unreachable.metadata=] const constructor •(core::List<core::int> list) → void
+ throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class VarAnnotation extends core::Object {
+[@vm.unreachable.metadata=] const constructor •() → void
+ throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class ParametrizedAnnotation<T extends core::Object = dynamic> extends core::Object {
+[@vm.unreachable.metadata=] const constructor •(self::ParametrizedAnnotation::T foo) → void
+ throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class A extends core::Object {
+ static method staticMethod() → void {}
+}
+@self::ClassAnnotation2::•()
+class B extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ @self::MethodAnnotation::•(42)
+ method instanceMethod() → void {}
+}
+static method foo([@vm.inferred-type.metadata=dart.core::Null?] (core::List<core::int>) → void a) → core::int {
+ @self::VarAnnotation::•() core::int x = 2;
+ return x.{core::num::+}(2);
+}
+@self::ParametrizedAnnotation::•<core::Null>(null)
+static method main(core::List<core::String> args) → dynamic {
+ self::A::staticMethod();
+ [@vm.direct-call.metadata=#lib::B::instanceMethod] new self::B::•().{self::B::instanceMethod}();
+ self::foo(null);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index aef2831..79d7fdc 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -47,9 +47,12 @@
method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T1::•();
}
- abstract no-such-method-forwarder get bar() → dynamic;
- abstract no-such-method-forwarder method foo() → dynamic;
- abstract no-such-method-forwarder method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4, dynamic a5]) → dynamic;
+ no-such-method-forwarder get bar() → dynamic
+ return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+ no-such-method-forwarder method foo() → dynamic
+ return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+ no-such-method-forwarder method bazz([@vm.inferred-type.metadata=!] dynamic a1, [@vm.inferred-type.metadata=!] dynamic a2, [@vm.inferred-type.metadata=!] dynamic a3, [[@vm.inferred-type.metadata=!] dynamic a4, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5]) → dynamic
+ return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("bazz", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
}
abstract class C extends core::Object {
synthetic constructor •() → void
@@ -63,9 +66,12 @@
synthetic constructor •() → void
: super self::C::•()
;
- abstract no-such-method-forwarder get bar() → dynamic;
- abstract no-such-method-forwarder method foo() → dynamic;
- abstract no-such-method-forwarder method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4, dynamic a5]) → dynamic;
+ no-such-method-forwarder get bar() → dynamic
+ return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+ no-such-method-forwarder method foo() → dynamic
+ return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+ no-such-method-forwarder method bazz([@vm.inferred-type.metadata=!] dynamic a1, [@vm.inferred-type.metadata=!] dynamic a2, [@vm.inferred-type.metadata=!] dynamic a3, [[@vm.inferred-type.metadata=!] dynamic a4, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5]) → dynamic
+ return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("bazz", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
}
class E extends core::Object implements self::A {
synthetic constructor •() → void
@@ -74,8 +80,8 @@
method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T4::•();
}
- abstract no-such-method-forwarder get bar() → dynamic;
- abstract no-such-method-forwarder method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4, dynamic a5]) → dynamic;
+ no-such-method-forwarder get bar() → dynamic
+ return [@vm.direct-call.metadata=#lib::E::noSuchMethod] [@vm.inferred-type.metadata=#lib::T4] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
}
class F extends core::Object {
synthetic constructor •() → void
@@ -109,12 +115,12 @@
static method getDynamic() → dynamic
return self::unknown.call();
static method main(core::List<core::String> args) → dynamic {
- core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}());
- core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bar});
- core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bazz}(1, 2, 3, 4));
- core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}());
- core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bar});
- core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4));
+ core::print([@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}());
+ core::print([@vm.direct-call.metadata=#lib::B::bar??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bar});
+ core::print([@vm.direct-call.metadata=#lib::B::bazz??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bazz}(1, 2, 3, 4));
+ core::print([@vm.direct-call.metadata=#lib::D::foo??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}());
+ core::print([@vm.direct-call.metadata=#lib::D::bar??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bar});
+ core::print([@vm.direct-call.metadata=#lib::D::bazz??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4));
new self::E::•();
self::A xx = self::getDynamic() as{TypeError} self::A;
core::print([@vm.inferred-type.metadata=!] xx.{self::A::bar});
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index cd965fe..64908b5 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -24,10 +24,15 @@
--packages=*)
PACKAGES="$arg"
;;
+ --enable-asserts)
+ GEN_KERNEL_OPTIONS+=("$arg")
+ OPTIONS+=("$arg")
+ ;;
--sync-async | \
--no-sync-async | \
--tfa | \
- --no-tfa )
+ --no-tfa | \
+ -D* )
GEN_KERNEL_OPTIONS+=("$arg")
;;
--*)
diff --git a/pkg/vm/tool/test_bytecode b/pkg/vm/tool/test_bytecode
index f1c4893..7b05997 100755
--- a/pkg/vm/tool/test_bytecode
+++ b/pkg/vm/tool/test_bytecode
@@ -9,6 +9,10 @@
# Usage
# pkg/vm/tool/test_bytecode ~/foo.dart
+# Note: To generate bytecode in the platform dill file as well, change the value
+# of the constant 'isKernelBytecodeEnabled' in file
+# pkg/vm/lib/bytecode/gen_bytecode.dart from 'false' to 'true'.
+
set -e
# Pick the architecture and mode to build and test.
@@ -55,11 +59,21 @@
$CUR_DIR/gen_kernel --platform $BUILD_DIR/vm_platform_strong.dill \
--gen-bytecode $@ -o $BUILD_DIR/test_bytecode.dill
+# Dump bytecode in generated vm_platform_strong.dill file to platform.txt.
+# $BUILD_DIR/dart $SDK_DIR/pkg/vm/bin/dump_kernel.dart \
+# $BUILD_DIR/vm_platform_strong.dill $BUILD_DIR/platform.txt
+
+# Dump bytecode in generated test_bytecode.dill file to test_bytecode.txt.
+# $BUILD_DIR/dart $SDK_DIR/pkg/vm/bin/dump_kernel.dart \
+# $BUILD_DIR/test_bytecode.dill $BUILD_DIR/test_bytecode.txt
+
# Required flags.
DART_VM_FLAGS="--preview-dart-2 --optimization-counter-threshold=-1 $DART_VM_FLAGS"
-# Optional flags.
-# DART_VM_FLAGS="--force-log-flush --dump-kernel-bytecode --trace-interpreter-after=0 $DART_VM_FLAGS"
+# Optional flags examples. Uncomment as needed.
+# DART_VM_FLAGS="--force-log-flush --isolate-log-filter=\"\" $DART_VM_FLAGS"
+# DART_VM_FLAGS="--dump-kernel-bytecode $DART_VM_FLAGS"
+# DART_VM_FLAGS="--trace-interpreter-after=0 $DART_VM_FLAGS"
# Execute dill file.
exec $BUILD_DIR/dart $DART_VM_FLAGS $BUILD_DIR/test_bytecode.dill
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 1a7fc12..2062431 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -3,6 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
import("../build/dart/dart_host_sdk_toolchain.gni")
+import("configs.gni")
import("runtime_args.gni")
config("dart_public_config") {
@@ -48,7 +49,7 @@
defines += [ "DART_PRECOMPILER" ]
}
-config("dart_no_snapshot_config") {
+config("dart_nosnapshot_config") {
defines = []
defines += [ "DART_NO_SNAPSHOT" ]
}
@@ -120,6 +121,17 @@
}
}
+config("dart_interpreter_config") {
+ defines = [ "DART_USE_INTERPRETER" ]
+}
+
+config("dart_maybe_interpreter_config") {
+ defines = []
+ if (dart_use_interpreter) {
+ defines += [ "DART_USE_INTERPRETER" ]
+ }
+}
+
config("dart_config") {
defines = []
@@ -136,15 +148,14 @@
}
if (is_fuchsia) {
- defines += [ "DART_USE_JEMALLOC" ]
+ import("//build/config/scudo/scudo.gni")
include_dirs += [
"//zircon/system/ulib/zx/include",
- "//zircon/third_party/ulib/jemalloc/include",
]
- }
-
- if (dart_use_interpreter) {
- defines += [ "DART_USE_INTERPRETER" ]
+ if (!use_scudo) {
+ defines += [ "DART_USE_JEMALLOC" ]
+ include_dirs += [ "//zircon/third_party/ulib/jemalloc/include" ]
+ }
}
if (!is_win) {
@@ -191,172 +202,29 @@
]
}
-template("libdart_library") {
- extra_configs = []
- if (defined(invoker.extra_configs)) {
- extra_configs += invoker.extra_configs
- }
- extra_deps = []
- if (defined(invoker.extra_deps)) {
- extra_deps += invoker.extra_deps
- }
- target(dart_component_kind, target_name) {
- configs += [
- ":dart_arch_config",
- ":dart_config",
- ] + extra_configs
- if (is_fuchsia) {
- configs -= [ "//build/config:symbol_visibility_hidden" ]
- }
- deps = [
- "third_party/double-conversion/src:libdouble_conversion",
- ":generate_version_cc_file",
- ] + extra_deps
- include_dirs = [ "." ]
- public_configs = [ ":dart_public_config" ]
- sources = [
- "$target_gen_dir/version.cc",
- "include/dart_api.h",
- "include/dart_native_api.h",
- "include/dart_tools_api.h",
- "vm/dart_api_impl.cc",
- "vm/native_api_impl.cc",
- "vm/version.h",
- ]
- defines = [ "DART_SHARED_LIB" ]
- }
-}
-
-libdart_library("libdart_jit") {
- extra_configs = [
- ":dart_maybe_product_config",
- ":dart_os_config",
- ]
+library_for_all_configs("libdart") {
+ target_type = dart_component_kind
extra_deps = [
+ "third_party/double-conversion/src:libdouble_conversion",
+ ":generate_version_cc_file",
+ ]
+ configurable_deps = [
"platform:libdart_platform",
- "vm:libdart_lib_jit",
- "vm:libdart_vm_jit",
+ "vm:libdart_lib",
+ "vm:libdart_vm",
]
-}
-
-libdart_library("libdart_jit_product") {
- extra_configs = [
- ":dart_product_config",
- ":dart_os_config",
+ include_dirs = [ "." ]
+ public_configs = [ ":dart_public_config" ]
+ sources = [
+ "$target_gen_dir/version.cc",
+ "include/dart_api.h",
+ "include/dart_native_api.h",
+ "include/dart_tools_api.h",
+ "vm/dart_api_impl.cc",
+ "vm/native_api_impl.cc",
+ "vm/version.h",
]
- extra_deps = [
- "platform:libdart_platform_product",
- "vm:libdart_lib_jit_product",
- "vm:libdart_vm_jit_product",
- ]
-}
-
-libdart_library("libdart_precompiled_runtime") {
- extra_configs = [
- ":dart_maybe_product_config",
- ":dart_precompiled_runtime_config",
- ":dart_os_config",
- ]
- extra_deps = [
- "platform:libdart_platform",
- "vm:libdart_lib_precompiled_runtime",
- "vm:libdart_vm_precompiled_runtime",
- ]
-}
-
-libdart_library("libdart_precompiled_runtime_product") {
- extra_configs = [
- ":dart_product_config",
- ":dart_precompiled_runtime_config",
- ":dart_os_config",
- ]
- extra_deps = [
- "platform:libdart_platform_product",
- "vm:libdart_lib_precompiled_runtime_product",
- "vm:libdart_vm_precompiled_runtime_product",
- ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler") {
- extra_configs = [
- ":dart_maybe_product_config",
- ":dart_no_snapshot_config",
- ":dart_precompiler_config",
- ":dart_os_config",
- ]
- extra_deps = [
- "platform:libdart_platform",
- "vm:libdart_lib_nosnapshot_with_precompiler",
- "vm:libdart_vm_nosnapshot_with_precompiler",
- ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler_product") {
- extra_configs = [
- ":dart_product_config",
- ":dart_no_snapshot_config",
- ":dart_precompiler_config",
- ":dart_os_config",
- ]
- extra_deps = [
- "platform:libdart_platform_product",
- "vm:libdart_lib_nosnapshot_with_precompiler_product",
- "vm:libdart_vm_nosnapshot_with_precompiler_product",
- ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler_fuchsia") {
- extra_configs = [
- ":dart_maybe_product_config",
- ":dart_no_snapshot_config",
- ":dart_precompiler_config",
- ":dart_os_fuchsia_config",
- ]
- extra_deps = [
- "platform:libdart_platform_fuchsia",
- "vm:libdart_lib_nosnapshot_with_precompiler_fuchsia",
- "vm:libdart_vm_nosnapshot_with_precompiler_fuchsia",
- ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler_product_fuchsia") {
- extra_configs = [
- ":dart_product_config",
- ":dart_no_snapshot_config",
- ":dart_precompiler_config",
- ":dart_os_fuchsia_config",
- ]
- extra_deps = [
- "platform:libdart_platform_product_fuchsia",
- "vm:libdart_lib_nosnapshot_with_precompiler_product_fuchsia",
- "vm:libdart_vm_nosnapshot_with_precompiler_product_fuchsia",
- ]
-}
-
-libdart_library("libdart_with_precompiler") {
- extra_configs = [
- ":dart_maybe_product_config",
- ":dart_precompiler_config",
- ":dart_os_config",
- ]
- extra_deps = [
- "platform:libdart_platform",
- "vm:libdart_lib_with_precompiler",
- "vm:libdart_vm_with_precompiler",
- ]
-}
-
-libdart_library("libdart_with_precompiler_product") {
- extra_configs = [
- ":dart_product_config",
- ":dart_precompiler_config",
- ":dart_os_config",
- ]
- extra_deps = [
- "platform:libdart_platform_product",
- "vm:libdart_lib_with_precompiler_product",
- "vm:libdart_vm_with_precompiler_product",
- ]
+ defines = [ "DART_SHARED_LIB" ]
}
action("generate_version_cc_file") {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 71d98d4..970dad7 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -246,6 +246,7 @@
static_library(target_name) {
configs += [
"..:dart_arch_config",
+ "..:dart_maybe_interpreter_config",
"..:dart_config",
] + extra_configs
if (is_fuchsia) {
@@ -332,6 +333,7 @@
configs += [
"..:dart_arch_config",
"..:dart_config",
+ "..:dart_maybe_interpreter_config",
"..:dart_precompiler_config",
] + extra_configs
if (is_fuchsia) {
@@ -467,6 +469,7 @@
configs += [
"..:dart_arch_config",
"..:dart_config",
+ "..:dart_maybe_interpreter_config",
"..:dart_precompiler_config",
] + extra_configs
deps = []
@@ -554,6 +557,7 @@
configs += [
"..:dart_arch_config",
"..:dart_config",
+ "..:dart_maybe_interpreter_config",
"..:dart_os_config",
] + extra_configs
if (is_fuchsia) {
@@ -868,6 +872,7 @@
"..:dart_arch_config",
"..:dart_config",
"..:dart_os_config",
+ "..:dart_maybe_interpreter_config",
"..:dart_maybe_product_config",
] + extra_configs
if (is_fuchsia) {
@@ -1011,7 +1016,7 @@
dart_executable("dart_bootstrap") {
extra_configs = [
"..:dart_precompiler_config",
- "..:dart_no_snapshot_config",
+ "..:dart_nosnapshot_config",
]
extra_deps = [
":gen_resources_cc",
@@ -1113,6 +1118,7 @@
"..:dart_arch_config",
"..:dart_config",
"..:dart_os_config",
+ "..:dart_maybe_interpreter_config",
"..:dart_maybe_product_config",
]
if (is_fuchsia) {
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index bb4661e..a5d1d83 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -213,7 +213,7 @@
return reinterpret_cast<void*>(file);
}
-void DartUtils::ReadFile(const uint8_t** data, intptr_t* len, void* stream) {
+void DartUtils::ReadFile(uint8_t** data, intptr_t* len, void* stream) {
ASSERT(data != NULL);
ASSERT(len != NULL);
ASSERT(stream != NULL);
@@ -225,14 +225,16 @@
return;
}
*len = static_cast<intptr_t>(file_len);
- uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*len));
- ASSERT(text_buffer != NULL);
- if (!file_stream->ReadFully(text_buffer, *len)) {
+ *data = reinterpret_cast<uint8_t*>(malloc(*len));
+ if (*data == NULL) {
+ OUT_OF_MEMORY();
+ }
+ if (!file_stream->ReadFully(*data, *len)) {
+ free(*data);
*data = NULL;
*len = -1; // Indicates read was not successful.
return;
}
- *data = text_buffer;
}
void DartUtils::WriteFile(const void* buffer,
@@ -270,16 +272,16 @@
snprintf(msg, len + 1, format, __VA_ARGS__); \
*error_msg = msg
-static const uint8_t* ReadFileFully(const char* filename,
- intptr_t* file_len,
- const char** error_msg) {
+static uint8_t* ReadFileFully(const char* filename,
+ intptr_t* file_len,
+ const char** error_msg) {
*file_len = -1;
void* stream = DartUtils::OpenFile(filename, false);
if (stream == NULL) {
SET_ERROR_MSG(error_msg, "Unable to open file: %s", filename);
return NULL;
}
- const uint8_t* text_buffer = NULL;
+ uint8_t* text_buffer = NULL;
DartUtils::ReadFile(&text_buffer, file_len, stream);
if (text_buffer == NULL || *file_len == -1) {
*error_msg = "Unable to read file contents";
@@ -292,12 +294,12 @@
Dart_Handle DartUtils::ReadStringFromFile(const char* filename) {
const char* error_msg = NULL;
intptr_t len;
- const uint8_t* text_buffer = ReadFileFully(filename, &len, &error_msg);
+ uint8_t* text_buffer = ReadFileFully(filename, &len, &error_msg);
if (text_buffer == NULL) {
return Dart_NewApiError(error_msg);
}
Dart_Handle str = Dart_NewStringFromUTF8(text_buffer, len);
- free(const_cast<uint8_t*>(text_buffer));
+ free(text_buffer);
return str;
}
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 5c14911..2ae7ca6 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -122,7 +122,7 @@
static void* MapExecutable(const char* name, intptr_t* file_len);
static void* OpenFile(const char* name, bool write);
static void* OpenFileUri(const char* uri, bool write);
- static void ReadFile(const uint8_t** data, intptr_t* file_len, void* stream);
+ static void ReadFile(uint8_t** data, intptr_t* file_len, void* stream);
static void WriteFile(const void* buffer, intptr_t num_bytes, void* stream);
static void CloseFile(void* stream);
static bool EntropySource(uint8_t* buffer, intptr_t length);
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 11167d4..c53b8d1 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -3,14 +3,16 @@
// BSD-style license that can be found in the LICENSE file.
#include "bin/dfe.h"
+
#include "bin/dartutils.h"
#include "bin/directory.h"
#include "bin/error_exit.h"
#include "bin/file.h"
#include "bin/platform.h"
#include "bin/utils.h"
-
-#include "vm/kernel.h"
+#include "include/dart_tools_api.h"
+#include "platform/utils.h"
+#include "vm/os.h"
extern "C" {
#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
@@ -75,15 +77,11 @@
return Utils::StrNDup(name, i + 1);
}
-static void NoopRelease(uint8_t* buffer) {}
-
DFE::DFE()
: use_dfe_(false),
frontend_filename_(NULL),
- kernel_service_program_(NULL),
- platform_program_(NULL),
- platform_strong_program_(NULL),
- application_kernel_binary_(NULL) {}
+ application_kernel_buffer_(NULL),
+ application_kernel_buffer_size_(0) {}
DFE::~DFE() {
if (frontend_filename_ != NULL) {
@@ -91,38 +89,15 @@
}
frontend_filename_ = NULL;
- // Do NOT delete kernel_service_program_ in the destructor.
- // It is always a full a dill file, hence it is used as
- // argument to Dart_CreateIsolateFromKernel as well as loaded
- // as the kernel program for the isolate. Hence, deleting here
- // would lead to double deletion.
-
- delete reinterpret_cast<kernel::Program*>(platform_program_);
- platform_program_ = NULL;
-
- delete reinterpret_cast<kernel::Program*>(platform_strong_program_);
- platform_strong_program_ = NULL;
-
- delete reinterpret_cast<kernel::Program*>(application_kernel_binary_);
- application_kernel_binary_ = NULL;
+ free(application_kernel_buffer_);
+ application_kernel_buffer_ = NULL;
+ application_kernel_buffer_size_ = 0;
}
void DFE::Init() {
if (platform_dill == NULL) {
return;
}
- // platform_dill is not NULL implies that platform_strong_dill is also
- // not NULL.
- if (platform_program_ == NULL) {
- ASSERT(Dart_IsKernel(platform_dill, platform_dill_size));
- platform_program_ =
- Dart_ReadKernelBinary(platform_dill, platform_dill_size, NoopRelease);
- }
- if (platform_strong_program_ == NULL) {
- ASSERT(Dart_IsKernel(platform_strong_dill, platform_strong_dill_size));
- platform_strong_program_ = Dart_ReadKernelBinary(
- platform_strong_dill, platform_strong_dill_size, NoopRelease);
- }
if (frontend_filename_ == NULL) {
// Look for the frontend snapshot next to the executable.
@@ -153,34 +128,29 @@
return kernel_service_dill != NULL;
}
-void* DFE::LoadKernelServiceProgram() {
- if (kernel_service_dill == NULL) {
- return NULL;
- }
- if (kernel_service_program_ == NULL) {
- kernel_service_program_ = Dart_ReadKernelBinary(
- kernel_service_dill, kernel_service_dill_size, NoopRelease);
- }
- return kernel_service_program_;
+void DFE::LoadKernelService(const uint8_t** kernel_service_buffer,
+ intptr_t* kernel_service_buffer_size) {
+ *kernel_service_buffer = kernel_service_dill;
+ *kernel_service_buffer_size = kernel_service_dill_size;
}
-void* DFE::platform_program(bool strong) const {
+void DFE::LoadPlatform(const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
+ bool strong) {
if (strong) {
- return platform_strong_program_;
+ *kernel_buffer = platform_strong_dill;
+ *kernel_buffer_size = platform_strong_dill_size;
} else {
- return platform_program_;
+ *kernel_buffer = platform_dill;
+ *kernel_buffer_size = platform_dill_size;
}
}
bool DFE::CanUseDartFrontend() const {
- return (platform_program() != NULL) &&
+ return (platform_dill != NULL) &&
(KernelServiceDillAvailable() || (frontend_filename() != NULL));
}
-static void ReleaseFetchedBytes(uint8_t* buffer) {
- free(buffer);
-}
-
class WindowsPathSanitizer {
public:
explicit WindowsPathSanitizer(const char* path) {
@@ -239,17 +209,22 @@
package_config);
}
-void* DFE::CompileAndReadScript(const char* script_uri,
- char** error,
- int* exit_code,
- bool strong,
- const char* package_config) {
+void DFE::CompileAndReadScript(const char* script_uri,
+ uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
+ char** error,
+ int* exit_code,
+ bool strong,
+ const char* package_config) {
Dart_KernelCompilationResult result =
CompileScript(script_uri, strong, true, package_config);
switch (result.status) {
case Dart_KernelCompilationStatus_Ok:
- return Dart_ReadKernelBinary(result.kernel, result.kernel_size,
- ReleaseFetchedBytes);
+ *kernel_buffer = result.kernel;
+ *kernel_buffer_size = result.kernel_size;
+ *error = NULL;
+ *exit_code = 0;
+ break;
case Dart_KernelCompilationStatus_Error:
*error = result.error; // Copy error message.
*exit_code = kCompilationErrorExitCode;
@@ -263,25 +238,27 @@
*exit_code = kErrorExitCode;
break;
}
- return NULL;
}
-void* DFE::ReadScript(const char* script_uri) const {
+void DFE::ReadScript(const char* script_uri,
+ uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size) const {
int64_t start = Dart_TimelineGetMicros();
- const uint8_t* buffer = NULL;
- intptr_t buffer_length = -1;
- bool result = TryReadKernelFile(script_uri, &buffer, &buffer_length);
- void* read_binary =
- result ? Dart_ReadKernelBinary(buffer, buffer_length, ReleaseFetchedBytes)
- : NULL;
+ if (!TryReadKernelFile(script_uri, kernel_buffer, kernel_buffer_size)) {
+ return;
+ }
+ if (!Dart_IsKernel(*kernel_buffer, *kernel_buffer_size)) {
+ free(*kernel_buffer);
+ *kernel_buffer = NULL;
+ *kernel_buffer_size = -1;
+ }
int64_t end = Dart_TimelineGetMicros();
Dart_TimelineEvent("DFE::ReadScript", start, end,
Dart_Timeline_Event_Duration, 0, NULL, NULL);
- return read_binary;
}
bool DFE::TryReadKernelFile(const char* script_uri,
- const uint8_t** kernel_ir,
+ uint8_t** kernel_ir,
intptr_t* kernel_ir_size) {
*kernel_ir = NULL;
*kernel_ir_size = -1;
@@ -289,7 +266,7 @@
if (script_file == NULL) {
return false;
}
- const uint8_t* buffer = NULL;
+ uint8_t* buffer = NULL;
DartUtils::ReadFile(&buffer, kernel_ir_size, script_file);
DartUtils::CloseFile(script_file);
if (*kernel_ir_size == 0 || buffer == NULL) {
@@ -297,7 +274,7 @@
}
if (DartUtils::SniffForMagicNumber(buffer, *kernel_ir_size) !=
DartUtils::kKernelMagicNumber) {
- free(const_cast<uint8_t*>(buffer));
+ free(buffer);
*kernel_ir = NULL;
*kernel_ir_size = -1;
return false;
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index d770bb0..6efb45c 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -40,10 +40,14 @@
// Set the kernel program for the main application if it was specified
// as a dill file.
- void set_application_kernel_binary(void* application_kernel_binary) {
- application_kernel_binary_ = application_kernel_binary;
+ void set_application_kernel_buffer(uint8_t* buffer, intptr_t size) {
+ application_kernel_buffer_ = buffer;
+ application_kernel_buffer_size_ = size;
}
- void* application_kernel_binary() const { return application_kernel_binary_; }
+ void application_kernel_buffer(const uint8_t** buffer, intptr_t* size) const {
+ *buffer = application_kernel_buffer_;
+ *size = application_kernel_buffer_size_;
+ }
// Compiles specified script.
// Returns result from compiling the script.
@@ -56,16 +60,20 @@
// If the compilation is successful, returns a valid in memory kernel
// representation of the script, NULL otherwise
// 'error' and 'exit_code' have the error values in case of errors.
- void* CompileAndReadScript(const char* script_uri,
- char** error,
- int* exit_code,
- bool strong,
- const char* package_config);
+ void CompileAndReadScript(const char* script_uri,
+ uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
+ char** error,
+ int* exit_code,
+ bool strong,
+ const char* package_config);
// Reads the script kernel file if specified 'script_uri' is a kernel file.
// Returns an in memory kernel representation of the specified script is a
// valid kernel file, false otherwise.
- void* ReadScript(const char* script_uri) const;
+ void ReadScript(const char* script_uri,
+ uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size) const;
static bool KernelServiceDillAvailable();
@@ -75,8 +83,8 @@
// The caller is responsible for free()ing [kernel_file] if `true`
// was returned.
static bool TryReadKernelFile(const char* script_uri,
- const uint8_t** kernel_ir,
- intptr_t* kernel_ir_size);
+ uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size);
// We distinguish between "intent to use Dart frontend" vs "can actually
// use Dart frontend". The method UseDartFrontend tells us about the
@@ -84,20 +92,19 @@
// be used.
bool CanUseDartFrontend() const;
- void* platform_program(bool strong = false) const;
-
- void* LoadKernelServiceProgram();
+ void LoadPlatform(const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
+ bool strong = false);
+ void LoadKernelService(const uint8_t** kernel_service_buffer,
+ intptr_t* kernel_service_buffer_size);
private:
bool use_dfe_;
char* frontend_filename_;
- void* kernel_service_program_;
- void* platform_program_;
- void* platform_strong_program_;
-
// Kernel binary specified on the cmd line.
- void* application_kernel_binary_;
+ uint8_t* application_kernel_buffer_;
+ intptr_t application_kernel_buffer_size_;
DISALLOW_COPY_AND_ASSIGN(DFE);
};
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 6de85ad..76e73d7 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1416,7 +1416,8 @@
return isolate;
}
-static int GenerateSnapshotFromKernelProgram(void* kernel_program) {
+static int GenerateSnapshotFromKernel(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
ASSERT(SnapshotKindAllowedFromKernel());
char* error = NULL;
@@ -1440,7 +1441,8 @@
// in the main isolate as well.
isolate_flags.load_vmservice_library = true;
Dart_Isolate isolate = Dart_CreateIsolateFromKernel(
- NULL, NULL, kernel_program, &isolate_flags, isolate_data, &error);
+ NULL, NULL, kernel_buffer, kernel_buffer_size, &isolate_flags,
+ isolate_data, &error);
if (isolate == NULL) {
delete isolate_data;
Log::PrintErr("%s\n", error);
@@ -1462,11 +1464,8 @@
//
// If the input dill file does not have a root library, then
// Dart_LoadScript will error.
- Dart_Handle dummy_uri =
- DartUtils::NewString("____dummy_gen_snapshot_root_library_uri____");
Dart_Handle library =
- Dart_LoadScript(dummy_uri, Dart_Null(),
- reinterpret_cast<Dart_Handle>(kernel_program), 0, 0);
+ Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size);
if (Dart_IsError(library)) {
Log::PrintErr("Unable to load root library from the input dill file.\n");
return kErrorExitCode;
@@ -1511,11 +1510,12 @@
}
// Sniff the script to check if it is actually a dill file.
- void* kernel_program = NULL;
+ uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = NULL;
if (app_script_name != NULL) {
- kernel_program = dfe.ReadScript(app_script_name);
+ dfe.ReadScript(app_script_name, &kernel_buffer, &kernel_buffer_size);
}
- if (kernel_program != NULL && !SnapshotKindAllowedFromKernel()) {
+ if (kernel_buffer != NULL && !SnapshotKindAllowedFromKernel()) {
// TODO(sivachandra): Add check for the kernel program format (incremental
// vs batch).
Log::PrintErr(
@@ -1567,7 +1567,7 @@
Dart_InitializeParams init_params;
memset(&init_params, 0, sizeof(init_params));
init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
- if (app_script_name != NULL && kernel_program == NULL) {
+ if (app_script_name != NULL && kernel_buffer == NULL) {
// We need the service isolate to load script files.
// When generating snapshots from a kernel program, we do not need to load
// any script files.
@@ -1613,8 +1613,8 @@
return kErrorExitCode;
}
- if (kernel_program != NULL) {
- return GenerateSnapshotFromKernelProgram(kernel_program);
+ if (kernel_buffer != NULL) {
+ return GenerateSnapshotFromKernel(kernel_buffer, kernel_buffer_size);
}
Dart_IsolateFlags flags;
@@ -1714,7 +1714,7 @@
AddDependency(commandline_packages_file);
}
- ASSERT(kernel_program == NULL);
+ ASSERT(kernel_buffer == NULL);
// Load any libraries named in the entry points. Do this before loading the
// user's script to ensure conditional imports see the embedder-specific
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 72368ca..324eb1a 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -169,6 +169,9 @@
V(SynchronousSocket_ReadList, 4) \
V(SynchronousSocket_WriteList, 4) \
V(SystemEncodingToString, 1) \
+ V(X509_Der, 1) \
+ V(X509_Pem, 1) \
+ V(X509_Sha1, 1) \
V(X509_Subject, 1) \
V(X509_Issuer, 1) \
V(X509_StartValidity, 1) \
diff --git a/runtime/bin/isolate_data.cc b/runtime/bin/isolate_data.cc
index 796509a..c7f1779 100644
--- a/runtime/bin/isolate_data.cc
+++ b/runtime/bin/isolate_data.cc
@@ -5,8 +5,6 @@
#include "bin/isolate_data.h"
#include "bin/snapshot_utils.h"
-#include "vm/kernel.h"
-
namespace dart {
namespace bin {
@@ -17,12 +15,14 @@
: script_url((url != NULL) ? strdup(url) : NULL),
package_root(NULL),
packages_file(NULL),
- kernel_program(NULL),
builtin_lib_(NULL),
loader_(NULL),
app_snapshot_(app_snapshot),
dependencies_(NULL),
- create_isolate_from_kernel_(false) {
+ resolved_packages_config_(NULL),
+ kernel_buffer_(NULL),
+ kernel_buffer_size_(0),
+ owns_kernel_buffer_(false) {
if (package_root != NULL) {
ASSERT(packages_file == NULL);
this->package_root = strdup(package_root);
@@ -45,10 +45,14 @@
package_root = NULL;
free(packages_file);
packages_file = NULL;
- if (kernel_program != NULL) {
- delete reinterpret_cast<kernel::Program*>(kernel_program);
- kernel_program = NULL;
+ free(resolved_packages_config_);
+ resolved_packages_config_ = NULL;
+ if (owns_kernel_buffer_) {
+ ASSERT(kernel_buffer_ != NULL);
+ free(kernel_buffer_);
}
+ kernel_buffer_ = NULL;
+ kernel_buffer_size_ = 0;
delete app_snapshot_;
app_snapshot_ = NULL;
}
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index ed78806..575d1b0 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -51,7 +51,15 @@
char* script_url;
char* package_root;
char* packages_file;
- void* kernel_program;
+
+ const uint8_t* kernel_buffer() const { return kernel_buffer_; }
+ intptr_t kernel_buffer_size() const { return kernel_buffer_size_; }
+ void set_kernel_buffer(uint8_t* buffer, intptr_t size, bool take_ownership) {
+ ASSERT(kernel_buffer_ == NULL);
+ kernel_buffer_ = buffer;
+ kernel_buffer_size_ = size;
+ owns_kernel_buffer_ = take_ownership;
+ }
void UpdatePackagesFile(const char* packages_file_) {
if (packages_file != NULL) {
@@ -61,6 +69,18 @@
packages_file = strdup(packages_file_);
}
+ const char* resolved_packages_config() const {
+ return resolved_packages_config_;
+ }
+
+ void set_resolved_packages_config(const char* packages_config) {
+ if (resolved_packages_config_ != NULL) {
+ free(resolved_packages_config_);
+ resolved_packages_config_ = NULL;
+ }
+ resolved_packages_config_ = strdup(packages_config);
+ }
+
// While loading a loader is associated with the isolate.
bool HasLoader() const { return loader_ != NULL; }
Loader* loader() const {
@@ -78,19 +98,15 @@
void OnIsolateShutdown();
- void set_create_isolate_from_kernel(bool value) {
- create_isolate_from_kernel_ = value;
- }
- bool create_isolate_from_kernel() const {
- return create_isolate_from_kernel_;
- }
-
private:
Dart_Handle builtin_lib_;
Loader* loader_;
AppSnapshot* app_snapshot_;
MallocGrowableArray<char*>* dependencies_;
- bool create_isolate_from_kernel_;
+ char* resolved_packages_config_;
+ uint8_t* kernel_buffer_;
+ intptr_t kernel_buffer_size_;
+ bool owns_kernel_buffer_;
DISALLOW_COPY_AND_ASSIGN(IsolateData);
};
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 70c34e3..64b76f5 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -336,10 +336,6 @@
uint8_t* decompressed_;
};
-static void ReleaseFetchedBytes(uint8_t* buffer) {
- free(buffer);
-}
-
bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) {
// We have to copy everything we care about out of |result| because after
// dropping the lock below |result| may no longer valid.
@@ -457,10 +453,7 @@
// isolates. We currently do not have support for neither
// `Isolate.spawn()` nor `Isolate.spawnUri()` with kernel-based
// frontend.
- Dart_Handle kernel_binary =
- reinterpret_cast<Dart_Handle>(Dart_ReadKernelBinary(
- payload, payload_length, ReleaseFetchedBytes));
- dart_result = Dart_LoadScript(uri, resolved_uri, kernel_binary, 0, 0);
+ dart_result = Dart_LoadScriptFromKernel(payload, payload_length);
} else {
dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0);
}
@@ -646,6 +639,12 @@
return Dart_Null();
}
#else
+static void MallocFinalizer(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* peer) {
+ free(peer);
+}
+
Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url) {
@@ -663,17 +662,17 @@
}
Dart_Isolate current = Dart_CurrentIsolate();
if (tag == Dart_kKernelTag) {
- const uint8_t* kernel_ir = NULL;
- intptr_t kernel_ir_size = 0;
-
- // Check to see if url_string points to a valid dill file. If so, return the
- // loaded kernel::Program.
- if (!DFE::TryReadKernelFile(url_string, &kernel_ir, &kernel_ir_size)) {
+ uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
+ if (!DFE::TryReadKernelFile(url_string, &kernel_buffer,
+ &kernel_buffer_size)) {
return DartUtils::NewError("'%s' is not a kernel file", url_string);
}
- void* kernel_program =
- Dart_ReadKernelBinary(kernel_ir, kernel_ir_size, ReleaseFetchedBytes);
- return Dart_NewExternalTypedData(Dart_TypedData_kUint64, kernel_program, 1);
+ result = Dart_NewExternalTypedData(Dart_TypedData_kUint8, kernel_buffer,
+ kernel_buffer_size);
+ Dart_NewWeakPersistentHandle(result, kernel_buffer, kernel_buffer_size,
+ MallocFinalizer);
+ return result;
}
if (tag == Dart_kImportResolvedExtensionTag) {
if (strncmp(url_string, "file://", 7)) {
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 9e2a352..5a495e8 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -224,9 +224,12 @@
char** error,
int* exit_code) {
Dart_EnterScope();
+#if !defined(DART_PRECOMPILED_RUNTIME)
IsolateData* isolate_data =
reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
- void* kernel_program = isolate_data->kernel_program;
+ const uint8_t* kernel_buffer = isolate_data->kernel_buffer();
+ intptr_t kernel_buffer_size = isolate_data->kernel_buffer_size();
+#endif
// Set up the library tag handler for this isolate.
Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler);
@@ -251,6 +254,9 @@
result = Dart_StringToCString(result, &resolved_packages_config);
CHECK_RESULT(result);
ASSERT(resolved_packages_config != NULL);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ isolate_data->set_resolved_packages_config(resolved_packages_config);
+#endif
}
result = Dart_SetEnvironmentCallback(EnvironmentCallback);
@@ -258,7 +264,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
if (Options::preview_dart_2() && !isolate_run_app_snapshot &&
- kernel_program == NULL && !Dart_IsKernelIsolate(isolate)) {
+ kernel_buffer == NULL && !Dart_IsKernelIsolate(isolate)) {
if (!dfe.CanUseDartFrontend()) {
const char* format = "Dart frontend unavailable to compile script %s.";
intptr_t len = snprintf(NULL, 0, format, script_uri) + 1;
@@ -270,24 +276,28 @@
Dart_ShutdownIsolate();
return NULL;
}
- kernel_program = dfe.CompileAndReadScript(
- script_uri, error, exit_code, flags->strong, resolved_packages_config);
- if (kernel_program == NULL) {
+ uint8_t* application_kernel_buffer = NULL;
+ intptr_t application_kernel_buffer_size = 0;
+ dfe.CompileAndReadScript(script_uri, &application_kernel_buffer,
+ &application_kernel_buffer_size, error, exit_code,
+ flags->strong, resolved_packages_config);
+ if (application_kernel_buffer == NULL) {
Dart_ExitScope();
Dart_ShutdownIsolate();
return NULL;
}
- isolate_data->kernel_program = kernel_program;
+ isolate_data->set_kernel_buffer(application_kernel_buffer,
+ application_kernel_buffer_size,
+ true /*take ownership*/);
+ kernel_buffer = application_kernel_buffer;
+ kernel_buffer_size = application_kernel_buffer_size;
}
- if (kernel_program != NULL) {
+ if (kernel_buffer != NULL) {
Dart_Handle uri = Dart_NewStringFromCString(script_uri);
CHECK_RESULT(uri);
Dart_Handle resolved_script_uri = DartUtils::ResolveScript(uri);
CHECK_RESULT(resolved_script_uri);
- result =
- Dart_LoadScript(uri, resolved_script_uri,
- reinterpret_cast<Dart_Handle>(kernel_program), 0, 0);
- isolate_data->kernel_program = NULL; // Dart_LoadScript takes ownership.
+ result = Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size);
CHECK_RESULT(result);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -322,11 +332,12 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
} else {
+#if !defined(DART_PRECOMPILED_RUNTIME)
// Load the specified application script into the newly created isolate.
Dart_Handle uri =
DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri));
CHECK_RESULT(uri);
- if (kernel_program == NULL) {
+ if (kernel_buffer == NULL) {
result = Loader::LibraryTagHandler(Dart_kScriptTag, Dart_Null(), uri);
CHECK_RESULT(result);
} else {
@@ -344,6 +355,9 @@
result = DartUtils::SetupIOLibrary(Options::namespc(), script_uri,
Options::exit_disabled());
CHECK_RESULT(result);
+#else
+ UNREACHABLE();
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
// Make the isolate runnable so that it is ready to handle messages.
@@ -402,13 +416,18 @@
isolate_snapshot_instructions, app_isolate_shared_data,
app_isolate_shared_instructions, flags, isolate_data, error);
} else {
- void* kernel_service_program = dfe.LoadKernelServiceProgram();
- ASSERT(kernel_service_program != NULL);
+ const uint8_t* kernel_service_buffer = NULL;
+ intptr_t kernel_service_buffer_size = 0;
+ dfe.LoadKernelService(&kernel_service_buffer, &kernel_service_buffer_size);
+ ASSERT(kernel_service_buffer != NULL);
IsolateData* isolate_data =
new IsolateData(uri, package_root, packages_config, NULL);
- isolate_data->kernel_program = kernel_service_program;
- isolate = Dart_CreateIsolateFromKernel(uri, main, kernel_service_program,
- flags, isolate_data, error);
+ isolate_data->set_kernel_buffer(const_cast<uint8_t*>(kernel_service_buffer),
+ kernel_service_buffer_size,
+ false /* take_ownership */);
+ isolate = Dart_CreateIsolateFromKernel(uri, main, kernel_service_buffer,
+ kernel_service_buffer_size, flags,
+ isolate_data, error);
}
if (isolate == NULL) {
@@ -466,15 +485,20 @@
if (Options::preview_dart_2()) {
// If there is intention to use DFE, then we create the isolate
// from kernel only if we can.
- void* platform_program = dfe.platform_program(flags->strong) != NULL
- ? dfe.platform_program(flags->strong)
- : dfe.application_kernel_binary();
+ const uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
+ dfe.LoadPlatform(&kernel_buffer, &kernel_buffer_size, flags->strong);
+ if (kernel_buffer == NULL) {
+ dfe.application_kernel_buffer(&kernel_buffer, &kernel_buffer_size);
+ }
+
// TODO(sivachandra): When the platform program is unavailable, check if
// application kernel binary is self contained or an incremental binary.
// Isolate should be created only if it is a self contained kernel binary.
- if (platform_program != NULL) {
- isolate = Dart_CreateIsolateFromKernel(script_uri, NULL, platform_program,
- flags, isolate_data, error);
+ if (kernel_buffer != NULL) {
+ isolate = Dart_CreateIsolateFromKernel(script_uri, NULL, kernel_buffer,
+ kernel_buffer_size, flags,
+ isolate_data, error);
} else {
*error =
strdup("Platform kernel not available to create service isolate.");
@@ -529,7 +553,8 @@
int* exit_code) {
int64_t start = Dart_TimelineGetMicros();
ASSERT(script_uri != NULL);
- void* kernel_program = NULL;
+ uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
AppSnapshot* app_snapshot = NULL;
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -563,12 +588,16 @@
}
}
if (!isolate_run_app_snapshot) {
- kernel_program = dfe.ReadScript(script_uri);
+ dfe.ReadScript(script_uri, &kernel_buffer, &kernel_buffer_size);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
IsolateData* isolate_data =
new IsolateData(script_uri, package_root, packages_config, app_snapshot);
+ if (kernel_buffer != NULL) {
+ isolate_data->set_kernel_buffer(kernel_buffer, kernel_buffer_size,
+ true /*take ownership*/);
+ }
if (is_main_isolate && (Options::snapshot_deps_filename() != NULL)) {
isolate_data->set_dependencies(new MallocGrowableArray<char*>());
}
@@ -576,20 +605,24 @@
Dart_Isolate isolate = NULL;
#if !defined(DART_PRECOMPILED_RUNTIME)
- if (Options::preview_dart_2()) {
- void* platform_program = dfe.platform_program(flags->strong) != NULL
- ? dfe.platform_program(flags->strong)
- : kernel_program;
-
- if (platform_program == NULL) {
+ if (Options::preview_dart_2() && !isolate_run_app_snapshot) {
+ const uint8_t* platform_kernel_buffer = NULL;
+ intptr_t platform_kernel_buffer_size = 0;
+ dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size,
+ flags->strong);
+ if (platform_kernel_buffer == NULL) {
+ platform_kernel_buffer = kernel_buffer;
+ platform_kernel_buffer_size = kernel_buffer_size;
+ }
+ if (platform_kernel_buffer == NULL) {
FATAL("platform_program cannot be NULL.");
}
// TODO(sivachandra): When the platform program is unavailable, check if
// application kernel binary is self contained or an incremental binary.
// Isolate should be created only if it is a self contained kernel binary.
- isolate = Dart_CreateIsolateFromKernel(script_uri, main, platform_program,
- flags, isolate_data, error);
- isolate_data->kernel_program = kernel_program;
+ isolate = Dart_CreateIsolateFromKernel(
+ script_uri, main, platform_kernel_buffer, platform_kernel_buffer_size,
+ flags, isolate_data, error);
} else {
isolate = Dart_CreateIsolate(
script_uri, main, isolate_snapshot_data, isolate_snapshot_instructions,
@@ -607,7 +640,12 @@
if (isolate == NULL) {
delete isolate_data;
} else {
- bool set_native_resolvers = (kernel_program || isolate_snapshot_data);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ bool set_native_resolvers =
+ (kernel_buffer != NULL) || (isolate_snapshot_data != NULL);
+#else
+ bool set_native_resolvers = isolate_snapshot_data != NULL;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
created_isolate =
IsolateSetupHelper(isolate, is_main_isolate, script_uri, package_root,
packages_config, set_native_resolvers,
@@ -616,7 +654,6 @@
int64_t end = Dart_TimelineGetMicros();
Dart_TimelineEvent("CreateIsolateAndSetupHelper", start, end,
Dart_Timeline_Event_Duration, 0, NULL, NULL);
-
return created_isolate;
}
@@ -871,6 +908,8 @@
Dart_EnterScope();
+ IsolateData* isolate_data =
+ reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
if (Options::gen_snapshot_kind() == kScript) {
if (vm_run_app_snapshot) {
Log::PrintErr("Cannot create a script snapshot from an app snapshot.\n");
@@ -880,7 +919,8 @@
}
if (Options::preview_dart_2()) {
Snapshot::GenerateKernel(Options::snapshot_filename(), script_name,
- flags.strong, Options::packages_file());
+ flags.strong,
+ isolate_data->resolved_packages_config());
} else {
Snapshot::GenerateScript(Options::snapshot_filename());
}
@@ -889,8 +929,6 @@
Dart_Handle root_lib = Dart_RootLibrary();
// Import the root library into the builtin library so that we can easily
// lookup the main entry point exported from the root library.
- IsolateData* isolate_data =
- reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
result = Dart_LibraryImportLibrary(isolate_data->builtin_lib(), root_lib,
Dart_Null());
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -1158,10 +1196,14 @@
// they might affect how the platform is loaded.
#if !defined(DART_PRECOMPILED_RUNTIME)
dfe.Init();
- void* application_kernel_binary = dfe.ReadScript(script_name);
- if (application_kernel_binary != NULL) {
+ uint8_t* application_kernel_buffer = NULL;
+ intptr_t application_kernel_buffer_size = 0;
+ dfe.ReadScript(script_name, &application_kernel_buffer,
+ &application_kernel_buffer_size);
+ if (application_kernel_buffer != NULL) {
// Since we loaded the script anyway, save it.
- dfe.set_application_kernel_binary(application_kernel_binary);
+ dfe.set_application_kernel_buffer(application_kernel_buffer,
+ application_kernel_buffer_size);
// Since we saw a dill file, it means we have to turn on all the
// preview_dart_2 options.
Options::SetPreviewDart2Options(&vm_options);
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index c5ce7a6..3dfe66c 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -71,6 +71,7 @@
vm_options->AddArgument("--strong");
vm_options->AddArgument("--reify-generic-functions");
vm_options->AddArgument("--limit-ints-to-64-bits");
+ vm_options->AddArgument("--sync-async");
}
bool OPTION_FIELD(preview_dart_2) = false;
diff --git a/runtime/bin/namespace_fuchsia.cc b/runtime/bin/namespace_fuchsia.cc
index 384aa9d..b84ccb4 100644
--- a/runtime/bin/namespace_fuchsia.cc
+++ b/runtime/bin/namespace_fuchsia.cc
@@ -41,15 +41,15 @@
}
~NamespaceImpl() {
+ NO_RETRY_EXPECTED(close(rootfd_));
+ free(cwd_);
+ NO_RETRY_EXPECTED(close(cwdfd_));
if (fdio_ns_ != NULL) {
zx_status_t status = fdio_ns_destroy(fdio_ns_);
if (status != ZX_OK) {
Log::PrintErr("fdio_ns_destroy: %s\n", zx_status_get_string(status));
}
}
- NO_RETRY_EXPECTED(close(rootfd_));
- free(cwd_);
- NO_RETRY_EXPECTED(close(cwdfd_));
}
intptr_t rootfd() const { return rootfd_; }
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 9d08b5d..b255370 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -172,7 +172,7 @@
Dart_EnterScope();
if (isolate_run_script_snapshot) {
- const uint8_t* payload;
+ uint8_t* payload;
intptr_t payload_length;
void* file = bin::DartUtils::OpenFile(script_uri, false);
bin::DartUtils::ReadFile(&payload, &payload_length, file);
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index 74c8bf4..3bb9e53 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -202,6 +202,33 @@
// This is done by WrappedX509 in secure_socket.cc.
_X509CertificateImpl();
+ Uint8List _cachedDer;
+ Uint8List get _der native "X509_Der";
+ Uint8List get der {
+ if (_cachedDer == null) {
+ _cachedDer = _der;
+ }
+ return _cachedDer;
+ }
+
+ String _cachedPem;
+ String get _pem native "X509_Pem";
+ String get pem {
+ if (_cachedPem == null) {
+ _cachedPem = _pem;
+ }
+ return _cachedPem;
+ }
+
+ Uint8List _cachedSha1;
+ Uint8List get _sha1 native "X509_Sha1";
+ Uint8List get sha1 {
+ if (_cachedSha1 == null) {
+ _cachedSha1 = _sha1;
+ }
+ return _cachedSha1;
+ }
+
String get subject native "X509_Subject";
String get issuer native "X509_Issuer";
DateTime get startValidity {
diff --git a/runtime/bin/secure_socket_unsupported.cc b/runtime/bin/secure_socket_unsupported.cc
index 7cd46d4..6a72909 100644
--- a/runtime/bin/secure_socket_unsupported.cc
+++ b/runtime/bin/secure_socket_unsupported.cc
@@ -125,6 +125,16 @@
"Secure Sockets unsupported on this platform"));
}
+void FUNCTION_NAME(X509_Der)(Dart_NativeArguments args) {
+ Dart_ThrowException(DartUtils::NewDartArgumentError(
+ "Secure Sockets unsupported on this platform"));
+}
+
+void FUNCTION_NAME(X509_Sha1)(Dart_NativeArguments args) {
+ Dart_ThrowException(DartUtils::NewDartArgumentError(
+ "Secure Sockets unsupported on this platform"));
+}
+
void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Secure Sockets unsupported on this platform"));
@@ -145,6 +155,11 @@
"Secure Sockets unsupported on this platform"));
}
+void FUNCTION_NAME(X509_Pem)(Dart_NativeArguments args) {
+ Dart_ThrowException(DartUtils::NewDartArgumentError(
+ "Secure Sockets unsupported on this platform"));
+}
+
class SSLFilter {
public:
static CObject* ProcessFilterRequest(const CObjectArray& request);
diff --git a/runtime/bin/security_context.cc b/runtime/bin/security_context.cc
index 56d99e4..dd92a40 100644
--- a/runtime/bin/security_context.cc
+++ b/runtime/bin/security_context.cc
@@ -647,6 +647,102 @@
return certificate;
}
+Dart_Handle X509Helper::GetDer(Dart_NativeArguments args) {
+ X509* certificate = GetX509Certificate(args);
+ // When the second argument is NULL, i2d_X509() returns the length of the
+ // DER encoded cert in bytes.
+ intptr_t length = i2d_X509(certificate, NULL);
+ Dart_Handle cert_handle = Dart_NewTypedData(Dart_TypedData_kUint8, length);
+ if (Dart_IsError(cert_handle)) {
+ Dart_PropagateError(cert_handle);
+ }
+ Dart_TypedData_Type typ;
+ void* dart_cert_bytes = NULL;
+ Dart_Handle status =
+ Dart_TypedDataAcquireData(cert_handle, &typ, &dart_cert_bytes, &length);
+ if (Dart_IsError(status)) {
+ Dart_PropagateError(status);
+ }
+
+ // When the the second argument points to a non-NULL buffer address,
+ // i2d_X509 fills that buffer with the DER encoded cert data and increments
+ // the buffer pointer.
+ unsigned char* tmp = static_cast<unsigned char*>(dart_cert_bytes);
+ const intptr_t written_length = i2d_X509(certificate, &tmp);
+ ASSERT(written_length <= length);
+ if (written_length < 0) {
+ Dart_TypedDataReleaseData(cert_handle);
+ SecureSocketUtils::ThrowIOException(
+ -1, "TlsException", "Failed to get certificate bytes", NULL);
+ // SecureSocketUtils::ThrowIOException() does not return.
+ }
+
+ status = Dart_TypedDataReleaseData(cert_handle);
+ if (Dart_IsError(status)) {
+ Dart_PropagateError(status);
+ }
+ return cert_handle;
+}
+
+Dart_Handle X509Helper::GetPem(Dart_NativeArguments args) {
+ X509* certificate = GetX509Certificate(args);
+ BIO* cert_bio = BIO_new(BIO_s_mem());
+ intptr_t status = PEM_write_bio_X509(cert_bio, certificate);
+ if (status == 0) {
+ BIO_free(cert_bio);
+ SecureSocketUtils::ThrowIOException(
+ -1, "TlsException", "Failed to write certificate to PEM", NULL);
+ // SecureSocketUtils::ThrowIOException() does not return.
+ }
+
+ BUF_MEM* mem = NULL;
+ BIO_get_mem_ptr(cert_bio, &mem);
+ Dart_Handle pem_string = Dart_NewStringFromUTF8(
+ reinterpret_cast<const uint8_t*>(mem->data), mem->length);
+ BIO_free(cert_bio);
+ if (Dart_IsError(pem_string)) {
+ Dart_PropagateError(pem_string);
+ }
+
+ return pem_string;
+}
+
+Dart_Handle X509Helper::GetSha1(Dart_NativeArguments args) {
+ unsigned char sha1_bytes[EVP_MAX_MD_SIZE];
+ X509* certificate = GetX509Certificate(args);
+ const EVP_MD* hash_type = EVP_sha1();
+
+ unsigned int sha1_size;
+ intptr_t status = X509_digest(certificate, hash_type, sha1_bytes, &sha1_size);
+ if (status == 0) {
+ SecureSocketUtils::ThrowIOException(
+ -1, "TlsException", "Failed to compute certificate's sha1", NULL);
+ // SecureSocketUtils::ThrowIOException() does not return.
+ }
+
+ Dart_Handle sha1_handle = Dart_NewTypedData(Dart_TypedData_kUint8, sha1_size);
+ if (Dart_IsError(sha1_handle)) {
+ Dart_PropagateError(sha1_handle);
+ }
+
+ Dart_TypedData_Type typ;
+ void* dart_sha1_bytes;
+ intptr_t length;
+ Dart_Handle result =
+ Dart_TypedDataAcquireData(sha1_handle, &typ, &dart_sha1_bytes, &length);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
+
+ memmove(dart_sha1_bytes, sha1_bytes, length);
+
+ result = Dart_TypedDataReleaseData(sha1_handle);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
+ return sha1_handle;
+}
+
Dart_Handle X509Helper::GetSubject(Dart_NativeArguments args) {
X509* certificate = GetX509Certificate(args);
X509_NAME* subject = X509_get_subject_name(certificate);
@@ -784,6 +880,18 @@
context->TrustBuiltinRoots();
}
+void FUNCTION_NAME(X509_Der)(Dart_NativeArguments args) {
+ Dart_SetReturnValue(args, X509Helper::GetDer(args));
+}
+
+void FUNCTION_NAME(X509_Pem)(Dart_NativeArguments args) {
+ Dart_SetReturnValue(args, X509Helper::GetPem(args));
+}
+
+void FUNCTION_NAME(X509_Sha1)(Dart_NativeArguments args) {
+ Dart_SetReturnValue(args, X509Helper::GetSha1(args));
+}
+
void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
Dart_SetReturnValue(args, X509Helper::GetSubject(args));
}
diff --git a/runtime/bin/security_context.h b/runtime/bin/security_context.h
index 968c550..8c37365 100644
--- a/runtime/bin/security_context.h
+++ b/runtime/bin/security_context.h
@@ -102,6 +102,9 @@
class X509Helper : public AllStatic {
public:
+ static Dart_Handle GetDer(Dart_NativeArguments args);
+ static Dart_Handle GetPem(Dart_NativeArguments args);
+ static Dart_Handle GetSha1(Dart_NativeArguments args);
static Dart_Handle GetSubject(Dart_NativeArguments args);
static Dart_Handle GetIssuer(Dart_NativeArguments args);
static Dart_Handle GetStartValidity(Dart_NativeArguments args);
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
index 8dbb43e..73f0fa8 100644
--- a/runtime/bin/security_context_macos.cc
+++ b/runtime/bin/security_context_macos.cc
@@ -58,14 +58,20 @@
if (cert == NULL) {
return NULL;
}
- unsigned char* deb_cert = NULL;
- int length = i2d_X509(cert, &deb_cert);
+ int length = i2d_X509(cert, NULL);
if (length < 0) {
return 0;
}
- ASSERT(deb_cert != NULL);
- ScopedCFDataRef cert_buf(
- CFDataCreateWithBytesNoCopy(NULL, deb_cert, length, kCFAllocatorNull));
+ auto deb_cert = std::make_unique<unsigned char[]>(length);
+ unsigned char* temp = deb_cert.get();
+ if (i2d_X509(cert, &temp) != length) {
+ return NULL;
+ }
+ // TODO(bkonyi): we create a copy of the deb_cert here since it's unclear
+ // whether or not SecCertificateCreateWithData takes ownership of the CFData.
+ // Implementation here:
+ // https://opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55050.2/lib/SecCertificate.cpp.auto.html
+ ScopedCFDataRef cert_buf(CFDataCreate(NULL, deb_cert.get(), length));
SecCertificateRef auth_cert =
SecCertificateCreateWithData(NULL, cert_buf.get());
if (auth_cert == NULL) {
diff --git a/runtime/configs.gni b/runtime/configs.gni
new file mode 100644
index 0000000..648083d
--- /dev/null
+++ b/runtime/configs.gni
@@ -0,0 +1,247 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+_dart_runtime = get_path_info("../runtime", "abspath")
+
+_base_config = [
+ "$_dart_runtime:dart_arch_config",
+ "$_dart_runtime:dart_config",
+ "$_dart_runtime:dart_os_config",
+]
+
+_base_fuchsia_config = [
+ "$_dart_runtime:dart_arch_config",
+ "$_dart_runtime:dart_config",
+ "$_dart_runtime:dart_os_fuchsia_config",
+]
+
+_jit_config = _base_config + [
+ "$_dart_runtime:dart_maybe_interpreter_config",
+ "$_dart_runtime:dart_maybe_product_config",
+ ]
+
+_jit_product_config = _base_config + [
+ "$_dart_runtime:dart_maybe_interpreter_config",
+ "$_dart_runtime:dart_product_config",
+ ]
+
+_jit_interpreter_config = _base_config + [
+ "$_dart_runtime:dart_interpreter_config",
+ "$_dart_runtime:dart_maybe_product_config",
+ ]
+
+_jit_product_interpreter_config = _base_config + [
+ "$_dart_runtime:dart_interpreter_config",
+ "$_dart_runtime:dart_product_config",
+ ]
+
+_precompiled_runtime_config =
+ _base_config + [
+ "$_dart_runtime:dart_maybe_product_config",
+ "$_dart_runtime:dart_precompiled_runtime_config",
+ ]
+
+_precompiled_runtime_product_config =
+ _base_config + [
+ "$_dart_runtime:dart_precompiled_runtime_config",
+ "$_dart_runtime:dart_product_config",
+ ]
+
+_precompiler_config = _base_config + [
+ "$_dart_runtime:dart_maybe_product_config",
+ "$_dart_runtime:dart_precompiler_config",
+ ]
+
+_precompiler_product_config = _base_config + [
+ "$_dart_runtime:dart_product_config",
+ "$_dart_runtime:dart_precompiler_config",
+ ]
+
+_nosnapshot_with_precompiler_config =
+ _base_config + [
+ "$_dart_runtime:dart_maybe_product_config",
+ "$_dart_runtime:dart_nosnapshot_config",
+ "$_dart_runtime:dart_precompiler_config",
+ ]
+
+_nosnapshot_with_precompiler_product_config =
+ _base_config + [
+ "$_dart_runtime:dart_product_config",
+ "$_dart_runtime:dart_nosnapshot_config",
+ "$_dart_runtime:dart_precompiler_config",
+ ]
+
+_nosnapshot_with_precompiler_fuchsia_config =
+ _base_fuchsia_config + [
+ "$_dart_runtime:dart_maybe_product_config",
+ "$_dart_runtime:dart_nosnapshot_config",
+ "$_dart_runtime:dart_precompiler_config",
+ ]
+
+_nosnapshot_with_precompiler_product_fuchsia_config =
+ _base_fuchsia_config + [
+ "$_dart_runtime:dart_product_config",
+ "$_dart_runtime:dart_nosnapshot_config",
+ "$_dart_runtime:dart_precompiler_config",
+ ]
+
+_all_configs = [
+ {
+ suffix = "_jit"
+ configs = _jit_config
+ snapshot = true
+ },
+ {
+ suffix = "_jit_product"
+ configs = _jit_product_config
+ snapshot = true
+ },
+ {
+ suffix = "_precompiled_runtime"
+ configs = _precompiled_runtime_config
+ snapshot = true
+ },
+ {
+ suffix = "_precompiled_runtime_product"
+ configs = _precompiled_runtime_product_config
+ snapshot = true
+ },
+ {
+ suffix = "_with_precompiler"
+ configs = _precompiler_config
+ snapshot = true
+ },
+ {
+ suffix = "_with_precompiler_product"
+ configs = _precompiler_product_config
+ snapshot = true
+ },
+ {
+ suffix = "_nosnapshot_with_precompiler"
+ configs = _nosnapshot_with_precompiler_config
+ snapshot = false
+ },
+ {
+ suffix = "_nosnapshot_with_precompiler_product"
+ configs = _nosnapshot_with_precompiler_product_config
+ snapshot = false
+ },
+ {
+ suffix = "_nosnapshot_with_precompiler_fuchsia"
+ configs = _nosnapshot_with_precompiler_fuchsia_config
+ snapshot = false
+ },
+ {
+ suffix = "_nosnapshot_with_precompiler_product_fuchsia"
+ configs = _nosnapshot_with_precompiler_product_fuchsia_config
+ snapshot = false
+ },
+]
+
+# The interpreter is not currently needed on Windows.
+if (!is_win) {
+ _all_configs += [
+ {
+ suffix = "_jit_interpreter"
+ configs = _jit_interpreter_config
+ snapshot = true
+ },
+ {
+ suffix = "_jit_product_interpreter"
+ configs = _jit_product_interpreter_config
+ snapshot = true
+ },
+ ]
+}
+
+# This template creates a target for each of the configurations listed above.
+# For example:
+#
+# library_for_all_configs("libfoo") {
+# target_type = "source_set"
+# sources = [ "foo.c" ]
+# configurable_deps [ ":libbar" ]
+# }
+#
+# will make a source_set target for libfoo_jit, libfoo_jit_product, etc. that
+# depends on libbar_jit, libbar_jit_product etc. respectively.
+#
+# Parameters
+#
+# target_type (required):
+# The target declaration or template to repeat for each configuration.
+#
+# configurable_deps (optional):
+# Dependencies of this target, which are themselves generated by
+# library_for_all_configs(). The listed dependencies will be suffixed with
+# a string that matches the configuration.
+#
+# extra_deps (optional):
+# Regular additional deps that don't receive special treatment.
+#
+# extra_configs (optional):
+# Any configs needed in addition to the ones above.
+#
+# snapshot_sources (optional):
+# Additional sources to include when the configuration has a snapshot.
+#
+# nosnapshot_sources (optional):
+# Additional sources to include when the configuration does not have a
+# snapshot (that is, one of the "nosnapshot" configurations above).
+#
+# nosnapshot_deps (optional):
+# Similar to nosnapshot_sources, but for deps.
+template("library_for_all_configs") {
+ assert(defined(invoker.target_type))
+ extra_configs = []
+ if (defined(invoker.extra_configs)) {
+ extra_configs += invoker.extra_configs
+ }
+ configurable_deps = []
+ if (defined(invoker.configurable_deps)) {
+ configurable_deps += invoker.configurable_deps
+ }
+ extra_deps = []
+ if (defined(invoker.extra_deps)) {
+ extra_deps += invoker.extra_deps
+ }
+ not_needed(invoker,
+ [
+ "snapshot_sources",
+ "nosnapshot_sources",
+ "nosnapshot_deps",
+ ])
+ foreach(conf, _all_configs) {
+ target(invoker.target_type, "${target_name}${conf.suffix}") {
+ forward_variables_from(invoker,
+ "*",
+ [
+ "extra_configs",
+ "extra_deps",
+ "configurable_deps",
+ ])
+ if (is_fuchsia) {
+ configs -= [ "//build/config:symbol_visibility_hidden" ]
+ }
+ configs += conf.configs + extra_configs
+ configured_deps = []
+ foreach(dep, configurable_deps) {
+ configured_deps += [ "${dep}${conf.suffix}" ]
+ }
+ deps = configured_deps + extra_deps
+ if (conf.snapshot) {
+ if (defined(invoker.snapshot_sources)) {
+ sources += snapshot_sources
+ }
+ } else {
+ if (defined(invoker.nosnapshot_sources)) {
+ sources += nosnapshot_sources
+ }
+ if (defined(nosnapshot_deps)) {
+ deps += nosnapshot_deps
+ }
+ }
+ }
+ }
+}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index b3fdd96..e287914 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -571,6 +571,7 @@
bool reify_generic_functions;
bool strong;
bool load_vmservice_library;
+ bool sync_async;
} Dart_IsolateFlags;
/**
@@ -716,7 +717,7 @@
*/
typedef void* (*Dart_FileOpenCallback)(const char* name, bool write);
-typedef void (*Dart_FileReadCallback)(const uint8_t** data,
+typedef void (*Dart_FileReadCallback)(uint8_t** data,
intptr_t* file_length,
void* stream);
@@ -893,12 +894,14 @@
*
* \return The new isolate on success, or NULL if isolate creation failed.
*/
-DART_EXPORT Dart_Isolate Dart_CreateIsolateFromKernel(const char* script_uri,
- const char* main,
- void* kernel_program,
- Dart_IsolateFlags* flags,
- void* callback_data,
- char** error);
+DART_EXPORT Dart_Isolate
+Dart_CreateIsolateFromKernel(const char* script_uri,
+ const char* main,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size,
+ Dart_IsolateFlags* flags,
+ void* callback_data,
+ char** error);
/**
* Shuts down the current isolate. After this call, the current isolate is NULL.
* Any current scopes created by Dart_EnterScope will be exited. Invokes the
@@ -2929,21 +2932,6 @@
Dart_LoadScriptFromKernel(const uint8_t* kernel_buffer, intptr_t kernel_size);
/**
- * Constructs an in-memory kernel program form a binary.
- *
- * \param buffer The start of a memory buffer containing the binary format.
- * \param buffer_len The length of the memory buffer.
- * \param callback If not NULL, is called to when buffer is no longer needed.
- * If it is NULL, then free() is used to free buffer.
- *
- * \return kernel_program The `dart::kernel::Program` object.
- */
-typedef void (*Dart_ReleaseBufferCallback)(uint8_t* buffer);
-DART_EXPORT void* Dart_ReadKernelBinary(const uint8_t* buffer,
- intptr_t buffer_len,
- Dart_ReleaseBufferCallback callback);
-
-/**
* Gets the library for the root script for the current isolate.
*
* If the root script has not yet been set for the current isolate,
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 73ea588..e7c2a2f 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -175,6 +175,13 @@
@patch
class NoSuchMethodError {
+ // Deprecated members to be removed.
+ final Object _receiver;
+ final Symbol _memberName;
+ final List _arguments;
+ final Map<Symbol, dynamic> _namedArguments;
+ final List _existingArgumentNames;
+
// TODO(regis): Move _receiver declaration here:
// final Object _receiver;
final _InvocationMirror _invocation;
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index 46bc649..2d9b9c4 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -41,6 +41,7 @@
final List _argumentsDescriptor;
final List _arguments;
final bool _isSuperInvocation;
+ final int _delayedTypeArgumentsLen;
// External representation of the invocation mirror; populated on demand.
Symbol _memberName;
@@ -79,16 +80,20 @@
return _memberName;
}
+ int get _typeArgsLen {
+ int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
+ return typeArgsLen == 0 ? _delayedTypeArgumentsLen : typeArgsLen;
+ }
+
List<Type> get typeArguments {
if (_typeArguments == null) {
- int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
- if (typeArgsLen == 0) {
+ if (_typeArgsLen == 0) {
return _typeArguments = const <Type>[];
}
// A TypeArguments object does not have a corresponding Dart class and
// cannot be accessed as an array in Dart. Therefore, we need a native
// call to unpack the individual types into a list.
- _typeArguments = _unpackTypeArguments(_arguments[0], typeArgsLen);
+ _typeArguments = _unpackTypeArguments(_arguments[0], _typeArgsLen);
}
return _typeArguments;
}
@@ -106,7 +111,7 @@
return _positionalArguments = const [];
}
// Exclude receiver and type args in the returned list.
- int receiverIndex = _argumentsDescriptor[_TYPE_ARGS_LEN] > 0 ? 1 : 0;
+ int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
_positionalArguments = new _ImmutableList._from(
_arguments, receiverIndex + 1, numPositionalArguments);
}
@@ -121,7 +126,7 @@
if (numNamedArguments == 0) {
return _namedArguments = const {};
}
- int receiverIndex = _argumentsDescriptor[_TYPE_ARGS_LEN] > 0 ? 1 : 0;
+ int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
_namedArguments = new Map<Symbol, dynamic>();
for (int i = 0; i < numNamedArguments; i++) {
int namedEntryIndex = _FIRST_NAMED_ENTRY + 2 * i;
@@ -164,10 +169,12 @@
}
_InvocationMirror(this._functionName, this._argumentsDescriptor,
- this._arguments, this._isSuperInvocation, this._type);
+ this._arguments, this._isSuperInvocation, this._type,
+ [this._delayedTypeArgumentsLen = 0]);
_InvocationMirror._withoutType(this._functionName, this._typeArguments,
- this._positionalArguments, this._namedArguments, this._isSuperInvocation);
+ this._positionalArguments, this._namedArguments, this._isSuperInvocation,
+ [this._delayedTypeArgumentsLen = 0]);
static _allocateInvocationMirror(String functionName,
List argumentsDescriptor, List arguments, bool isSuperInvocation,
@@ -175,4 +182,19 @@
return new _InvocationMirror(
functionName, argumentsDescriptor, arguments, isSuperInvocation, type);
}
+
+ // This factory is used when creating an `Invocation` for a closure call which
+ // may have delayed type arguments. In that case, the arguments descriptor will
+ // indicate 0 type arguments, but the actual number of type arguments are
+ // passed in `delayedTypeArgumentsLen`. If any type arguments are available,
+ // the type arguments vector will be the first entry in `arguments`.
+ static _allocateInvocationMirrorForClosure(
+ String functionName,
+ List argumentsDescriptor,
+ List arguments,
+ int type,
+ int delayedTypeArgumentsLen) {
+ return new _InvocationMirror(functionName, argumentsDescriptor, arguments,
+ false, type, delayedTypeArgumentsLen);
+ }
}
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 5e29999..f4f53b2 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -357,10 +357,11 @@
// If we were passed a value then override the default flags state for
// checked mode.
if (!checked.IsNull()) {
- bool val = checked.value();
+ bool is_checked = checked.value();
Dart_IsolateFlags* flags = state->isolate_flags();
- flags->enable_asserts = val;
- flags->enable_type_checks = val;
+ flags->enable_asserts = is_checked;
+ // Do not enable type checks in strong mode.
+ flags->enable_type_checks = is_checked && !flags->strong;
}
ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
diff --git a/runtime/observatory/tests/service/async_generator_breakpoint_test.dart b/runtime/observatory/tests/service/async_generator_breakpoint_test.dart
index 6781af7..d96c822 100644
--- a/runtime/observatory/tests/service/async_generator_breakpoint_test.dart
+++ b/runtime/observatory/tests/service/async_generator_breakpoint_test.dart
@@ -1,8 +1,8 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug --stacktrace-every=55 --stress-async-stacks
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug --no-sync-async
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug --stacktrace-every=55 --stress-async-stacks --no-sync-async
import 'dart:async';
import 'package:observatory/service_io.dart';
@@ -69,7 +69,8 @@
var hits = [];
- isolate.rootLibrary.evaluate('testerReady = true;').then((result) {
+ isolate.rootLibrary.evaluate('testerReady = true').then((result) {
+ print(result);
expect((result as Instance).valueAsString, equals('true'));
});
diff --git a/runtime/observatory/tests/service/async_single_step_exception_test.dart b/runtime/observatory/tests/service/async_single_step_exception_test.dart
index 6794fb9..c026f4a 100644
--- a/runtime/observatory/tests/service/async_single_step_exception_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_exception_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger --no-sync-async
import 'dart:developer';
import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/bad_reload_test.dart b/runtime/observatory/tests/service/bad_reload_test.dart
index 8e9aed7..23927e9 100644
--- a/runtime/observatory/tests/service/bad_reload_test.dart
+++ b/runtime/observatory/tests/service/bad_reload_test.dart
@@ -72,9 +72,11 @@
expect(reasonForCancelling['type'], equals('ReasonForCancelling'));
expect(reasonForCancelling['message'], contains('library_isnt_here_man'));
- // Invoke test in v2.
- String v2 = await invokeTest(spawnedIsolate);
- expect(v2, 'apple');
+ // TODO(32341): enable in Dart 2
+ if (!Platform.executableArguments.contains("--preview_dart_2")) {
+ String v2 = await invokeTest(spawnedIsolate);
+ expect(v2, 'apple');
+ }
}
];
diff --git a/runtime/observatory/tests/service/debugger_inspect_test.dart b/runtime/observatory/tests/service/debugger_inspect_test.dart
index c52c42f..4f8f680 100644
--- a/runtime/observatory/tests/service/debugger_inspect_test.dart
+++ b/runtime/observatory/tests/service/debugger_inspect_test.dart
@@ -32,7 +32,7 @@
});
// Start listening for events first.
- await isolate.rootLibrary.evaluate('testeeDo();');
+ await isolate.rootLibrary.evaluate('testeeDo()');
return completer.future;
},
];
diff --git a/runtime/observatory/tests/service/evaluate_activation_test.dart b/runtime/observatory/tests/service/evaluate_activation_test.dart
index fc87190..cb352cd 100644
--- a/runtime/observatory/tests/service/evaluate_activation_test.dart
+++ b/runtime/observatory/tests/service/evaluate_activation_test.dart
@@ -114,7 +114,7 @@
}
});
- var result = await rootLib.evaluate('new C().method(3);');
+ var result = await rootLib.evaluate('new C().method(3)');
print("Result $result");
expect(hitBreakpoint, isTrue);
}
@@ -163,7 +163,7 @@
}
});
- var result = await rootLib.evaluate('C.method2(3);');
+ var result = await rootLib.evaluate('C.method2(3)');
print("Result $result");
expect(hitBreakpoint, isTrue);
}
@@ -204,7 +204,7 @@
}
});
- var result = await rootLib.evaluate('new C().method3(3);');
+ var result = await rootLib.evaluate('new C().method3(3)');
print("Result $result");
expect(hitBreakpoint, isTrue);
}
diff --git a/runtime/observatory/tests/service/evaluate_class_type_parameters_test.dart b/runtime/observatory/tests/service/evaluate_class_type_parameters_test.dart
new file mode 100644
index 0000000..0909420
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_class_type_parameters_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+class A<T> {
+ void foo() {
+ debugger();
+ }
+}
+
+class B<S> extends A<int> {
+ void bar() {
+ debugger();
+ }
+}
+
+testFunction() {
+ var v = new B<String>();
+ v.bar();
+ v.foo();
+}
+
+var tests = <IsolateTest>[
+ hasStoppedAtBreakpoint,
+ (Isolate isolate) async {
+ // Make sure we are in the right place.
+ var stack = await isolate.getStack();
+ var topFrame = 0;
+ expect(stack.type, equals('Stack'));
+ expect(await stack['frames'][topFrame].location.getLine(), 20);
+
+ Instance result = await isolate.evalFrame(topFrame, '"\$S"');
+ print(result);
+ expect(result.valueAsString, equals("String"));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ (Isolate isolate) async {
+ // Make sure we are in the right place.
+ var stack = await isolate.getStack();
+ var topFrame = 0;
+ expect(stack.type, equals('Stack'));
+ expect(await stack['frames'][topFrame].location.getLine(), 14);
+
+ Instance result = await isolate.evalFrame(topFrame, '"\$T"');
+ print(result);
+ expect(result.valueAsString, equals("int"));
+ },
+ resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart b/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart
new file mode 100644
index 0000000..1ee01db
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+topLevel<S>() {
+ debugger();
+
+ void inner1<T>() {
+ debugger();
+ }
+
+ inner1<int>();
+
+ void inner2() {
+ debugger();
+ }
+
+ inner2();
+}
+
+class A {
+ foo<T>() {
+ debugger();
+ }
+}
+
+void testMain() {
+ topLevel<String>();
+ (new A()).foo<int>();
+}
+
+var tests = <IsolateTest>[
+ hasStoppedAtBreakpoint,
+ (Isolate isolate) async {
+ // Make sure we are in the right place.
+ var stack = await isolate.getStack();
+ var topFrame = 0;
+ expect(stack.type, equals('Stack'));
+ expect(await stack['frames'][topFrame].location.getLine(), 14);
+
+ Instance result = await isolate.evalFrame(topFrame, "S.toString()");
+ print(result);
+ expect(result.valueAsString, equals("String"));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ (Isolate isolate) async {
+ // Make sure we are in the right place.
+ var stack = await isolate.getStack();
+ var topFrame = 0;
+ expect(stack.type, equals('Stack'));
+ expect(await stack['frames'][topFrame].location.getLine(), 16);
+
+ Instance result = await isolate.evalFrame(topFrame, "T.toString()");
+ print(result);
+ expect(result.valueAsString, equals("int"));
+
+ result = await isolate.evalFrame(topFrame, "S.toString()");
+ print(result);
+ expect(result.valueAsString, equals("String"));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ (Isolate isolate) async {
+ // Make sure we are in the right place.
+ var stack = await isolate.getStack();
+ var topFrame = 0;
+ expect(stack.type, equals('Stack'));
+ expect(await stack['frames'][topFrame].location.getLine(), 22);
+
+ Instance result = await isolate.evalFrame(topFrame, "S.toString()");
+ print(result);
+ expect(result.valueAsString, equals("String"));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ (Isolate isolate) async {
+ // Make sure we are in the right place.
+ var stack = await isolate.getStack();
+ var topFrame = 0;
+ expect(stack.type, equals('Stack'));
+ expect(await stack['frames'][topFrame].location.getLine(), 30);
+
+ Instance result = await isolate.evalFrame(topFrame, "T.toString()");
+ print(result);
+ expect(result.valueAsString, equals("int"));
+ },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
index c458396..6211574 100644
--- a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
@@ -40,7 +40,7 @@
// Expect a simple path through variable x instead of long path filled
// with VM objects
(Isolate isolate) async {
- var target1 = await eval(isolate, 'x;');
+ var target1 = await eval(isolate, 'x');
var params = {
'targetId': target1['id'],
'limit': 100,
@@ -56,7 +56,7 @@
// Expect a simple path through variable fn instead of long path filled
// with VM objects
(Isolate isolate) async {
- var target2 = await eval(isolate, 'fn;');
+ var target2 = await eval(isolate, 'fn');
var params = {
'targetId': target2['id'],
'limit': 100,
diff --git a/runtime/observatory/tests/service/positive_token_pos_test.dart b/runtime/observatory/tests/service/positive_token_pos_test.dart
index ceb42fc..375b676 100644
--- a/runtime/observatory/tests/service/positive_token_pos_test.dart
+++ b/runtime/observatory/tests/service/positive_token_pos_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --no-sync-async
import 'dart:developer';
import 'package:observatory/service_io.dart';
diff --git a/runtime/observatory/tests/service/rewind_test.dart b/runtime/observatory/tests/service/rewind_test.dart
index 7f0d590..b89fa2c8 100644
--- a/runtime/observatory/tests/service/rewind_test.dart
+++ b/runtime/observatory/tests/service/rewind_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override
+// VMOptions=--error_on_bad_type --error_on_bad_override --no-sync-async
import 'dart:developer';
import 'package:observatory/service_io.dart';
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 5a699c0..8a40809 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -43,6 +43,7 @@
# Kernel version of tests
[ $compiler != dartk ]
add_breakpoint_rpc_kernel_test: SkipByDesign # kernel specific version of add_breakpoint_rpc_test
+evaluate_function_type_parameters_test: SkipByDesign # only supported in kernel
[ $compiler == precompiler ]
*: Skip # Issue 24651
@@ -73,6 +74,9 @@
[ $mode == debug && ($arch == simarm || $arch == simarm64) ]
*: SkipSlow
+[ !$strong && ($compiler == dartk || $compiler == dartkp) ]
+*: Skip
+
[ ($compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index c9b5f1d..8003fb4 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -11,7 +11,6 @@
async_star_step_out_test: RuntimeError # Issue 29158, Async debugging
async_step_out_test: RuntimeError # Issue 29158, Async debugging
awaiter_async_stack_contents_test: RuntimeError # Issue 29158, Async debugging
-eval_internal_class_test: RuntimeError
evaluate_activation_in_method_class_test: RuntimeError
evaluate_activation_test/instance: RuntimeError
evaluate_activation_test/scope: RuntimeError
@@ -31,7 +30,6 @@
complex_reload_test: RuntimeError
[ $arch == simdbc64 && $compiler == dartk ]
-coverage_optimized_function_test: Crash # Please triage
get_cpu_profile_timeline_rpc_test: Pass, RuntimeError # http://dartbug.com/31794
pause_on_unhandled_async_exceptions_test: RuntimeError, Timeout # Issue 31765
@@ -109,18 +107,40 @@
async_single_step_exception_test: RuntimeError
[ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+add_breakpoint_rpc_kernel_test: RuntimeError # Issue #33087
async_generator_breakpoint_test: Pass, RuntimeError
bad_reload_test: Skip # Times out on sim architectures, also RuntimeError.
+break_on_activation_test: RuntimeError # Issue #33087
complex_reload_test: Skip # Times out on sim architectures, also RuntimeError.
coverage_leaf_function_test: RuntimeError # Please triage.
coverage_optimized_function_test: RuntimeError # Please triage.
+debugger_inspect_test: RuntimeError, Timeout # Issue #33087
+developer_service_get_isolate_id_test: RuntimeError # Issue #33087
+eval_internal_class_test: RuntimeError # Issue #33087
+eval_test: RuntimeError # Issue #33087
+evaluate_activation_test/none: RuntimeError # Issue #33087
+evaluate_async_closure_test: RuntimeError # Issue #33087
+evaluate_class_type_parameters_test: RuntimeError # Issue 33087
+evaluate_function_type_parameters_test: RuntimeError # Issue 33087
+evaluate_in_async_activation_test: RuntimeError # Issue #33087
+evaluate_in_async_star_activation_test: RuntimeError # Issue #33087
+evaluate_in_frame_rpc_test: RuntimeError # Issue #33087
+evaluate_in_frame_with_scope_test: RuntimeError # Issue #33087
+evaluate_with_scope_test: RuntimeError # Issue #33087
+get_instances_rpc_test: RuntimeError # Issue #33087
get_object_rpc_test: RuntimeError # Please triage.
+get_retaining_path_rpc_test: RuntimeError # Issue #33087
get_source_report_test: RuntimeError # Please triage.
+get_user_level_retaining_path_rpc_test: RuntimeError # Issue #33087
+instance_field_order_rpc_test: RuntimeError # Issue #33087
+pause_on_exceptions_test: RuntimeError, Timeout # Issue #33087
positive_token_pos_test: Pass, RuntimeError
reload_sources_test: Skip # Times out.
+rewind_optimized_out_test: RuntimeError # Issue #33087
rewind_test: Pass, RuntimeError
set_name_rpc_test: RuntimeError # Please triage.
unused_changes_in_last_reload_test: Skip # Times out on sim architectures.
+valid_source_locations_test: Pass, Slow, Timeout # Issue 33087
[ $compiler == fasta && $strong ]
add_breakpoint_rpc_test: CompileTimeError
diff --git a/runtime/platform/BUILD.gn b/runtime/platform/BUILD.gn
index 32a9339..6f2cdf9 100644
--- a/runtime/platform/BUILD.gn
+++ b/runtime/platform/BUILD.gn
@@ -2,53 +2,12 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
+import("../configs.gni")
import("platform_sources.gni")
-template("build_libdart_platform") {
- extra_configs = []
- if (defined(invoker.extra_configs)) {
- extra_configs += invoker.extra_configs
- }
- static_library(target_name) {
- configs += [
- "..:dart_arch_config",
- "..:dart_config",
- ] + extra_configs
- if (is_fuchsia) {
- configs -= [ "//build/config:symbol_visibility_hidden" ]
- }
- public_configs = [ "../vm:libdart_vm_config" ]
-
- sources = platform_sources
-
- include_dirs = [ ".." ]
- }
-}
-
-build_libdart_platform("libdart_platform") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_platform("libdart_platform_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_platform("libdart_platform_fuchsia") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_os_fuchsia_config",
- ]
-}
-
-build_libdart_platform("libdart_platform_product_fuchsia") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_os_fuchsia_config",
- ]
+library_for_all_configs("libdart_platform") {
+ target_type = "static_library"
+ public_configs = [ "../vm:libdart_vm_config" ]
+ sources = platform_sources
+ include_dirs = [ ".." ]
}
diff --git a/runtime/platform/growable_array.h b/runtime/platform/growable_array.h
index 32ffcc4..f6c0598 100644
--- a/runtime/platform/growable_array.h
+++ b/runtime/platform/growable_array.h
@@ -70,6 +70,16 @@
}
}
+ void EnsureLength(intptr_t new_length, const T& default_value) {
+ const intptr_t old_length = length_;
+ if (old_length < new_length) {
+ Resize(new_length);
+ for (intptr_t i = old_length; i < new_length; ++i) {
+ (*this)[i] = default_value;
+ }
+ }
+ }
+
const T& At(intptr_t index) const { return operator[](index); }
T& Last() const {
diff --git a/runtime/tests/vm/dart/appjit_test.dart b/runtime/tests/vm/dart/appjit_test.dart
new file mode 100644
index 0000000..6fbe998
--- /dev/null
+++ b/runtime/tests/vm/dart/appjit_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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=100
+
+// Verify that app-jit snapshot contains dependencies between classes and CHA
+// optimized code.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as p;
+
+class Result {
+ final String cmdline;
+ final ProcessResult processResult;
+
+ Result(this.cmdline, this.processResult);
+}
+
+void reportError(Result result, String msg) {
+ print('running ${result.cmdline}:');
+ if (result.processResult.stdout.isNotEmpty) {
+ print('''
+
+Command stdout:
+${result.processResult.stdout}''');
+ }
+
+ if (result.processResult.stderr.isNotEmpty) {
+ print('''
+
+Command stderr:
+${result.processResult.stderr}''');
+ }
+
+ Expect.fail(msg);
+}
+
+void expectOutput(String what, Result result) {
+ if (result.processResult.stdout.trim() != what) {
+ reportError(result, 'Expected test to print \'${what}\' to stdout');
+ }
+}
+
+Future<Result> runDartBinary(String prefix, List<String> arguments) async {
+ final binary = Platform.executable;
+ final actualArguments = <String>[]
+ ..addAll(Platform.executableArguments)
+ ..addAll(arguments);
+ final processResult = await Process.run(binary, actualArguments);
+ final result = new Result(
+ '[$prefix] ${binary} ${actualArguments.join(' ')}', processResult);
+ if (result.processResult.exitCode != 0) {
+ reportError(result,
+ '[$prefix] Process finished with non-zero exit code ${result.processResult.exitCode}');
+ }
+ return result;
+}
+
+const snapshotName = 'app.jit';
+
+void main() async {
+ final Directory temp = Directory.systemTemp.createTempSync();
+ final snapshotPath = p.join(temp.path, 'app.jit');
+ final testPath = Platform.script
+ .toFilePath()
+ .replaceAll(new RegExp(r'_test.dart$'), '_test_body.dart');
+
+ await temp.create();
+ try {
+ final trainingResult = await runDartBinary('TRAINING RUN', [
+ '--snapshot=$snapshotPath',
+ '--snapshot-kind=app-jit',
+ testPath,
+ '--train'
+ ]);
+ expectOutput("OK(Trained)", trainingResult);
+ final runResult = await runDartBinary('RUN FROM SNAPSHOT', [snapshotPath]);
+ expectOutput("OK(Run)", runResult);
+ } finally {
+ await temp.delete(recursive: true);
+ }
+}
diff --git a/runtime/tests/vm/dart/appjit_test_body.dart b/runtime/tests/vm/dart/appjit_test_body.dart
new file mode 100644
index 0000000..c59f720
--- /dev/null
+++ b/runtime/tests/vm/dart/appjit_test_body.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that app-jit snapshot contains dependencies between classes and CHA
+// optimized code.
+
+import 'package:expect/expect.dart';
+
+class A {
+ void getMyName() => getMyNameImpl();
+
+ void getMyNameImpl() => "A";
+}
+
+class B extends A {
+ void getMyNameImpl() => "B";
+}
+
+final Function makeA = () => new A();
+final Function makeB = () => new B();
+
+void optimizeGetMyName(dynamic obj) {
+ for (var i = 0; i < 100; i++) {
+ obj.getMyName();
+ }
+ Expect.equals("A", obj.getMyName());
+}
+
+void main(List<String> args) {
+ final isTraining = args.contains("--train");
+ final dynamic obj = (isTraining ? makeA : makeB)();
+ if (isTraining) {
+ for (var i = 0; i < 10; i++) {
+ optimizeGetMyName(obj);
+ }
+ Expect.equals('A', obj.getMyName());
+ print('OK(Trained)');
+ } else {
+ Expect.equals('B', obj.getMyName());
+ print('OK(Run)');
+ }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 6e45883..d07500e 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -54,6 +54,7 @@
[ $compiler != dartk ]
cc/IsolateReload_KernelIncrementalCompile: SkipByDesign
cc/IsolateReload_KernelIncrementalCompileAppAndLib: SkipByDesign
+cc/IsolateReload_KernelIncrementalCompileExpression: SkipByDesign
cc/IsolateReload_KernelIncrementalCompileGenerics: SkipByDesign
cc/Mixin_PrivateSuperResolution: Skip
cc/Mixin_PrivateSuperResolutionCrossLibraryShouldFail: Skip
@@ -146,8 +147,7 @@
[ $compiler == dartk && $runtime == vm ]
cc/Class_ComputeEndTokenPos: Crash
-cc/DartAPI_IsolateShutdownRunDartCode: Skip # Flaky
-cc/DartAPI_LoadLibrary: Crash # Issue 33048.
+cc/DartAPI_LoadLibrary: Fail, Crash # Issue 33048.
cc/DebuggerAPI_BreakpointStubPatching: Fail
cc/DebuggerAPI_GetClosureInfo: Fail
cc/DebuggerAPI_InterruptIsolate: SkipSlow
@@ -284,6 +284,9 @@
cc/RegExp_TwoByteString: Skip # TODO(vegorov) These tests don't seem to work if FLAG_interpret_irregexp is switched on by default because they attempt to call regexp functions directly instead of going through JSSyntaxRegExp_ExecuteMatch.
cc/RegenerateAllocStubs: Skip # This test is meaningless for DBC as allocation stubs are not used.
+[ $arch == simdbc64 || $builder_tag == optimization_counter_threshold || $compiler != none ]
+dart/appjit_test: Skip
+
[ $compiler == dart2analyzer || $compiler == dart2js ]
dart/data_uri*test: Skip # Data uri's not supported by dart2js or the analyzer.
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 69e3168..dd24564 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -30,6 +30,7 @@
import("../lib/profiler_sources.gni")
import("../lib/typed_data_sources.gni")
import("../lib/vmservice_sources.gni")
+import("../configs.gni")
import("../runtime_args.gni")
import("compiler/compiler_sources.gni")
import("vm_sources.gni")
@@ -54,128 +55,28 @@
}
}
-template("build_libdart_vm") {
- extra_configs = []
- if (defined(invoker.extra_configs)) {
- extra_configs += invoker.extra_configs
+library_for_all_configs("libdart_vm") {
+ target_type = "source_set"
+ if (is_fuchsia) {
+ extra_deps = [
+ # TODO(US-399): Remove time_service specific code when it is no longer
+ # necessary.
+ "//garnet/public/lib/app/cpp",
+ "//garnet/public/lib/time_zone/fidl",
+
+ # TODO(zra): When the platform-specific timeline code is moved out to
+ # the embedder, this can go away.
+ "//zircon/public/lib/fbl",
+ "//zircon/public/lib/trace-engine",
+ ]
}
- source_set(target_name) {
- configs += [
- "..:dart_arch_config",
- "..:dart_config",
- ] + extra_configs
- if (is_fuchsia) {
- configs -= [ "//build/config:symbol_visibility_hidden" ]
- deps = [
- # TODO(US-399): Remove time_service specific code when it is no longer
- # necessary.
- "//garnet/public/lib/app/cpp",
- "//garnet/public/lib/time_zone/fidl",
-
- # TODO(zra): When the platform-specific timeline code is moved out to
- # the embedder, this can go away.
- "//zircon/public/lib/fbl",
- "//zircon/public/lib/trace-engine",
- ]
- }
- public_configs = [ ":libdart_vm_config" ]
- set_sources_assignment_filter([
- "*_test.cc",
- "*_test.h",
- ])
- sources = vm_sources + rebase_path(compiler_sources, ".", "./compiler/")
- include_dirs = [ ".." ]
- }
-}
-
-build_libdart_vm("libdart_vm_jit") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_jit_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_precompiled_runtime") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiled_runtime_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_precompiled_runtime_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_no_snapshot_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiler_config",
- "..:dart_no_snapshot_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiler_config",
- "..:dart_no_snapshot_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_fuchsia") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiler_config",
- "..:dart_no_snapshot_config",
- "..:dart_os_fuchsia_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_product_fuchsia") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiler_config",
- "..:dart_no_snapshot_config",
- "..:dart_os_fuchsia_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_with_precompiler") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_config",
- ]
-}
-
-build_libdart_vm("libdart_vm_with_precompiler_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_config",
- ]
+ public_configs = [ ":libdart_vm_config" ]
+ set_sources_assignment_filter([
+ "*_test.cc",
+ "*_test.h",
+ ])
+ sources = vm_sources + rebase_path(compiler_sources, ".", "./compiler/")
+ include_dirs = [ ".." ]
}
template("process_library_source") {
@@ -224,33 +125,6 @@
}
}
-template("build_libdart_lib") {
- extra_configs = []
- if (defined(invoker.extra_configs)) {
- extra_configs += invoker.extra_configs
- }
- extra_deps = []
- if (defined(invoker.extra_deps)) {
- extra_deps += invoker.extra_deps
- }
- extra_sources = []
- if (defined(invoker.extra_sources)) {
- extra_sources += invoker.extra_sources
- }
- source_set(target_name) {
- configs += [
- "..:dart_arch_config",
- "..:dart_config",
- ] + extra_configs
- if (is_fuchsia) {
- configs -= [ "//build/config:symbol_visibility_hidden" ]
- }
- deps = extra_deps
- sources = extra_sources
- include_dirs = [ ".." ]
- }
-}
-
# This templates expects invoker.sources to be a list of lists.
# The lists contain the following information about each library:
# library name (string)
@@ -300,98 +174,13 @@
all_libsources = rebase_path(invoker.allsources, ".", "../lib")
- build_libdart_lib("libdart_lib_nosnapshot_with_precompiler") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_config",
- ]
- extra_deps = libdeps
- extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
- }
-
- build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_config",
- ]
- extra_deps = libdeps
- extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
- }
-
- build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_fuchsia") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_fuchsia_config",
- ]
- extra_deps = libdeps
- extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
- }
-
- build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_product_fuchsia") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_fuchsia_config",
- ]
- extra_deps = libdeps
- extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
- }
-
- build_libdart_lib("libdart_lib_with_precompiler") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_config",
- ]
- extra_deps = libdeps
- extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
- }
-
- build_libdart_lib("libdart_lib_with_precompiler_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiler_config",
- "..:dart_os_config",
- ]
- extra_deps = libdeps
- extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
- }
-
- build_libdart_lib("libdart_lib_jit") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_os_config",
- ]
- extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
- }
-
- build_libdart_lib("libdart_lib_jit_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_os_config",
- ]
- extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
- }
-
- build_libdart_lib("libdart_lib_precompiled_runtime") {
- extra_configs = [
- "..:dart_maybe_product_config",
- "..:dart_precompiled_runtime_config",
- "..:dart_os_config",
- ]
- extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
- }
-
- build_libdart_lib("libdart_lib_precompiled_runtime_product") {
- extra_configs = [
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config",
- "..:dart_os_config",
- ]
- extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
+ library_for_all_configs("libdart_lib") {
+ target_type = "source_set"
+ include_dirs = [ ".." ]
+ sources = all_libsources
+ snapshot_sources = [ "bootstrap_nocore.cc" ]
+ nosnapshot_sources = [ "bootstrap.cc" ] + liboutputs
+ nosnapshot_deps = libdeps
}
}
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 2bd04fa..84d44b4 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -310,8 +310,12 @@
}
#if !defined(DART_PRECOMPILED_RUNTIME)
-static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
+static RawError* BootstrapFromKernel(Thread* thread,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Zone* zone = thread->zone();
+ kernel::Program* program =
+ kernel::Program::ReadFromBuffer(kernel_buffer, kernel_buffer_size, false);
kernel::KernelLoader loader(program);
Isolate* isolate = thread->isolate();
@@ -336,7 +340,8 @@
// The platform binary may contain other libraries (e.g., dart:_builtin or
// dart:io) that will not be bundled with application. Load them now.
- const Object& result = loader.LoadProgram();
+ const Object& result = Object::Handle(zone, loader.LoadProgram());
+ delete program;
if (result.IsError()) {
return Error::Cast(result).raw();
}
@@ -349,13 +354,16 @@
return Error::null();
}
#else
-static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
+static RawError* BootstrapFromKernel(Thread* thread,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
UNREACHABLE();
return Error::null();
}
#endif
-RawError* Bootstrap::DoBootstrapping(kernel::Program* kernel_program) {
+RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
Zone* zone = thread->zone();
@@ -378,8 +386,9 @@
}
}
- return (kernel_program == NULL) ? BootstrapFromSource(thread)
- : BootstrapFromKernel(thread, kernel_program);
+ return (kernel_buffer == NULL)
+ ? BootstrapFromSource(thread)
+ : BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_size);
}
} // namespace dart
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 0c271b3..fe782ce 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -24,7 +24,8 @@
// bootstrapping.
// The caller of this function is responsible for managing the kernel
// program's memory.
- static RawError* DoBootstrapping(kernel::Program* program);
+ static RawError* DoBootstrapping(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size);
static void SetupNativeResolver();
static bool IsBootstapResolver(Dart_NativeEntryResolver resolver);
diff --git a/runtime/vm/bootstrap_nocore.cc b/runtime/vm/bootstrap_nocore.cc
index 679c41f..9938296 100644
--- a/runtime/vm/bootstrap_nocore.cc
+++ b/runtime/vm/bootstrap_nocore.cc
@@ -70,8 +70,12 @@
Compiler::CompileClass(cls);
}
-RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
+RawError* BootstrapFromKernel(Thread* thread,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Zone* zone = thread->zone();
+ kernel::Program* program =
+ kernel::Program::ReadFromBuffer(kernel_buffer, kernel_buffer_size, false);
kernel::KernelLoader loader(program);
Isolate* isolate = thread->isolate();
@@ -96,7 +100,8 @@
// The platform binary may contain other libraries (e.g., dart:_builtin or
// dart:io) that will not be bundled with application. Load them now.
- const Object& result = loader.LoadProgram();
+ const Object& result = Object::Handle(loader.LoadProgram());
+ delete program;
if (result.IsError()) {
return Error::Cast(result).raw();
}
@@ -109,7 +114,8 @@
return Error::null();
}
-RawError* Bootstrap::DoBootstrapping(kernel::Program* program) {
+RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
Zone* zone = thread->zone();
@@ -132,10 +138,11 @@
}
}
- return BootstrapFromKernel(thread, program);
+ return BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_size);
}
#else
-RawError* Bootstrap::DoBootstrapping(kernel::Program* program) {
+RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
UNREACHABLE();
return Error::null();
}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index a3b0e33..2d94185 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2712,6 +2712,7 @@
CollectImmediateSuperInterfaces(cls, &cids);
RemoveCHAOptimizedCode(cls, cids);
}
+
if (cls.is_enum_class()) {
AllocateEnumValues(cls);
}
@@ -2765,11 +2766,15 @@
(sentinel.raw() == field.raw())) {
continue;
}
- field.SetStaticValue(Object::transition_sentinel());
- result = Compiler::EvaluateStaticInitializer(field);
- ASSERT(!result.IsError());
- field.SetStaticValue(Instance::Cast(result), true);
- field.RecordStore(Instance::Cast(result));
+ // The eager evaluation of the enum values is required for hot-reload (see
+ // commit e3ecc87).
+ if (!FLAG_precompiled_mode) {
+ field.SetStaticValue(Object::transition_sentinel());
+ result = Compiler::EvaluateStaticInitializer(field);
+ ASSERT(!result.IsError());
+ field.SetStaticValue(Instance::Cast(result), true);
+ field.RecordStore(Instance::Cast(result));
+ }
}
} else {
const String& name_prefix =
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index e465222..2208c17 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -256,22 +256,6 @@
}
}
- void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
- NOT_IN_PRODUCT(TimelineDurationScope tds(
- Thread::Current(), Timeline::GetIsolateStream(), "PostLoadClass"));
-
- Class& cls = Class::Handle(zone);
- for (intptr_t i = predefined_start_index_; i < predefined_stop_index_;
- i++) {
- cls ^= refs.At(i);
- cls.RehashConstants(zone);
- }
- for (intptr_t i = start_index_; i < stop_index_; i++) {
- cls ^= refs.At(i);
- cls.RehashConstants(zone);
- }
- }
-
private:
intptr_t predefined_start_index_;
intptr_t predefined_stop_index_;
@@ -2100,10 +2084,14 @@
intptr_t length = handlers->ptr()->num_entries_;
s->WriteUnsigned(length);
s->WriteRef(handlers->ptr()->handled_types_data_);
-
- uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
- intptr_t length_in_bytes = length * sizeof(ExceptionHandlerInfo);
- s->WriteBytes(data, length_in_bytes);
+ for (intptr_t j = 0; j < length; j++) {
+ const ExceptionHandlerInfo& info = handlers->ptr()->data()[j];
+ s->Write<uint32_t>(info.handler_pc_offset);
+ s->Write<int16_t>(info.outer_try_index);
+ s->Write<int8_t>(info.needs_stacktrace);
+ s->Write<int8_t>(info.has_catch_all);
+ s->Write<int8_t>(info.is_generated);
+ }
}
}
@@ -2142,10 +2130,14 @@
handlers->ptr()->num_entries_ = length;
handlers->ptr()->handled_types_data_ =
reinterpret_cast<RawArray*>(d->ReadRef());
-
- uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
- intptr_t length_in_bytes = length * sizeof(ExceptionHandlerInfo);
- d->ReadBytes(data, length_in_bytes);
+ for (intptr_t j = 0; j < length; j++) {
+ ExceptionHandlerInfo& info = handlers->ptr()->data()[j];
+ info.handler_pc_offset = d->Read<uint32_t>();
+ info.outer_try_index = d->Read<int16_t>();
+ info.needs_stacktrace = d->Read<int8_t>();
+ info.has_catch_all = d->Read<int8_t>();
+ info.is_generated = d->Read<int8_t>();
+ }
}
}
};
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 29afb6d..5b2415a 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -510,6 +510,7 @@
{"dart:core", "_CastError", "_CastError._create"},
{"dart:core", "_InternalError", "_InternalError."},
{"dart:core", "_InvocationMirror", "_allocateInvocationMirror"},
+ {"dart:core", "_InvocationMirror", "_allocateInvocationMirrorForClosure"},
{"dart:core", "_TypeError", "_TypeError._create"},
{"dart:collection", "::", "_rehashObjects"},
{"dart:isolate", "IsolateSpawnException", "IsolateSpawnException."},
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index 0fefb14..531cc82 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -250,7 +250,6 @@
const Code& bytecode,
Object** object,
uword pc) {
-#if !defined(PRODUCT)
const uint32_t instr = *reinterpret_cast<uint32_t*>(pc);
const uint8_t opcode = instr & 0xFF;
ASSERT(opcode < kOpcodeCount);
@@ -274,9 +273,6 @@
*object = NULL;
}
}
-#else
- UNREACHABLE();
-#endif
}
void KernelBytecodeDisassembler::Disassemble(uword start,
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 5411f90..4aedb3c 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1020,8 +1020,9 @@
// Replace the argument descriptor slot with a special parameter.
if (parsed_function().has_arg_desc_var()) {
- Definition* defn = new SpecialParameterInstr(
- SpecialParameterInstr::kArgDescriptor, Thread::kNoDeoptId);
+ Definition* defn =
+ new SpecialParameterInstr(SpecialParameterInstr::kArgDescriptor,
+ Thread::kNoDeoptId, graph_entry_);
AllocateSSAIndexes(defn);
AddToInitialDefinitions(defn);
env[ArgumentDescriptorEnvIndex()] = defn;
@@ -1081,10 +1082,34 @@
}
}
}
- } else if (block_entry->IsCatchBlockEntry()) {
+ } else if (CatchBlockEntryInstr* catch_entry =
+ block_entry->AsCatchBlockEntry()) {
+ const intptr_t raw_exception_var_envindex =
+ catch_entry->raw_exception_var() != nullptr
+ ? catch_entry->raw_exception_var()->BitIndexIn(
+ num_direct_parameters_)
+ : -1;
+ const intptr_t raw_stacktrace_var_envindex =
+ catch_entry->raw_stacktrace_var() != nullptr
+ ? catch_entry->raw_stacktrace_var()->BitIndexIn(
+ num_direct_parameters_)
+ : -1;
+
// Add real definitions for all locals and parameters.
for (intptr_t i = 0; i < env->length(); ++i) {
- ParameterInstr* param = new (zone()) ParameterInstr(i, block_entry);
+ // Replace usages of the raw exception/stacktrace variables with
+ // [SpecialParameterInstr]s.
+ Definition* param = nullptr;
+ if (raw_exception_var_envindex == i) {
+ param = new SpecialParameterInstr(SpecialParameterInstr::kException,
+ Thread::kNoDeoptId, catch_entry);
+ } else if (raw_stacktrace_var_envindex == i) {
+ param = new SpecialParameterInstr(SpecialParameterInstr::kStackTrace,
+ Thread::kNoDeoptId, catch_entry);
+ } else {
+ param = new (zone()) ParameterInstr(i, block_entry);
+ }
+
param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
(*env)[i] = param;
block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param);
@@ -1106,6 +1131,30 @@
// Attach environment to the block entry.
AttachEnvironment(block_entry, env);
+#if defined(TARGET_ARCH_DBC)
+ // On DBC the exception/stacktrace variables are in special registers when
+ // entering the catch block. The only usage of those special registers is
+ // within the catch block. A possible lazy-deopt at the beginning of the
+ // catch does not need to move those around, since the registers will be
+ // up-to-date when arriving in the unoptimized code and unoptimized code will
+ // take care of moving them to appropriate slots.
+ if (CatchBlockEntryInstr* catch_entry = block_entry->AsCatchBlockEntry()) {
+ Environment* deopt_env = catch_entry->env();
+ const LocalVariable* raw_exception_var = catch_entry->raw_exception_var();
+ const LocalVariable* raw_stacktrace_var = catch_entry->raw_stacktrace_var();
+ if (raw_exception_var != nullptr) {
+ Value* value = deopt_env->ValueAt(
+ raw_exception_var->BitIndexIn(num_direct_parameters_));
+ value->BindToEnvironment(constant_null());
+ }
+ if (raw_stacktrace_var != nullptr) {
+ Value* value = deopt_env->ValueAt(
+ raw_stacktrace_var->BitIndexIn(num_direct_parameters_));
+ value->BindToEnvironment(constant_null());
+ }
+ }
+#endif // defined(TARGET_ARCH_DBC)
+
// 2. Process normal instructions.
for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
index 0e9f214..557f69a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
@@ -17,6 +17,7 @@
#include "vm/instructions.h"
#include "vm/object_store.h"
#include "vm/parser.h"
+#include "vm/simulator.h"
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
@@ -383,6 +384,12 @@
} else if (source.IsArgsDescRegister()) {
ASSERT(destination.IsRegister());
__ LoadArgDescriptorOpt(destination.reg());
+ } else if (source.IsExceptionRegister()) {
+ ASSERT(destination.IsRegister());
+ __ MoveSpecial(destination.reg(), Simulator::kExceptionSpecialIndex);
+ } else if (source.IsStackTraceRegister()) {
+ ASSERT(destination.IsRegister());
+ __ MoveSpecial(destination.reg(), Simulator::kStackTraceSpecialIndex);
} else if (source.IsConstant() && destination.IsRegister()) {
if (source.constant_instruction()->representation() == kUnboxedDouble) {
const Register result = destination.reg();
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index a957568..875f806 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -1641,7 +1641,8 @@
const LocalVariable& stacktrace_var,
bool needs_stacktrace,
intptr_t deopt_id,
- bool should_restore_closure_context = false)
+ const LocalVariable* raw_exception_var,
+ const LocalVariable* raw_stacktrace_var)
: BlockEntryInstr(block_id, try_index, deopt_id),
graph_entry_(graph_entry),
predecessor_(NULL),
@@ -1649,8 +1650,9 @@
catch_try_index_(catch_try_index),
exception_var_(exception_var),
stacktrace_var_(stacktrace_var),
+ raw_exception_var_(raw_exception_var),
+ raw_stacktrace_var_(raw_stacktrace_var),
needs_stacktrace_(needs_stacktrace),
- should_restore_closure_context_(should_restore_closure_context),
handler_token_pos_(handler_token_pos),
is_generated_(is_generated) {}
@@ -1669,6 +1671,11 @@
const LocalVariable& exception_var() const { return exception_var_; }
const LocalVariable& stacktrace_var() const { return stacktrace_var_; }
+ const LocalVariable* raw_exception_var() const { return raw_exception_var_; }
+ const LocalVariable* raw_stacktrace_var() const {
+ return raw_stacktrace_var_;
+ }
+
bool needs_stacktrace() const { return needs_stacktrace_; }
bool is_generated() const { return is_generated_; }
@@ -1692,12 +1699,6 @@
predecessor_ = predecessor;
}
- bool should_restore_closure_context() const {
- ASSERT(exception_var_.is_captured() == stacktrace_var_.is_captured());
- ASSERT(!exception_var_.is_captured() || should_restore_closure_context_);
- return should_restore_closure_context_;
- }
-
GraphEntryInstr* graph_entry_;
BlockEntryInstr* predecessor_;
const Array& catch_handler_types_;
@@ -1705,8 +1706,9 @@
GrowableArray<Definition*> initial_definitions_;
const LocalVariable& exception_var_;
const LocalVariable& stacktrace_var_;
+ const LocalVariable* raw_exception_var_;
+ const LocalVariable* raw_stacktrace_var_;
const bool needs_stacktrace_;
- const bool should_restore_closure_context_;
TokenPosition handler_token_pos_;
bool is_generated_;
@@ -2998,12 +3000,23 @@
// the type arguments of a generic function or an arguments descriptor.
class SpecialParameterInstr : public TemplateDefinition<0, NoThrow> {
public:
- enum SpecialParameterKind { kContext, kTypeArgs, kArgDescriptor };
+ enum SpecialParameterKind {
+ kContext,
+ kTypeArgs,
+ kArgDescriptor,
+ kException,
+ kStackTrace
+ };
- SpecialParameterInstr(SpecialParameterKind kind, intptr_t deopt_id)
- : TemplateDefinition(deopt_id), kind_(kind) {}
+ SpecialParameterInstr(SpecialParameterKind kind,
+ intptr_t deopt_id,
+ BlockEntryInstr* block)
+ : TemplateDefinition(deopt_id), kind_(kind), block_(block) {}
DECLARE_INSTRUCTION(SpecialParameter)
+
+ virtual BlockEntryInstr* GetBlock() { return block_; }
+
virtual CompileType ComputeType() const;
virtual bool ComputeCanDeoptimize() const { return false; }
@@ -3027,6 +3040,10 @@
return "kTypeArgs";
case kArgDescriptor:
return "kArgDescriptor";
+ case kException:
+ return "kException";
+ case kStackTrace:
+ return "kStackTrace";
}
UNREACHABLE();
return NULL;
@@ -3034,6 +3051,7 @@
private:
const SpecialParameterKind kind_;
+ BlockEntryInstr* block_;
DISALLOW_COPY_AND_ASSIGN(SpecialParameterInstr);
};
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 9b5729c..3d7b61d 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -2888,38 +2888,15 @@
ASSERT(fp_sp_dist <= 0);
__ AddImmediate(SP, FP, fp_sp_dist);
- // Auxiliary variables introduced by the try catch can be captured if we are
- // inside a function with yield/resume points. In this case we first need
- // to restore the context to match the context at entry into the closure.
- if (should_restore_closure_context()) {
- const ParsedFunction& parsed_function = compiler->parsed_function();
- ASSERT(parsed_function.function().IsClosureFunction());
- LocalScope* scope = parsed_function.node_sequence()->scope();
-
- LocalVariable* closure_parameter = scope->VariableAt(0);
- ASSERT(!closure_parameter->is_captured());
- __ LoadFromOffset(kWord, R6, FP, closure_parameter->index() * kWordSize);
- __ LoadFieldFromOffset(kWord, R6, R6, Closure::context_offset());
-
- const intptr_t context_index =
- parsed_function.current_context_var()->index();
- __ StoreToOffset(kWord, R6, FP, context_index * kWordSize);
- }
-
- // Initialize exception and stack trace variables.
- if (exception_var().is_captured()) {
- ASSERT(stacktrace_var().is_captured());
- __ StoreIntoObjectOffset(R6,
- Context::variable_offset(exception_var().index()),
- kExceptionObjectReg);
- __ StoreIntoObjectOffset(R6,
- Context::variable_offset(stacktrace_var().index()),
- kStackTraceObjectReg);
- } else {
- __ StoreToOffset(kWord, kExceptionObjectReg, FP,
- exception_var().index() * kWordSize);
- __ StoreToOffset(kWord, kStackTraceObjectReg, FP,
- stacktrace_var().index() * kWordSize);
+ if (!compiler->is_optimizing()) {
+ if (raw_exception_var_ != nullptr) {
+ __ StoreToOffset(kWord, kExceptionObjectReg, FP,
+ raw_exception_var_->index() * kWordSize);
+ }
+ if (raw_stacktrace_var_ != nullptr) {
+ __ StoreToOffset(kWord, kStackTraceObjectReg, FP,
+ raw_stacktrace_var_->index() * kWordSize);
+ }
}
}
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 9c0a698..9a9bc82 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -2637,40 +2637,15 @@
ASSERT(fp_sp_dist <= 0);
__ AddImmediate(SP, FP, fp_sp_dist);
- // Auxiliary variables introduced by the try catch can be captured if we are
- // inside a function with yield/resume points. In this case we first need
- // to restore the context to match the context at entry into the closure.
- if (should_restore_closure_context()) {
- const ParsedFunction& parsed_function = compiler->parsed_function();
- ASSERT(parsed_function.function().IsClosureFunction());
- LocalScope* scope = parsed_function.node_sequence()->scope();
-
- LocalVariable* closure_parameter = scope->VariableAt(0);
- ASSERT(!closure_parameter->is_captured());
- __ LoadFromOffset(R28, FP, closure_parameter->index() * kWordSize);
- __ LoadFieldFromOffset(R28, R28, Closure::context_offset());
-
- const intptr_t context_index =
- parsed_function.current_context_var()->index();
- __ StoreToOffset(R28, FP, context_index * kWordSize);
- }
-
- // Initialize exception and stack trace variables.
- if (exception_var().is_captured()) {
- ASSERT(stacktrace_var().is_captured());
- __ StoreIntoObjectOffset(R28,
- Context::variable_offset(exception_var().index()),
- kExceptionObjectReg);
- __ StoreIntoObjectOffset(R28,
- Context::variable_offset(stacktrace_var().index()),
- kStackTraceObjectReg);
- } else {
- // Restore stack and initialize the two exception variables:
- // exception and stack trace variables.
- __ StoreToOffset(kExceptionObjectReg, FP,
- exception_var().index() * kWordSize);
- __ StoreToOffset(kStackTraceObjectReg, FP,
- stacktrace_var().index() * kWordSize);
+ if (!compiler->is_optimizing()) {
+ if (raw_exception_var_ != nullptr) {
+ __ StoreToOffset(kExceptionObjectReg, FP,
+ raw_exception_var_->index() * kWordSize);
+ }
+ if (raw_stacktrace_var_ != nullptr) {
+ __ StoreToOffset(kStackTraceObjectReg, FP,
+ raw_stacktrace_var_->index() * kWordSize);
+ }
}
}
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 093c340..c00e4e9 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -1184,69 +1184,18 @@
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
+ __ SetFrame(compiler->StackSize());
- Register context_reg = kNoRegister;
-
- // Auxiliary variables introduced by the try catch can be captured if we are
- // inside a function with yield/resume points. In this case we first need
- // to restore the context to match the context at entry into the closure.
- if (should_restore_closure_context()) {
- const ParsedFunction& parsed_function = compiler->parsed_function();
-
- ASSERT(parsed_function.function().IsClosureFunction());
- LocalScope* scope = parsed_function.node_sequence()->scope();
-
- LocalVariable* closure_parameter = scope->VariableAt(0);
- ASSERT(!closure_parameter->is_captured());
-
- const LocalVariable& current_context_var =
- *parsed_function.current_context_var();
-
- context_reg = compiler->is_optimizing()
- ? compiler->CatchEntryRegForVariable(current_context_var)
- : LocalVarIndex(0, current_context_var.index());
-
- Register closure_reg;
- if (closure_parameter->index() > 0) {
- __ Move(context_reg, LocalVarIndex(0, closure_parameter->index()));
- closure_reg = context_reg;
- } else {
- closure_reg = LocalVarIndex(0, closure_parameter->index());
- }
-
- __ LoadField(context_reg, closure_reg,
- Closure::context_offset() / kWordSize);
- }
-
- if (exception_var().is_captured()) {
- ASSERT(stacktrace_var().is_captured());
- ASSERT(context_reg != kNoRegister);
- // This will be SP[1] register so we are free to use it as a temporary.
- const Register temp = compiler->StackSize();
- __ MoveSpecial(temp, Simulator::kExceptionSpecialIndex);
- __ StoreField(context_reg,
- Context::variable_offset(exception_var().index()) / kWordSize,
- temp);
- __ MoveSpecial(temp, Simulator::kStackTraceSpecialIndex);
- __ StoreField(
- context_reg,
- Context::variable_offset(stacktrace_var().index()) / kWordSize, temp);
- } else {
- if (compiler->is_optimizing()) {
- const intptr_t exception_reg =
- compiler->CatchEntryRegForVariable(exception_var());
- const intptr_t stacktrace_reg =
- compiler->CatchEntryRegForVariable(stacktrace_var());
- __ MoveSpecial(exception_reg, Simulator::kExceptionSpecialIndex);
- __ MoveSpecial(stacktrace_reg, Simulator::kStackTraceSpecialIndex);
- } else {
- __ MoveSpecial(LocalVarIndex(0, exception_var().index()),
+ if (!compiler->is_optimizing()) {
+ if (raw_exception_var_ != nullptr) {
+ __ MoveSpecial(LocalVarIndex(0, raw_exception_var_->index()),
Simulator::kExceptionSpecialIndex);
- __ MoveSpecial(LocalVarIndex(0, stacktrace_var().index()),
+ }
+ if (raw_stacktrace_var_ != nullptr) {
+ __ MoveSpecial(LocalVarIndex(0, raw_stacktrace_var_->index()),
Simulator::kStackTraceSpecialIndex);
}
}
- __ SetFrame(compiler->StackSize());
}
EMIT_NATIVE_CODE(Throw, 0, Location::NoLocation(), LocationSummary::kCall) {
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index c92b517..e8ec6e3 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -2496,51 +2496,15 @@
ASSERT(fp_sp_dist <= 0);
__ leal(ESP, Address(EBP, fp_sp_dist));
- // Auxiliary variables introduced by the try catch can be captured if we are
- // inside a function with yield/resume points. In this case we first need
- // to restore the context to match the context at entry into the closure.
- if (should_restore_closure_context()) {
- const ParsedFunction& parsed_function = compiler->parsed_function();
- ASSERT(parsed_function.function().IsClosureFunction());
- LocalScope* scope = parsed_function.node_sequence()->scope();
-
- LocalVariable* closure_parameter = scope->VariableAt(0);
- ASSERT(!closure_parameter->is_captured());
- __ movl(EDI, Address(EBP, closure_parameter->index() * kWordSize));
- __ movl(EDI, FieldAddress(EDI, Closure::context_offset()));
-
-#ifdef DEBUG
- Label ok;
- __ LoadClassId(EBX, EDI);
- __ cmpl(EBX, Immediate(kContextCid));
- __ j(EQUAL, &ok, Assembler::kNearJump);
- __ Stop("Incorrect context at entry");
- __ Bind(&ok);
-#endif
-
- const intptr_t context_index =
- parsed_function.current_context_var()->index();
- __ movl(Address(EBP, context_index * kWordSize), EDI);
- }
-
- // Initialize exception and stack trace variables.
- if (exception_var().is_captured()) {
- ASSERT(stacktrace_var().is_captured());
- __ StoreIntoObject(
- EDI,
- FieldAddress(EDI, Context::variable_offset(exception_var().index())),
- kExceptionObjectReg);
- __ StoreIntoObject(
- EDI,
- FieldAddress(EDI, Context::variable_offset(stacktrace_var().index())),
- kStackTraceObjectReg);
- } else {
- // Restore stack and initialize the two exception variables:
- // exception and stack trace variables.
- __ movl(Address(EBP, exception_var().index() * kWordSize),
- kExceptionObjectReg);
- __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
- kStackTraceObjectReg);
+ if (!compiler->is_optimizing()) {
+ if (raw_exception_var_ != nullptr) {
+ __ movl(Address(EBP, raw_exception_var_->index() * kWordSize),
+ kExceptionObjectReg);
+ }
+ if (raw_stacktrace_var_ != nullptr) {
+ __ movl(Address(EBP, raw_stacktrace_var_->index() * kWordSize),
+ kStackTraceObjectReg);
+ }
}
}
diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc
index 4792e3c..8fb8da0 100644
--- a/runtime/vm/compiler/backend/il_test.cc
+++ b/runtime/vm/compiler/backend/il_test.cc
@@ -13,9 +13,10 @@
EXPECT(target_instr->IsBlockEntry());
EXPECT(!target_instr->IsDefinition());
SpecialParameterInstr* context = new SpecialParameterInstr(
- SpecialParameterInstr::kContext, Thread::kNoDeoptId);
+ SpecialParameterInstr::kContext, Thread::kNoDeoptId, target_instr);
EXPECT(context->IsDefinition());
EXPECT(!context->IsBlockEntry());
+ EXPECT(context->GetBlock() == target_instr);
}
TEST_CASE(OptimizationTests) {
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index b44d650..cbbd640 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -2571,49 +2571,15 @@
ASSERT(fp_sp_dist <= 0);
__ leaq(RSP, Address(RBP, fp_sp_dist));
- // Auxiliary variables introduced by the try catch can be captured if we are
- // inside a function with yield/resume points. In this case we first need
- // to restore the context to match the context at entry into the closure.
- if (should_restore_closure_context()) {
- const ParsedFunction& parsed_function = compiler->parsed_function();
- ASSERT(parsed_function.function().IsClosureFunction());
- LocalScope* scope = parsed_function.node_sequence()->scope();
-
- LocalVariable* closure_parameter = scope->VariableAt(0);
- ASSERT(!closure_parameter->is_captured());
- __ movq(R12, Address(RBP, closure_parameter->index() * kWordSize));
- __ movq(R12, FieldAddress(R12, Closure::context_offset()));
-
-#ifdef DEBUG
- Label ok;
- __ LoadClassId(RBX, R12);
- __ cmpq(RBX, Immediate(kContextCid));
- __ j(EQUAL, &ok, Assembler::kNearJump);
- __ Stop("Incorrect context at entry");
- __ Bind(&ok);
-#endif
-
- const intptr_t context_index =
- parsed_function.current_context_var()->index();
- __ movq(Address(RBP, context_index * kWordSize), R12);
- }
-
- // Initialize exception and stack trace variables.
- if (exception_var().is_captured()) {
- ASSERT(stacktrace_var().is_captured());
- __ StoreIntoObject(
- R12,
- FieldAddress(R12, Context::variable_offset(exception_var().index())),
- kExceptionObjectReg);
- __ StoreIntoObject(
- R12,
- FieldAddress(R12, Context::variable_offset(stacktrace_var().index())),
- kStackTraceObjectReg);
- } else {
- __ movq(Address(RBP, exception_var().index() * kWordSize),
- kExceptionObjectReg);
- __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
- kStackTraceObjectReg);
+ if (!compiler->is_optimizing()) {
+ if (raw_exception_var_ != nullptr) {
+ __ movq(Address(RBP, raw_exception_var_->index() * kWordSize),
+ kExceptionObjectReg);
+ }
+ if (raw_stacktrace_var_ != nullptr) {
+ __ movq(Address(RBP, raw_stacktrace_var_->index() * kWordSize),
+ kStackTraceObjectReg);
+ }
}
}
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 10d2c09..f96a09d 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -595,23 +595,6 @@
range->DefineAt(catch_entry->start_pos()); // Defined at block entry.
ProcessInitialDefinition(defn, range, catch_entry);
}
- // Block the two fixed registers used by CatchBlockEntryInstr from the
- // block start to until the end of the instruction so that they are
- // preserved.
- intptr_t start = catch_entry->start_pos();
-#if !defined(TARGET_ARCH_DBC)
- const Register exception_reg = kExceptionObjectReg;
- const Register stacktrace_reg = kStackTraceObjectReg;
-#else
- const intptr_t exception_reg =
- LocalVarIndex(0, catch_entry->exception_var().index());
- const intptr_t stacktrace_reg =
- LocalVarIndex(0, catch_entry->stacktrace_var().index());
-#endif
- BlockLocation(Location::RegisterLocation(exception_reg), start,
- ToInstructionEnd(start));
- BlockLocation(Location::RegisterLocation(stacktrace_reg), start,
- ToInstructionEnd(start));
}
}
@@ -639,11 +622,42 @@
void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn,
LiveRange* range,
BlockEntryInstr* block) {
-#if defined(TARGET_ARCH_DBC)
+ // Save the range end because it may change below.
+ const intptr_t range_end = range->End();
+
+ // TODO(31956): Clean up this code and factor common functionality out.
+ // Consider also making a separate [ProcessInitialDefinition] for
+ // [CatchBlockEntry]'s.
if (block->IsCatchBlockEntry()) {
- if (defn->IsParameter()) {
+ if (SpecialParameterInstr* param = defn->AsSpecialParameter()) {
+ Location loc;
+ switch (param->kind()) {
+ case SpecialParameterInstr::kException:
+ loc = Location::ExceptionLocation();
+ break;
+ case SpecialParameterInstr::kStackTrace:
+ loc = Location::StackTraceLocation();
+ break;
+ default:
+ UNREACHABLE();
+ }
+ range->set_assigned_location(loc);
+ AssignSafepoints(defn, range);
+ range->finger()->Initialize(range);
+ SplitInitialDefinitionAt(range, block->lifetime_position() + 1);
+ ConvertAllUses(range);
+
+ // On non-DBC we'll have exception/stacktrace in a register and need to
+ // ensure this register is not available for register allocation during
+ // the [CatchBlockEntry] to ensure it's not overwritten.
+ if (loc.IsRegister()) {
+ BlockLocation(loc, block->lifetime_position(),
+ block->lifetime_position() + 1);
+ }
+ return;
+#if defined(TARGET_ARCH_DBC)
+ } else if (ParameterInstr* param = defn->AsParameter()) {
// This must be in sync with FlowGraphCompiler::CatchEntryRegForVariable.
- ParameterInstr* param = defn->AsParameter();
intptr_t slot_index = param->index();
AssignSafepoints(defn, range);
range->finger()->Initialize(range);
@@ -652,8 +666,8 @@
SplitInitialDefinitionAt(range, block->lifetime_position() + 2);
ConvertAllUses(range);
BlockLocation(Location::RegisterLocation(slot_index), 0, kMaxPosition);
- } else {
- ConstantInstr* constant = defn->AsConstant();
+ return;
+ } else if (ConstantInstr* constant = defn->AsConstant()) {
ASSERT(constant != NULL);
range->set_assigned_location(Location::Constant(constant));
range->set_spill_slot(Location::Constant(constant));
@@ -668,13 +682,11 @@
CompleteRange(tail, Location::kRegister);
}
ConvertAllUses(range);
+ return;
+#endif // defined(TARGET_ARCH_DBC)
}
- return;
}
-#endif
- // Save the range end because it may change below.
- intptr_t range_end = range->End();
if (defn->IsParameter()) {
ParameterInstr* param = defn->AsParameter();
intptr_t slot_index = param->index();
@@ -705,16 +717,14 @@
Location loc;
#if defined(TARGET_ARCH_DBC)
loc = Location::ArgumentsDescriptorLocation();
- range->set_assigned_location(loc);
#else
loc = Location::RegisterLocation(ARGS_DESC_REG);
- range->set_assigned_location(loc);
#endif // defined(TARGET_ARCH_DBC)
+ range->set_assigned_location(loc);
if (loc.IsRegister()) {
AssignSafepoints(defn, range);
if (range->End() > kNormalEntryPos) {
- LiveRange* tail = range->SplitAt(kNormalEntryPos);
- CompleteRange(tail, Location::kRegister);
+ SplitInitialDefinitionAt(range, kNormalEntryPos);
}
ConvertAllUses(range);
return;
@@ -1963,7 +1973,15 @@
}
}
+ while (idx > spill_slots_.length()) {
+ spill_slots_.Add(kMaxPosition);
+ quad_spill_slots_.Add(false);
+ untagged_spill_slots_.Add(false);
+ }
+
if (idx == spill_slots_.length()) {
+ idx = spill_slots_.length();
+
// No free spill slot found. Allocate a new one.
spill_slots_.Add(0);
quad_spill_slots_.Add(need_quad);
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index a01abb2..44c88ee 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -180,8 +180,17 @@
}
UNREACHABLE();
#if TARGET_ARCH_DBC
- case kArgsDescRegister:
- return "ArgDesc";
+ case kSpecialDbcRegister:
+ switch (payload()) {
+ case kArgsDescriptorReg:
+ return "ArgDescReg";
+ case kExceptionReg:
+ return "ExceptionReg";
+ case kStackTraceReg:
+ return "StackTraceReg";
+ default:
+ UNREACHABLE();
+ }
#endif
default:
if (IsConstant()) {
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index f6ffbab..fd4d576 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -62,6 +62,14 @@
static const uword kLocationTagMask = 0x3;
public:
+#if defined(TARGET_ARCH_DBC)
+ enum SpecialDbcRegister{
+ kArgsDescriptorReg,
+ kExceptionReg,
+ kStackTraceReg,
+ };
+#endif
+
// Constant payload can overlap with kind field so Kind values
// have to be chosen in a way that their last 2 bits are never
// the same as kConstantTag or kPairLocationTag.
@@ -99,9 +107,9 @@
kFpuRegister = 12,
#ifdef TARGET_ARCH_DBC
- // We use this to signify a special `Location` where the arguments
- // descriptor can be found on DBC.
- kArgsDescRegister = 15,
+ // We use this to signify a special `Location` where the different
+ // [SpecialDbcRegister]s can be found on DBC.
+ kSpecialDbcRegister = 15,
#endif
};
@@ -130,8 +138,9 @@
COMPILE_ASSERT((kFpuRegister & kLocationTagMask) != kPairLocationTag);
#ifdef TARGET_ARCH_DBC
- COMPILE_ASSERT((kArgsDescRegister & kLocationTagMask) != kConstantTag);
- COMPILE_ASSERT((kArgsDescRegister & kLocationTagMask) != kPairLocationTag);
+ COMPILE_ASSERT((kSpecialDbcRegister & kLocationTagMask) != kConstantTag);
+ COMPILE_ASSERT((kSpecialDbcRegister & kLocationTagMask) !=
+ kPairLocationTag);
#endif
// Verify tags and tagmask.
@@ -247,12 +256,44 @@
bool IsFpuRegister() const { return kind() == kFpuRegister; }
-#ifdef TARGET_ARCH_DBC
static Location ArgumentsDescriptorLocation() {
- return Location(kArgsDescRegister, 0);
+#ifdef TARGET_ARCH_DBC
+ return Location(kSpecialDbcRegister, kArgsDescriptorReg);
+#else
+ return Location::RegisterLocation(ARGS_DESC_REG);
+#endif
}
- bool IsArgsDescRegister() const { return kind() == kArgsDescRegister; }
+ static Location ExceptionLocation() {
+#ifdef TARGET_ARCH_DBC
+ return Location(kSpecialDbcRegister, kExceptionReg);
+#else
+ return Location::RegisterLocation(kExceptionObjectReg);
+#endif
+ }
+
+ static Location StackTraceLocation() {
+#ifdef TARGET_ARCH_DBC
+ return Location(kSpecialDbcRegister, kStackTraceReg);
+#else
+ return Location::RegisterLocation(kStackTraceObjectReg);
+#endif
+ }
+
+#ifdef TARGET_ARCH_DBC
+ bool IsArgsDescRegister() const {
+ return IsSpecialDbcRegister(kArgsDescriptorReg);
+ }
+ bool IsExceptionRegister() const {
+ return IsSpecialDbcRegister(kExceptionReg);
+ }
+ bool IsStackTraceRegister() const {
+ return IsSpecialDbcRegister(kStackTraceReg);
+ }
+
+ bool IsSpecialDbcRegister(SpecialDbcRegister reg) const {
+ return kind() == kSpecialDbcRegister && payload() == reg;
+ }
#endif
FpuRegister fpu_reg() const {
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 2623846..449ace0 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3157,12 +3157,9 @@
// not tracked in the environment anyway.
const intptr_t parameter_count = flow_graph->num_direct_parameters();
- if (!catch_entry->exception_var().is_captured()) {
- cdefs[catch_entry->exception_var().BitIndexIn(parameter_count)] = NULL;
- }
- if (!catch_entry->stacktrace_var().is_captured()) {
- cdefs[catch_entry->stacktrace_var().BitIndexIn(parameter_count)] = NULL;
- }
+ cdefs[catch_entry->raw_exception_var()->BitIndexIn(parameter_count)] = NULL;
+ cdefs[catch_entry->raw_stacktrace_var()->BitIndexIn(parameter_count)] =
+ NULL;
for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
!block_it.Done(); block_it.Advance()) {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 6b9c5bb..1f0f476 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1051,6 +1051,13 @@
return CompileType::FromCid(kTypeArgumentsCid);
case kArgDescriptor:
return CompileType::FromCid(kImmutableArrayCid);
+ case kException:
+ return CompileType(CompileType::kNonNullable, kDynamicCid,
+ &Object::dynamic_type());
+ case kStackTrace:
+ // We cannot use [kStackTraceCid] here because any kind of object can be
+ // used as a stack trace via `new Future.error(..., <obj>)` :-/
+ return CompileType::Dynamic();
}
UNREACHABLE();
return CompileType::Dynamic();
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index c26f4a6..aa65f19 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -4116,7 +4116,8 @@
owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(),
catch_block->handler_types(), try_handler_index,
catch_block->exception_var(), catch_block->stacktrace_var(),
- catch_block->needs_stacktrace(), owner()->GetNextDeoptId());
+ catch_block->needs_stacktrace(), owner()->GetNextDeoptId(),
+ &catch_block->exception_var(), &catch_block->stacktrace_var());
owner()->AddCatchEntry(catch_entry);
AppendFragment(catch_entry, for_catch);
@@ -4162,7 +4163,8 @@
owner()->AllocateBlockId(), original_handler_index,
owner()->graph_entry(), types, catch_handler_index,
catch_block->exception_var(), catch_block->stacktrace_var(),
- catch_block->needs_stacktrace(), owner()->GetNextDeoptId());
+ catch_block->needs_stacktrace(), owner()->GetNextDeoptId(),
+ &catch_block->exception_var(), &catch_block->stacktrace_var());
owner()->AddCatchEntry(finally_entry);
AppendFragment(finally_entry, for_finally);
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 0e85f68..b943afa 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -679,7 +679,7 @@
intptr_t node_offset = reader.ReadUInt32();
intptr_t md_offset = reader.ReadUInt32();
- ASSERT((node_offset > 0) && (md_offset > 0));
+ ASSERT((node_offset > 0) && (md_offset >= 0));
ASSERT(node_offset > prev_node_offset);
prev_node_offset = node_offset;
}
@@ -747,7 +747,7 @@
intptr_t index = last_mapping_index_;
intptr_t mapping_node_offset = 0;
- intptr_t mapping_md_offset = 0;
+ intptr_t mapping_md_offset = -1;
Reader reader(H.metadata_mappings());
const intptr_t kUInt32Size = 4;
@@ -766,7 +766,7 @@
last_node_offset_ = node_offset;
if ((index < mappings_num_) && (mapping_node_offset == node_offset)) {
- ASSERT(mapping_md_offset > 0);
+ ASSERT(mapping_md_offset >= 0);
return mapping_md_offset;
} else {
return -1;
@@ -782,7 +782,7 @@
}
AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
- md_offset - MetadataPayloadOffset);
+ md_offset);
*target_name = builder_->ReadCanonicalNameReference();
*check_receiver_for_null = builder_->ReadBool();
@@ -860,7 +860,7 @@
}
AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
- md_offset - MetadataPayloadOffset);
+ md_offset);
const int kDynamicUsesBit = 1 << 0;
const int kNonThisUsesBit = 1 << 1;
@@ -890,7 +890,7 @@
}
AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
- md_offset - MetadataPayloadOffset);
+ md_offset);
const NameIndex kernel_name = builder_->ReadCanonicalNameReference();
const bool nullable = builder_->ReadBool();
@@ -923,7 +923,7 @@
}
AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
- md_offset - MetadataPayloadOffset);
+ md_offset);
// Read bytecode.
intptr_t bytecode_size = builder_->reader_.ReadUInt();
@@ -1014,8 +1014,8 @@
}
} break;
case ConstantPoolTag::kICData: {
- NameIndex target = builder_->ReadCanonicalNameReference();
- name = H.DartProcedureName(target).raw();
+ StringIndex target = builder_->ReadStringReference();
+ name = H.DartSymbolPlain(target).raw();
intptr_t arg_desc_index = builder_->ReadUInt();
ASSERT(arg_desc_index < i);
array ^= obj_pool.ObjectAt(arg_desc_index);
@@ -1084,12 +1084,10 @@
obj = H.Canonicalize(Instance::Cast(obj));
break;
case ConstantPoolTag::kType:
- UNIMPLEMENTED(); // Encoding is under discussion with CFE team.
obj = builder_->type_translator_.BuildType().raw();
ASSERT(obj.IsAbstractType());
break;
case ConstantPoolTag::kTypeArguments:
- UNIMPLEMENTED(); // Encoding is under discussion with CFE team.
obj = builder_->type_translator_
.BuildTypeArguments(builder_->ReadListLength())
.raw();
@@ -2157,6 +2155,9 @@
ExitScope(builder_->reader_.min_position(),
builder_->reader_.max_position());
}
+
+ FinalizeCatchVariables();
+
--depth_.catch_;
return;
}
@@ -2174,6 +2175,8 @@
VisitStatement(); // read finalizer.
+ FinalizeCatchVariables();
+
--depth_.catch_;
return;
}
@@ -2598,6 +2601,30 @@
variables->Add(v);
}
+void StreamingScopeBuilder::FinalizeExceptionVariable(
+ GrowableArray<LocalVariable*>* variables,
+ GrowableArray<LocalVariable*>* raw_variables,
+ const String& symbol,
+ intptr_t nesting_depth) {
+ // No need to create variables for try/catch-statements inside
+ // nested functions.
+ if (depth_.function_ > 0) return;
+
+ LocalVariable* variable = (*variables)[nesting_depth - 1];
+ LocalVariable* raw_variable;
+ if (variable->is_captured()) {
+ raw_variable =
+ new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+ symbol, AbstractType::dynamic_type());
+ const bool ok = scope_->AddVariable(raw_variable);
+ ASSERT(ok);
+ } else {
+ raw_variable = variable;
+ }
+ raw_variables->EnsureLength(nesting_depth, nullptr);
+ (*raw_variables)[nesting_depth - 1] = raw_variable;
+}
+
void StreamingScopeBuilder::AddTryVariables() {
AddExceptionVariable(&result_->catch_context_variables,
":saved_try_context_var", depth_.try_);
@@ -2610,6 +2637,16 @@
depth_.catch_);
}
+void StreamingScopeBuilder::FinalizeCatchVariables() {
+ const intptr_t unique_id = result_->raw_variable_counter_++;
+ FinalizeExceptionVariable(
+ &result_->exception_variables, &result_->raw_exception_variables,
+ GenerateName(":raw_exception", unique_id), depth_.catch_);
+ FinalizeExceptionVariable(
+ &result_->stack_trace_variables, &result_->raw_stack_trace_variables,
+ GenerateName(":raw_stacktrace", unique_id), depth_.catch_);
+}
+
void StreamingScopeBuilder::AddIteratorVariable() {
if (depth_.function_ > 0) return;
if (result_->iterator_variables.length() >= depth_.for_in_) return;
@@ -5191,6 +5228,46 @@
return instructions;
}
+// If no type arguments are passed to a generic function, we need to fill the
+// type arguments in with the default types stored on the TypeParameter nodes
+// in Kernel.
+Fragment StreamingFlowGraphBuilder::BuildDefaultTypeHandling(
+ const Function& function,
+ intptr_t type_parameters_offset) {
+ if (function.IsGeneric() && I->reify_generic_functions()) {
+ AlternativeReadingScope alt(&reader_);
+ SetOffset(type_parameters_offset);
+ intptr_t num_type_params = ReadListLength();
+ ASSERT(num_type_params == function.NumTypeParameters());
+ TypeArguments& default_types =
+ TypeArguments::ZoneHandle(TypeArguments::New(num_type_params));
+ for (intptr_t i = 0; i < num_type_params; ++i) {
+ TypeParameterHelper helper(this);
+ helper.ReadUntilExcludingAndSetJustRead(
+ TypeParameterHelper::kDefaultType);
+ if (ReadTag() == kSomething) {
+ default_types.SetTypeAt(i, T.BuildType());
+ } else {
+ default_types.SetTypeAt(i, Object::dynamic_type());
+ }
+ helper.Finish();
+ }
+ default_types = default_types.Canonicalize();
+
+ if (!default_types.IsNull()) {
+ // clang-format off
+ return B->TestAnyTypeArgs(/*then=*/{}, /*else=*/{
+ TranslateInstantiatedTypeArguments(default_types),
+ StoreLocal(TokenPosition::kNoSource,
+ parsed_function()->function_type_arguments()),
+ Drop()
+ });
+ // clang-format on
+ }
+ }
+ return Fragment();
+}
+
FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
const Function& function) {
const Function& parent = Function::ZoneHandle(Z, function.parent_function());
@@ -5227,6 +5304,11 @@
body +=
flow_graph_builder_->CheckStackOverflowInPrologue(function.token_pos());
+ FunctionNodeHelper function_node_helper(this);
+ function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
+
+ body += BuildDefaultTypeHandling(function, ReaderOffset());
+
intptr_t type_args_len = 0;
if (I->reify_generic_functions() && function.IsGeneric()) {
type_args_len = function.NumTypeParameters();
@@ -5235,9 +5317,6 @@
body += PushArgument();
}
- FunctionNodeHelper function_node_helper(this);
- function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
-
if (I->argument_type_checks()) {
if (!target.NeedsArgumentTypeChecks(I)) {
// Tearoffs of static methods needs to perform arguments checks since
@@ -5376,27 +5455,13 @@
body += StoreLocal(TokenPosition::kNoSource, argument_count_var);
body += Drop();
if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
- Fragment test_generic;
- JoinEntryInstr* join = BuildJoinEntry();
-
- TargetEntryInstr *passed_type_args, *not_passed_type_args;
- test_generic += B->LoadArgDescriptor();
- test_generic += LoadField(ArgumentsDescriptor::type_args_len_offset());
- test_generic += IntConstant(0);
- test_generic += BranchIfEqual(¬_passed_type_args, &passed_type_args,
- /*negate=*/false);
-
- Fragment passed_type_args_frag(passed_type_args);
- passed_type_args_frag += IntConstant(1);
- passed_type_args_frag +=
- StoreLocal(TokenPosition::kNoSource, argument_count_var);
- passed_type_args_frag += Drop();
- passed_type_args_frag += Goto(join);
-
- Fragment not_passed_type_args_frag(not_passed_type_args);
- not_passed_type_args_frag += Goto(join);
-
- body += Fragment(test_generic.entry, join);
+ // clang-format off
+ body += flow_graph_builder_->TestAnyTypeArgs(/*then=*/{
+ IntConstant(1),
+ StoreLocal(TokenPosition::kNoSource, argument_count_var),
+ Drop()
+ }, /*else=*/{});
+ // clang-format on
}
if (function.HasOptionalParameters()) {
@@ -5413,7 +5478,13 @@
//
// var arguments = new Array<dynamic>(argument_count);
//
- // for (int i = 0; i < argument_count; ++i) {
+ // int i = 0;
+ // if (any type arguments are passed) {
+ // arguments[0] = function_type_arguments;
+ // ++i;
+ // }
+ //
+ // for (; i < argument_count; ++i) {
// arguments[i] = LoadFpRelativeSlot(
// kWordSize * (kParamEndSlotFromFp + argument_count - i));
// }
@@ -5429,6 +5500,26 @@
body += StoreLocal(TokenPosition::kNoSource, index);
body += Drop();
+ // if (any type arguments are passed) {
+ // arguments[0] = function_type_arguments;
+ // i = 1;
+ // }
+ if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
+ // clang-format off
+ Fragment store_type_arguments = {
+ LoadLocal(arguments),
+ IntConstant(0),
+ LoadFunctionTypeArguments(),
+ StoreIndexed(kArrayCid),
+ Drop(),
+ IntConstant(1),
+ StoreLocal(TokenPosition::kNoSource, index),
+ Drop()
+ };
+ // clang-format on
+ body += B->TestAnyTypeArgs(store_type_arguments, {});
+ }
+
TargetEntryInstr* body_entry;
TargetEntryInstr* loop_exit;
@@ -5515,10 +5606,6 @@
body += LoadLocal(arguments);
body += PushArgument();
- // false -> this is not super NSM
- body += Constant(Bool::False());
- body += PushArgument();
-
if (throw_no_such_method_error) {
const Function& parent =
Function::ZoneHandle(Z, function.parent_function());
@@ -5541,12 +5628,30 @@
}
body += PushArgument();
+ // Push the number of delayed type arguments.
+ if (function.IsClosureFunction()) {
+ LocalVariable* closure =
+ parsed_function()->node_sequence()->scope()->VariableAt(0);
+ body += B->TestDelayedTypeArgs(
+ closure,
+ Fragment({IntConstant(function.NumTypeParameters()),
+ StoreLocal(TokenPosition::kNoSource, argument_count_var),
+ Drop()}),
+ Fragment({IntConstant(0),
+ StoreLocal(TokenPosition::kNoSource, argument_count_var),
+ Drop()}));
+ body += LoadLocal(argument_count_var);
+ } else {
+ body += IntConstant(0);
+ }
+ body += PushArgument();
+
const Class& mirror_class =
Class::Handle(Z, Library::LookupCoreClass(Symbols::InvocationMirror()));
ASSERT(!mirror_class.IsNull());
const Function& allocation_function = Function::ZoneHandle(
- Z, mirror_class.LookupStaticFunction(
- Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror())));
+ Z, mirror_class.LookupStaticFunction(Library::PrivateCoreLibName(
+ Symbols::AllocateInvocationMirrorForClosure())));
ASSERT(!allocation_function.IsNull());
body += StaticCall(TokenPosition::kMinSource, allocation_function,
/* argument_count = */ 5, ICData::kStatic);
@@ -5912,6 +6017,9 @@
// body because it needs to be executed everytime we enter the function -
// even if we are resuming from the yield.
Fragment prologue;
+
+ prologue += BuildDefaultTypeHandling(dart_function, type_parameters_offset);
+
if (dart_function.IsClosureFunction() &&
dart_function.NumParentTypeParameters() > 0 &&
I->reify_generic_functions()) {
@@ -10912,51 +11020,39 @@
// Read metadataMappings elements.
for (uint32_t i = 0; i < metadata_num; ++i) {
- // Read nodeReferences length.
+ // Read nodeOffsetToMetadataOffset length.
offset -= kUInt32Size;
- uint32_t node_references_num = reader.ReadUInt32At(offset);
-
- // Skip nodeReferences and read nodeOffsetToMetadataOffset length.
- offset -= node_references_num * kUInt32Size + kUInt32Size;
uint32_t mappings_num = reader.ReadUInt32At(offset);
// Skip nodeOffsetToMetadataOffset and read tag.
offset -= mappings_num * 2 * kUInt32Size + kUInt32Size;
StringIndex tag = StringIndex(reader.ReadUInt32At(offset));
+ if (mappings_num == 0) {
+ continue;
+ }
+
// Check recognized metadata
if (H.StringEquals(tag, DirectCallMetadataHelper::tag())) {
- ASSERT(node_references_num == 0);
-
- if (mappings_num > 0) {
- if (!FLAG_precompiled_mode) {
- FATAL("DirectCallMetadata is allowed in precompiled mode only");
- }
- direct_call_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
- mappings_num);
+ if (!FLAG_precompiled_mode) {
+ FATAL("DirectCallMetadata is allowed in precompiled mode only");
}
+ direct_call_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
+ mappings_num);
} else if (H.StringEquals(tag, InferredTypeMetadataHelper::tag())) {
- ASSERT(node_references_num == 0);
-
- if (mappings_num > 0) {
- if (!FLAG_precompiled_mode) {
- FATAL("InferredTypeMetadata is allowed in precompiled mode only");
- }
- inferred_type_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
- mappings_num);
+ if (!FLAG_precompiled_mode) {
+ FATAL("InferredTypeMetadata is allowed in precompiled mode only");
}
+ inferred_type_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
+ mappings_num);
} else if (H.StringEquals(tag, ProcedureAttributesMetadataHelper::tag())) {
- ASSERT(node_references_num == 0);
-
- if (mappings_num > 0) {
- if (!FLAG_precompiled_mode) {
- FATAL(
- "ProcedureAttributesMetadata is allowed in precompiled mode "
- "only");
- }
- procedure_attributes_metadata_helper_.SetMetadataMappings(
- offset + kUInt32Size, mappings_num);
+ if (!FLAG_precompiled_mode) {
+ FATAL(
+ "ProcedureAttributesMetadata is allowed in precompiled mode "
+ "only");
}
+ procedure_attributes_metadata_helper_.SetMetadataMappings(
+ offset + kUInt32Size, mappings_num);
} else if (H.StringEquals(tag, BytecodeMetadataHelper::tag())) {
bytecode_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
mappings_num);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 77d8ce6..a8b39a4 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -327,9 +327,6 @@
bool IsRedirectingFactoryConstructor() {
return (flags_ & kRedirectingFactoryConstructor) != 0;
}
- bool IsNoSuchMethodForwarder() {
- return (flags_ & kNoSuchMethodForwarder) != 0;
- }
NameIndex canonical_name_;
TokenPosition position_;
@@ -825,8 +822,14 @@
const char* prefix,
intptr_t nesting_depth);
+ void FinalizeExceptionVariable(GrowableArray<LocalVariable*>* variables,
+ GrowableArray<LocalVariable*>* raw_variables,
+ const String& symbol,
+ intptr_t nesting_depth);
+
void AddTryVariables();
void AddCatchVariables();
+ void FinalizeCatchVariables();
void AddIteratorVariable();
void AddSwitchVariable();
@@ -1392,6 +1395,10 @@
kTypeChecksForNoDynamicInvocationsTearOff
};
+ // Does not move the cursor.
+ Fragment BuildDefaultTypeHandling(const Function& function,
+ intptr_t type_parameters_offset);
+
Fragment BuildArgumentTypeChecks(TypeChecksToBuild mode = kDefaultTypeChecks);
Fragment ThrowException(TokenPosition position);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index aa1cb20..6b5a9af 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1178,19 +1178,54 @@
intptr_t handler_index,
bool needs_stacktrace,
bool is_synthesized) {
- ASSERT(CurrentException()->is_captured() ==
- CurrentStackTrace()->is_captured());
- const bool should_restore_closure_context =
- CurrentException()->is_captured() || CurrentCatchContext()->is_captured();
+ LocalVariable* exception_var = CurrentException();
+ LocalVariable* stacktrace_var = CurrentStackTrace();
+ LocalVariable* raw_exception_var = CurrentRawException();
+ LocalVariable* raw_stacktrace_var = CurrentRawStackTrace();
+
CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
TokenPosition::kNoSource, // Token position of catch block.
is_synthesized, // whether catch block was synthesized by FE compiler
AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types,
- handler_index, *CurrentException(), *CurrentStackTrace(),
- needs_stacktrace, GetNextDeoptId(), should_restore_closure_context);
+ handler_index, *exception_var, *stacktrace_var, needs_stacktrace,
+ GetNextDeoptId(), raw_exception_var, raw_stacktrace_var);
graph_entry_->AddCatchEntry(entry);
+
Fragment instructions(entry);
+ // Auxiliary variables introduced by the try catch can be captured if we are
+ // inside a function with yield/resume points. In this case we first need
+ // to restore the context to match the context at entry into the closure.
+ const bool should_restore_closure_context =
+ CurrentException()->is_captured() || CurrentCatchContext()->is_captured();
+ LocalVariable* context_variable = parsed_function_->current_context_var();
+ if (should_restore_closure_context) {
+ ASSERT(parsed_function_->function().IsClosureFunction());
+ LocalScope* scope = parsed_function_->node_sequence()->scope();
+
+ LocalVariable* closure_parameter = scope->VariableAt(0);
+ ASSERT(!closure_parameter->is_captured());
+ instructions += LoadLocal(closure_parameter);
+ instructions += LoadField(Closure::context_offset());
+ instructions += StoreLocal(TokenPosition::kNoSource, context_variable);
+ instructions += Drop();
+ }
+
+ if (exception_var->is_captured()) {
+ instructions += LoadLocal(context_variable);
+ instructions += LoadLocal(raw_exception_var);
+ instructions +=
+ StoreInstanceField(TokenPosition::kNoSource,
+ Context::variable_offset(exception_var->index()));
+ }
+ if (stacktrace_var->is_captured()) {
+ instructions += LoadLocal(context_variable);
+ instructions += LoadLocal(raw_stacktrace_var);
+ instructions +=
+ StoreInstanceField(TokenPosition::kNoSource,
+ Context::variable_offset(stacktrace_var->index()));
+ }
+
// :saved_try_context_var can be captured in the context of
// of the closure, in this case CatchBlockEntryInstr restores
// :current_context_var to point to closure context in the
@@ -1385,6 +1420,28 @@
return Fragment(test.entry, join);
}
+Fragment BaseFlowGraphBuilder::TestAnyTypeArgs(Fragment present,
+ Fragment absent) {
+ if (parsed_function_->function().IsClosureFunction()) {
+ LocalVariable* closure =
+ parsed_function_->node_sequence()->scope()->VariableAt(0);
+
+ JoinEntryInstr* complete = BuildJoinEntry();
+ JoinEntryInstr* present_entry = BuildJoinEntry();
+
+ Fragment test = TestTypeArgsLen(
+ TestDelayedTypeArgs(closure, Goto(present_entry), absent),
+ Goto(present_entry), 0);
+ test += Goto(complete);
+
+ Fragment(present_entry) + present + Goto(complete);
+
+ return Fragment(test.entry, complete);
+ } else {
+ return TestTypeArgsLen(absent, present, 0);
+ }
+}
+
Fragment FlowGraphBuilder::RethrowException(TokenPosition position,
int catch_try_index) {
Fragment instructions;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 817633f..a22d222 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -7,6 +7,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
+#include <functional>
#include <initializer_list>
#include "vm/growable_array.h"
@@ -484,7 +485,8 @@
finally_return_variable(NULL),
setter_value(NULL),
yield_jump_variable(NULL),
- yield_context_variable(NULL) {}
+ yield_context_variable(NULL),
+ raw_variable_counter_(0) {}
IntMap<LocalVariable*> locals;
IntMap<LocalScope*> scopes;
@@ -521,6 +523,12 @@
GrowableArray<LocalVariable*> stack_trace_variables;
GrowableArray<LocalVariable*> catch_context_variables;
+ // These are used to access the raw exception/stacktrace variables (and are
+ // used to put them into the captured variables in the context).
+ GrowableArray<LocalVariable*> raw_exception_variables;
+ GrowableArray<LocalVariable*> raw_stack_trace_variables;
+ intptr_t raw_variable_counter_;
+
// For-in iterators, one per for-in nesting level.
GrowableArray<LocalVariable*> iterator_variables;
};
@@ -647,6 +655,7 @@
Fragment TestDelayedTypeArgs(LocalVariable* closure,
Fragment present,
Fragment absent);
+ Fragment TestAnyTypeArgs(Fragment present, Fragment absent);
JoinEntryInstr* BuildThrowNoSuchMethod();
@@ -869,6 +878,12 @@
LocalVariable* CurrentStackTrace() {
return scopes_->stack_trace_variables[catch_depth_ - 1];
}
+ LocalVariable* CurrentRawException() {
+ return scopes_->raw_exception_variables[catch_depth_ - 1];
+ }
+ LocalVariable* CurrentRawStackTrace() {
+ return scopes_->raw_stack_trace_variables[catch_depth_ - 1];
+ }
LocalVariable* CurrentCatchContext() {
return scopes_->catch_context_variables[try_depth_];
}
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 18225e6..0430ef9 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -1043,9 +1043,25 @@
// We got an error during compilation.
error = thread->sticky_error();
thread->clear_sticky_error();
- if ((error.IsLanguageError() &&
- LanguageError::Cast(error).kind() == Report::kBailout) ||
- error.IsUnhandledException()) {
+
+ if (error.raw() == Object::background_compilation_error().raw()) {
+ if (FLAG_trace_compiler) {
+ THR_Print(
+ "--> disabling background optimizations for '%s' (will "
+ "try to re-compile on isolate thread again)\n",
+ function.ToFullyQualifiedCString());
+ }
+
+ // Ensure we don't attempt to re-compile the function on the
+ // background compiler.
+ function.set_is_background_optimizable(false);
+
+ // Trigger another optimization soon on the main thread.
+ function.SetUsageCounter(FLAG_optimization_counter_threshold);
+ } else if ((error.IsLanguageError() &&
+ LanguageError::Cast(error).kind() ==
+ Report::kBailout) ||
+ error.IsUnhandledException()) {
if (FLAG_trace_compiler) {
THR_Print("--> disabling optimizations for '%s'\n",
function.ToFullyQualifiedCString());
@@ -1287,7 +1303,8 @@
// not currently allowed.
ASSERT(!thread->IsMutatorThread() || (osr_id != kNoOSRDeoptId) ||
!FLAG_background_compilation ||
- BackgroundCompiler::IsDisabled(Isolate::Current()));
+ BackgroundCompiler::IsDisabled(Isolate::Current()) ||
+ !function.is_background_optimizable());
CompilationPipeline* pipeline =
CompilationPipeline::New(thread->zone(), function);
return CompileFunctionHelper(pipeline, function, true, /* optimized */
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 091dd5d..bbc4d16 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -179,6 +179,10 @@
}
ISOLATE_UNIT_TEST_CASE(EvalExpressionWithLazyCompile) {
+ { // Initialize an incremental compiler in DFE mode.
+ TransitionVMToNative transition(thread);
+ TestCase::LoadTestScript("", NULL);
+ }
Library& lib = Library::Handle(Library::CoreLibrary());
const String& expression = String::Handle(
@@ -193,6 +197,10 @@
}
ISOLATE_UNIT_TEST_CASE(EvalExpressionExhaustCIDs) {
+ { // Initialize an incremental compiler in DFE mode.
+ TransitionVMToNative transition(thread);
+ TestCase::LoadTestScript("", NULL);
+ }
Library& lib = Library::Handle(Library::CoreLibrary());
const String& expression = String::Handle(String::New("3 + 4"));
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 4efa972..09ce27c 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -137,6 +137,7 @@
SetFileCallbacks(file_open, file_read, file_write, file_close);
set_entropy_source_callback(entropy_source);
OS::InitOnce();
+ NOT_IN_PRODUCT(CodeObservers::InitOnce());
start_time_micros_ = OS::GetCurrentMonotonicMicros();
VirtualMemory::InitOnce();
OSThread::InitOnce();
@@ -152,7 +153,6 @@
ForwardingCorpse::InitOnce();
Api::InitOnce();
NativeSymbolResolver::InitOnce();
- NOT_IN_PRODUCT(CodeObservers::InitOnce());
NOT_IN_PRODUCT(Profiler::InitOnce());
SemiSpace::InitOnce();
NOT_IN_PRODUCT(Metric::InitOnce());
@@ -504,8 +504,8 @@
const uint8_t* snapshot_instructions,
const uint8_t* shared_data,
const uint8_t* shared_instructions,
- intptr_t snapshot_length,
- kernel::Program* kernel_program,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size,
void* data) {
// Initialize the new isolate.
Thread* T = Thread::Current();
@@ -524,11 +524,11 @@
}
Error& error = Error::Handle(T->zone());
- error = Object::Init(I, kernel_program);
+ error = Object::Init(I, kernel_buffer, kernel_buffer_size);
if (!error.IsNull()) {
return error.raw();
}
- if ((snapshot_data != NULL) && kernel_program == NULL) {
+ if ((snapshot_data != NULL) && kernel_buffer == NULL) {
// Read the snapshot and setup the initial state.
NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
"IsolateSnapshotReader"));
@@ -567,7 +567,7 @@
MegamorphicCacheTable::PrintSizes(I);
}
} else {
- if ((vm_snapshot_kind_ != Snapshot::kNone) && kernel_program == NULL) {
+ if ((vm_snapshot_kind_ != Snapshot::kNone) && kernel_buffer == NULL) {
const String& message =
String::Handle(String::New("Missing isolate snapshot"));
return ApiError::New(message);
@@ -592,7 +592,7 @@
Code::Handle(I->object_store()->megamorphic_miss_code());
I->set_ic_miss_code(miss_code);
- if ((snapshot_data == NULL) || (kernel_program != NULL)) {
+ if ((snapshot_data == NULL) || (kernel_buffer != NULL)) {
const Error& error = Error::Handle(I->object_store()->PreallocateObjects());
if (!error.IsNull()) {
return error.raw();
@@ -677,6 +677,10 @@
FLAG_error_on_bad_type);
ADD_FLAG(error_on_bad_override, enable_error_on_bad_override,
FLAG_error_on_bad_override);
+ // sync-async and reify_generic_functions also affect deopt_ids.
+ ADD_FLAG(sync_async, sync_async, FLAG_sync_async);
+ ADD_FLAG(reify_generic_functions, reify_generic_functions,
+ FLAG_reify_generic_functions);
if (kind == Snapshot::kFullJIT) {
ADD_FLAG(use_field_guards, use_field_guards, FLAG_use_field_guards);
ADD_FLAG(use_osr, use_osr, FLAG_use_osr);
@@ -717,7 +721,9 @@
}
void Dart::RunShutdownCallback() {
- Isolate* isolate = Isolate::Current();
+ Thread* thread = Thread::Current();
+ ASSERT(thread->execution_state() == Thread::kThreadInNative);
+ Isolate* isolate = thread->isolate();
void* callback_data = isolate->init_callback_data();
Dart_IsolateShutdownCallback callback = Isolate::ShutdownCallback();
if (callback != NULL) {
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index ce8b5e0..76243b3 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -50,8 +50,8 @@
const uint8_t* snapshot_instructions,
const uint8_t* shared_data,
const uint8_t* shared_instructions,
- intptr_t snapshot_length,
- kernel::Program* kernel_program,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size,
void* data);
static void RunShutdownCallback();
static void ShutdownIsolate(Isolate* isolate);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 26bb097..02fa964 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1101,8 +1101,8 @@
const uint8_t* snapshot_instructions,
const uint8_t* shared_data,
const uint8_t* shared_instructions,
- intptr_t snapshot_length,
- kernel::Program* kernel_program,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size,
Dart_IsolateFlags* flags,
void* callback_data,
char** error) {
@@ -1131,14 +1131,14 @@
// bootstrap library files which call out to a tag handler that may create
// Api Handles when an error is encountered.
Dart_EnterScope();
- const Error& error_obj =
- Error::Handle(Z, Dart::InitializeIsolate(
- snapshot_data, snapshot_instructions, shared_data,
- shared_instructions, snapshot_length,
- kernel_program, callback_data));
+ const Error& error_obj = Error::Handle(
+ Z,
+ Dart::InitializeIsolate(snapshot_data, snapshot_instructions,
+ shared_data, shared_instructions, kernel_buffer,
+ kernel_buffer_size, callback_data));
if (error_obj.IsNull()) {
#if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT)
- if (FLAG_check_function_fingerprints && kernel_program == NULL) {
+ if (FLAG_check_function_fingerprints && kernel_buffer == NULL) {
Library::CheckFunctionFingerprints();
}
#endif // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT).
@@ -1181,16 +1181,18 @@
char** error) {
API_TIMELINE_DURATION(Thread::Current());
return CreateIsolate(script_uri, main, snapshot_data, snapshot_instructions,
- shared_data, shared_instructions, -1, NULL, flags,
+ shared_data, shared_instructions, NULL, 0, flags,
callback_data, error);
}
-DART_EXPORT Dart_Isolate Dart_CreateIsolateFromKernel(const char* script_uri,
- const char* main,
- void* kernel_program,
- Dart_IsolateFlags* flags,
- void* callback_data,
- char** error) {
+DART_EXPORT Dart_Isolate
+Dart_CreateIsolateFromKernel(const char* script_uri,
+ const char* main,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size,
+ Dart_IsolateFlags* flags,
+ void* callback_data,
+ char** error) {
API_TIMELINE_DURATION(Thread::Current());
// Setup default flags in case none were passed.
Dart_IsolateFlags api_flags;
@@ -1199,9 +1201,8 @@
flags = &api_flags;
}
flags->use_dart_frontend = true;
- return CreateIsolate(script_uri, main, NULL, NULL, NULL, NULL, -1,
- reinterpret_cast<kernel::Program*>(kernel_program),
- flags, callback_data, error);
+ return CreateIsolate(script_uri, main, NULL, NULL, NULL, NULL, kernel_buffer,
+ kernel_buffer_size, flags, callback_data, error);
}
DART_EXPORT void Dart_ShutdownIsolate() {
@@ -5153,17 +5154,6 @@
lib.SetLoadError(Object::null_instance());
}
}
-
-static Dart_Handle LoadKernelProgram(Thread* T,
- const String& url,
- void* kernel) {
- // NOTE: Now the VM owns the [kernel_program] memory!
- // We will promptly delete it when done.
- kernel::Program* program = reinterpret_cast<kernel::Program*>(kernel);
- const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
- delete program;
- return Api::NewHandle(T, tmp.raw());
-}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
@@ -5207,27 +5197,8 @@
Dart_Handle result;
if (I->use_dart_frontend()) {
- // TODO(kernel): Fix callers to use Dart_LoadScriptFromKernel.
- if ((source == Api::Null()) || (source == NULL)) {
- RETURN_NULL_ERROR(source);
- }
- void* kernel_pgm = reinterpret_cast<void*>(source);
- result = LoadKernelProgram(T, resolved_url_str, kernel_pgm);
- if (::Dart_IsError(result)) {
- return result;
- }
- library ^= Library::LookupLibrary(T, resolved_url_str);
- if (library.IsNull()) {
- // If the URL string does not match, use the library object
- // returned by the kernel loader.
- library ^= Api::UnwrapHandle(result);
- }
- if (library.IsNull()) {
- return Api::NewError("%s: Unable to load script '%s' correctly.",
- CURRENT_FUNC, resolved_url_str.ToCString());
- }
- I->object_store()->set_root_library(library);
- return Api::NewHandle(T, library.raw());
+ return Api::NewError("%s: Should not be called with using Dart frontend",
+ CURRENT_FUNC);
}
const String& source_str = Api::UnwrapStringHandle(Z, source);
@@ -5319,20 +5290,6 @@
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
-DART_EXPORT void* Dart_ReadKernelBinary(const uint8_t* buffer,
- intptr_t buffer_len,
- Dart_ReleaseBufferCallback callback) {
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
- return NULL;
-#else
- kernel::Program* program =
- kernel::Program::ReadFromBuffer(buffer, buffer_len);
- program->set_release_buffer_callback(callback);
- return program;
-#endif
-}
-
DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t* buffer,
intptr_t buffer_size) {
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -5360,7 +5317,7 @@
if (tmp.IsError()) {
return Api::NewHandle(T, tmp.raw());
}
- // TODO(kernel): Setting root library based on whether it has 'main' or not
+ // TODO(32618): Setting root library based on whether it has 'main' or not
// is not correct because main can be in the exported namespace of a library
// or it could be a getter.
if (tmp.IsNull()) {
@@ -5576,13 +5533,8 @@
}
Dart_Handle result;
if (I->use_dart_frontend()) {
- // TODO(kernel): Fix callers to use Dart_LoadLibraryFromKernel.
- void* kernel_pgm = reinterpret_cast<void*>(source);
- result = LoadKernelProgram(T, url_str, kernel_pgm);
- if (::Dart_IsError(result)) {
- return result;
- }
- return Api::NewHandle(T, Library::LookupLibrary(T, url_str));
+ return Api::NewError("%s: Should not be called with using Dart frontend",
+ CURRENT_FUNC);
}
if (::Dart_IsNull(resolved_url)) {
resolved_url = url;
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 5370e37..52bd15c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3394,21 +3394,20 @@
static Dart_Handle LoadScript(const char* url_str, const char* source) {
Dart_Handle url = NewString(url_str);
Dart_Handle result;
- Dart_Handle script;
if (!FLAG_use_dart_frontend) {
result = Dart_SetLibraryTagHandler(TestCase::library_handler);
EXPECT_VALID(result);
- script = NewString(source);
+ return Dart_LoadScript(url, Dart_Null(), NewString(source), 0, 0);
} else {
- void* kernel_pgm = NULL;
- char* error =
- TestCase::CompileTestScriptWithDFE(url_str, source, &kernel_pgm);
+ const uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
+ char* error = TestCase::CompileTestScriptWithDFE(
+ url_str, source, &kernel_buffer, &kernel_buffer_size);
if (error != NULL) {
return Dart_NewApiError(error);
}
- script = reinterpret_cast<Dart_Handle>(kernel_pgm);
+ return Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size);
}
- return Dart_LoadScript(url, Dart_Null(), script, 0, 0);
}
VM_UNIT_TEST_CASE(DartAPI_IsolateSetCheckedMode) {
@@ -7177,6 +7176,12 @@
static int64_t add_result = 0;
static void IsolateShutdownRunDartCodeTestCallback(void* callback_data) {
+ Dart_Isolate isolate = Dart_CurrentIsolate();
+ if (Dart_IsKernelIsolate(isolate) || Dart_IsServiceIsolate(isolate)) {
+ return;
+ } else {
+ ASSERT(add_result == 0);
+ }
Dart_EnterScope();
Dart_Handle lib = Dart_RootLibrary();
EXPECT_VALID(lib);
@@ -7210,12 +7215,10 @@
{
Dart_EnterScope();
- Dart_Handle url = NewString(TestCase::url());
- Dart_Handle source = NewString(kScriptChars);
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ EXPECT_VALID(lib);
Dart_Handle result = Dart_SetLibraryTagHandler(TestCase::library_handler);
EXPECT_VALID(result);
- Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
- EXPECT_VALID(lib);
result = Dart_FinalizeLoading(false);
EXPECT_VALID(result);
result = Dart_Invoke(lib, NewString("main"), 0, NULL);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 85adc30..559b954 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1266,6 +1266,8 @@
const GrowableObjectArray& param_names,
const GrowableObjectArray& param_values) {
GetDescIndices();
+ bool type_arguments_available = false;
+ TypeArguments& type_arguments = TypeArguments::Handle();
String& name = String::Handle();
String& existing_name = String::Handle();
Object& value = Instance::Handle();
@@ -1273,7 +1275,11 @@
for (intptr_t i = 0; i < num_variables; i++) {
TokenPosition ignore;
VariableAt(i, &name, &ignore, &ignore, &ignore, &value);
- if (!name.Equals(Symbols::This()) && !IsSyntheticVariableName(name)) {
+ if (name.Equals(Symbols::FunctionTypeArgumentsVar())) {
+ type_arguments_available = true;
+ type_arguments = TypeArguments::RawCast(value.raw());
+ } else if (!name.Equals(Symbols::This()) &&
+ !IsSyntheticVariableName(name)) {
if (IsPrivateVariableName(name)) {
name = String::ScrubName(name);
}
@@ -1295,11 +1301,44 @@
}
}
+ Array& type_param_names = Array::Handle();
+ if ((function().IsGeneric() || function().HasGenericParent()) &&
+ type_arguments_available) {
+ intptr_t num_vars =
+ function().NumTypeParameters() + function().NumParentTypeParameters();
+ type_param_names = Array::New(num_vars);
+ TypeArguments& type_params = TypeArguments::Handle();
+ TypeParameter& type_param = TypeParameter::Handle();
+ String& name = String::Handle();
+ Function& current = Function::Handle(function().raw());
+ for (intptr_t i = 0; !current.IsNull(); i += current.NumTypeParameters(),
+ current = current.parent_function()) {
+ type_params = current.type_parameters();
+ for (intptr_t j = 0; j < current.NumTypeParameters(); ++j) {
+ type_param = TypeParameter::RawCast(type_params.TypeAt(j));
+ name = type_param.Name();
+ // Write the names in backwards so they match up with the order of the
+ // types in 'type_arguments'.
+ type_param_names.SetAt(num_vars - (i + j) - 1, name);
+ }
+ }
+ if (type_arguments.IsNull()) {
+ type_arguments = TypeArguments::New(num_vars);
+ for (intptr_t i = 0; i < num_vars; ++i) {
+ type_arguments.SetTypeAt(i, Object::dynamic_type());
+ }
+ }
+ ASSERT(type_arguments.Length() == num_vars);
+ } else {
+ type_param_names = Object::empty_array().raw();
+ }
+
if (function().is_static()) {
const Class& cls = Class::Handle(function().Owner());
return cls.Evaluate(expr,
Array::Handle(Array::MakeFixedLength(param_names)),
- Array::Handle(Array::MakeFixedLength(param_values)));
+ Array::Handle(Array::MakeFixedLength(param_values)),
+ type_param_names, type_arguments);
} else {
const Object& receiver = Object::Handle(GetReceiver());
const Class& method_cls = Class::Handle(function().origin());
@@ -1310,7 +1349,8 @@
const Instance& inst = Instance::Cast(receiver);
return inst.Evaluate(method_cls, expr,
Array::Handle(Array::MakeFixedLength(param_names)),
- Array::Handle(Array::MakeFixedLength(param_values)));
+ Array::Handle(Array::MakeFixedLength(param_values)),
+ type_param_names, type_arguments);
}
UNREACHABLE();
return Object::null();
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index ff62dbf..36452aa 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -74,6 +74,8 @@
"Emit DWARF line number and inlining info" \
"in dylib snapshots and don't symbolize stack traces.") \
R(enable_asserts, false, bool, false, "Enable assert statements.") \
+ P(enable_kernel_expression_compilation, bool, true, \
+ "Compile expressions with the Kernel front-end.") \
P(enable_mirrors, bool, true, \
"Disable to make importing dart:mirrors an error.") \
R(enable_type_checks, false, bool, false, "Enable type checks.") \
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 725c385..d8b68f7 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -563,7 +563,7 @@
last_setjmp_buffer_ = NULL;
top_exit_frame_info_ = 0;
- DEBUG_ONLY(icount_ = 0);
+ DEBUG_ONLY(icount_ = 1); // So that tracing after 0 traces first bytecode.
}
Interpreter::~Interpreter() {
@@ -586,6 +586,7 @@
#if defined(DEBUG)
// Returns true if tracing of executed instructions is enabled.
+// May be called on entry, when icount_ has not been incremented yet.
DART_FORCE_INLINE bool Interpreter::IsTracingExecution() const {
return icount_ > FLAG_trace_interpreter_after;
}
@@ -624,6 +625,12 @@
frame[3] = reinterpret_cast<RawObject*>(base);
fp_ = frame + kKBCDartFrameFixedSize;
thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_));
+#if defined(DEBUG)
+ if (IsTracingExecution()) {
+ THR_Print("Exiting interpreter 0x%" Px " at fp_ 0x%" Px "\n",
+ reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
+ }
+#endif
}
// TODO(vegorov): Investigate advantages of using
@@ -1119,10 +1126,10 @@
// Counts and prints executed bytecode instructions (in DEBUG mode).
#if defined(DEBUG)
#define TRACE_INSTRUCTION \
- icount_++; \
if (IsTracingExecution()) { \
TraceInstruction(pc - 1); \
- }
+ } \
+ icount_++;
#else
#define TRACE_INSTRUCTION
#endif // defined(DEBUG)
@@ -1240,6 +1247,31 @@
// Corner case: handler PC can be a fake marker that marks entry frame, which
// means exception was not handled in the Dart code. In this case we return
// caught exception from Interpreter::Call.
+#if defined(DEBUG)
+
+#define HANDLE_EXCEPTION \
+ do { \
+ FP = reinterpret_cast<RawObject**>(fp_); \
+ pc = reinterpret_cast<uint32_t*>(pc_); \
+ if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \
+ fp_ = reinterpret_cast<RawObject**>(fp_[0]); \
+ thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); \
+ thread->set_top_resource(top_resource); \
+ thread->set_vm_tag(vm_tag); \
+ if (IsTracingExecution()) { \
+ THR_Print("Returning exception from interpreter 0x%" Px \
+ " at fp_ 0x%" Px "\n", \
+ reinterpret_cast<uword>(this), \
+ reinterpret_cast<uword>(fp_)); \
+ } \
+ return special_[kExceptionSpecialIndex]; \
+ } \
+ pp_ = InterpreterHelpers::FrameCode(FP)->ptr()->object_pool_; \
+ goto DispatchAfterException; \
+ } while (0)
+
+#else // !defined(DEBUG)
+
#define HANDLE_EXCEPTION \
do { \
FP = reinterpret_cast<RawObject**>(fp_); \
@@ -1255,6 +1287,8 @@
goto DispatchAfterException; \
} while (0)
+#endif // !defined(DEBUG)
+
#define HANDLE_RETURN \
do { \
pp_ = InterpreterHelpers::FrameCode(FP)->ptr()->object_pool_; \
@@ -1352,9 +1386,17 @@
uint32_t op; // Currently executing op.
uint16_t rA; // A component of the currently executing op.
- if (fp_ == NULL) {
+ bool reentering = fp_ != NULL;
+ if (!reentering) {
fp_ = reinterpret_cast<RawObject**>(stack_);
}
+#if defined(DEBUG)
+ if (IsTracingExecution()) {
+ THR_Print("%s interpreter 0x%" Px " at fp_ 0x%" Px "\n",
+ reentering ? "Re-entering" : "Entering",
+ reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
+ }
+#endif
// Save current VM tag and mark thread as executing Dart code.
const uword vm_tag = thread->vm_tag();
@@ -1440,9 +1482,122 @@
{
BYTECODE(EntryOptional, A_B_C);
- // TODO(regis): Recover deleted code.
- // See https://dart-review.googlesource.com/c/sdk/+/25320
- UNIMPLEMENTED();
+ const uint16_t num_fixed_params = rA;
+ const uint16_t num_opt_pos_params = rB;
+ const uint16_t num_opt_named_params = rC;
+ const intptr_t min_num_pos_args = num_fixed_params;
+ const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params;
+
+ // Decode arguments descriptor.
+ const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
+ const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
+ const intptr_t named_count = (arg_count - pos_count);
+
+ // Check that got the right number of positional parameters.
+ if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) {
+ goto ClosureNoSuchMethod;
+ }
+
+ // Copy all passed position arguments.
+ RawObject** first_arg = FrameArguments(FP, arg_count);
+ memmove(FP, first_arg, pos_count * kWordSize);
+
+ if (num_opt_named_params != 0) {
+ // This is a function with named parameters.
+ // Walk the list of named parameters and their
+ // default values encoded as pairs of LoadConstant instructions that
+ // follows the entry point and find matching values via arguments
+ // descriptor.
+ RawObject** argdesc_data = argdesc_->ptr()->data();
+
+ intptr_t i = named_count - 1; // argument position
+ intptr_t j = num_opt_named_params - 1; // parameter position
+ while ((j >= 0) && (i >= 0)) {
+ // Fetch formal parameter information: name, default value, target slot.
+ const uint32_t load_name = pc[2 * j];
+ const uint32_t load_value = pc[2 * j + 1];
+ ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
+ KernelBytecode::kLoadConstant);
+ ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
+ KernelBytecode::kLoadConstant);
+ const uint8_t reg = KernelBytecode::DecodeA(load_name);
+ ASSERT(reg == KernelBytecode::DecodeA(load_value));
+
+ RawString* name = static_cast<RawString*>(
+ LOAD_CONSTANT(KernelBytecode::DecodeD(load_name)));
+ if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
+ // Parameter was passed. Fetch passed value.
+ const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
+ argdesc_data[ArgumentsDescriptor::position_index(i)]));
+ FP[reg] = first_arg[arg_index];
+ i--; // Consume passed argument.
+ } else {
+ // Parameter was not passed. Fetch default value.
+ FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+ }
+ j--; // Next formal parameter.
+ }
+
+ // If we have unprocessed formal parameters then initialize them all
+ // using default values.
+ while (j >= 0) {
+ const uint32_t load_name = pc[2 * j];
+ const uint32_t load_value = pc[2 * j + 1];
+ ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
+ KernelBytecode::kLoadConstant);
+ ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
+ KernelBytecode::kLoadConstant);
+ const uint8_t reg = KernelBytecode::DecodeA(load_name);
+ ASSERT(reg == KernelBytecode::DecodeA(load_value));
+
+ FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+ j--;
+ }
+
+ // If we have unprocessed passed arguments that means we have mismatch
+ // between formal parameters and concrete arguments. This can only
+ // occur if the current function is a closure.
+ if (i != -1) {
+ goto ClosureNoSuchMethod;
+ }
+
+ // Skip LoadConstant-s encoding information about named parameters.
+ pc += num_opt_named_params * 2;
+
+ // SP points past copied arguments.
+ SP = FP + num_fixed_params + num_opt_named_params - 1;
+ } else {
+ ASSERT(num_opt_pos_params != 0);
+ if (named_count != 0) {
+ // Function can't have both named and optional positional parameters.
+ // This kind of mismatch can only occur if the current function
+ // is a closure.
+ goto ClosureNoSuchMethod;
+ }
+
+ // Process the list of default values encoded as a sequence of
+ // LoadConstant instructions after EntryOpt bytecode.
+ // Execute only those that correspond to parameters that were not passed.
+ for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params;
+ i++) {
+ const uint32_t load_value = pc[i];
+ ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
+ KernelBytecode::kLoadConstant);
+#if defined(DEBUG)
+ const uint8_t reg = KernelBytecode::DecodeA(load_value);
+ ASSERT((num_fixed_params + i) == reg);
+#endif
+ FP[num_fixed_params + i] =
+ LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+ }
+
+ // Skip LoadConstant-s encoding default values for optional positional
+ // parameters.
+ pc += num_opt_pos_params;
+
+ // SP points past the last copied parameter.
+ SP = FP + max_num_pos_args - 1;
+ }
DISPATCH();
}
@@ -2758,6 +2913,12 @@
thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_));
thread->set_top_resource(top_resource);
thread->set_vm_tag(vm_tag);
+#if defined(DEBUG)
+ if (IsTracingExecution()) {
+ THR_Print("Returning from interpreter 0x%" Px " at fp_ 0x%" Px "\n",
+ reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
+ }
+#endif
return result;
}
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 10ec3e4..61af137 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1611,6 +1611,7 @@
if (!error.IsNull() && !error.IsUnwindError()) {
OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
}
+ TransitionVMToNative transition(thread);
Dart::RunShutdownCallback();
}
// Shut the isolate down.
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index bf2f38c..28c0795 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -140,6 +140,7 @@
V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts) \
V(NONPRODUCT, reify_generic_functions, ReifyGenericFunctions, \
reify_generic_functions, FLAG_reify_generic_functions) \
+ V(NONPRODUCT, sync_async, SyncAsync, sync_async, FLAG_sync_async) \
V(NONPRODUCT, strong, Strong, strong, FLAG_strong) \
V(NONPRODUCT, error_on_bad_type, ErrorOnBadType, enable_error_on_bad_type, \
FLAG_error_on_bad_type) \
@@ -850,6 +851,7 @@
V(ErrorOnBadType) \
V(ErrorOnBadOverride) \
V(ReifyGenericFunctions) \
+ V(SyncAsync) \
V(Strong) \
V(UseFieldGuards) \
V(UseOsr) \
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 984de86..b8f24ef 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -614,8 +614,8 @@
return;
}
did_kernel_compilation = true;
- kernel_program.set(
- kernel::Program::ReadFromBuffer(retval.kernel, retval.kernel_size));
+ kernel_program.set(kernel::Program::ReadFromBuffer(
+ retval.kernel, retval.kernel_size, true));
}
kernel_program.get()->set_release_buffer_callback(ReleaseFetchedBytes);
@@ -1501,8 +1501,8 @@
Become::ElementsForwardIdentity(before, after);
}
- // Rehash constants map for all classes. Constants are hashed by address, and
- // addresses may change during a become operation.
+ // Rehash constants map for all classes. Constants are hashed by content, and
+ // content may have changed from fields being added or removed.
{
TIMELINE_SCOPE(RehashConstants);
I->RehashConstants();
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 1362438..48f8763 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -8,6 +8,7 @@
#include "vm/debugger_api_impl_test.h"
#include "vm/globals.h"
#include "vm/isolate.h"
+#include "vm/kernel_loader.h"
#include "vm/lockers.h"
#include "vm/thread_barrier.h"
#include "vm/thread_pool.h"
@@ -123,15 +124,17 @@
}};
// clang-format on
{
- void* kernel_pgm = NULL;
+ const uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
char* error = TestCase::CompileTestScriptWithDFE(
"file:///test-app",
sizeof(updated_sourcefiles) / sizeof(Dart_SourceFile),
- updated_sourcefiles, &kernel_pgm, true /* incrementally */);
+ updated_sourcefiles, &kernel_buffer, &kernel_buffer_size,
+ true /* incrementally */);
EXPECT(error == NULL);
- EXPECT_NOTNULL(kernel_pgm);
+ EXPECT_NOTNULL(kernel_buffer);
- lib = TestCase::ReloadTestKernel(kernel_pgm);
+ lib = TestCase::ReloadTestKernel(kernel_buffer, kernel_buffer_size);
EXPECT_VALID(lib);
}
result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -182,15 +185,17 @@
}};
// clang-format on
{
- void* kernel_pgm = NULL;
+ const uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
char* error = TestCase::CompileTestScriptWithDFE(
"file:///test-app.dart",
sizeof(updated_sourcefiles) / sizeof(Dart_SourceFile),
- updated_sourcefiles, &kernel_pgm, true /* incrementally */);
+ updated_sourcefiles, &kernel_buffer, &kernel_buffer_size,
+ true /* incrementally */);
EXPECT(error == NULL);
- EXPECT_NOTNULL(kernel_pgm);
+ EXPECT_NOTNULL(kernel_buffer);
- lib = TestCase::ReloadTestKernel(kernel_pgm);
+ lib = TestCase::ReloadTestKernel(kernel_buffer, kernel_buffer_size);
EXPECT_VALID(lib);
}
result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -257,15 +262,17 @@
}};
// clang-format on
{
- void* kernel_pgm = NULL;
+ const uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
char* error = TestCase::CompileTestScriptWithDFE(
"file:///test-app.dart",
sizeof(updated_sourcefiles) / sizeof(Dart_SourceFile),
- updated_sourcefiles, &kernel_pgm, true /* incrementally */);
+ updated_sourcefiles, &kernel_buffer, &kernel_buffer_size,
+ true /* incrementally */);
EXPECT(error == NULL);
- EXPECT_NOTNULL(kernel_pgm);
+ EXPECT_NOTNULL(kernel_buffer);
- lib = TestCase::ReloadTestKernel(kernel_pgm);
+ lib = TestCase::ReloadTestKernel(kernel_buffer, kernel_buffer_size);
EXPECT_VALID(lib);
}
result = Dart_Invoke(lib, NewString("main"), 0, NULL);
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 036e3a4..d297dda 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -55,6 +55,8 @@
enum LogicalOperator { kAnd, kOr };
+typedef void (*Dart_ReleaseBufferCallback)(uint8_t* buffer);
+
class Program {
public:
~Program() {
@@ -77,18 +79,24 @@
* "sub program" should not try to release the buffer.
* @return
*/
- static Program* ReadFrom(Reader* reader, bool take_buffer_ownership = true);
+ static Program* ReadFrom(Reader* reader, bool take_buffer_ownership = false);
static Program* ReadFromFile(const char* script_uri);
static Program* ReadFromBuffer(const uint8_t* buffer,
intptr_t buffer_length,
- bool take_buffer_ownership = true);
+ bool take_buffer_ownership = false);
bool is_single_program() { return single_program_; }
NameIndex main_method() { return main_method_reference_; }
intptr_t source_table_offset() const { return source_table_offset_; }
intptr_t string_table_offset() const { return string_table_offset_; }
intptr_t name_table_offset() const { return name_table_offset_; }
+ intptr_t metadata_payloads_offset() const {
+ return metadata_payloads_offset_;
+ }
+ intptr_t metadata_mappings_offset() const {
+ return metadata_mappings_offset_;
+ }
intptr_t constant_table_offset() { return constant_table_offset_; }
const uint8_t* kernel_data() { return kernel_data_; }
intptr_t kernel_data_size() { return kernel_data_size_; }
@@ -115,6 +123,12 @@
// The offset from the start of the binary to the canonical name table.
intptr_t name_table_offset_;
+ // The offset from the start of the binary to the metadata payloads.
+ intptr_t metadata_payloads_offset_;
+
+ // The offset from the start of the binary to the metadata mappings.
+ intptr_t metadata_mappings_offset_;
+
// The offset from the start of the binary to the start of the string table.
intptr_t string_table_offset_;
@@ -194,6 +208,7 @@
const dart::TypedData& line_starts_data_;
KernelLineStartsHelper* helper_;
+ Dart_ReleaseBufferCallback release_callback;
DISALLOW_COPY_AND_ASSIGN(KernelLineStartsReader);
};
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index a2fe779..9b97137 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -69,6 +69,8 @@
SourceTableFieldCountFromFirstLibraryOffset,
1, 0);
program->name_table_offset_ = reader->ReadUInt32();
+ program->metadata_payloads_offset_ = reader->ReadUInt32();
+ program->metadata_mappings_offset_ = reader->ReadUInt32();
program->string_table_offset_ = reader->ReadUInt32();
program->constant_table_offset_ = reader->ReadUInt32();
@@ -90,17 +92,25 @@
Dart_kKernelTag, Api::Null(),
Api::NewHandle(thread, String::New(script_uri)));
if (!Dart_IsError(retval)) {
- uint64_t data;
- intptr_t data_len = 0;
Dart_TypedData_Type data_type;
+ uint8_t* data;
ASSERT(Dart_IsTypedData(retval));
+
+ uint8_t* kernel_buffer;
+ intptr_t kernel_buffer_size;
Dart_Handle val = Dart_TypedDataAcquireData(
- retval, &data_type, reinterpret_cast<void**>(&data), &data_len);
+ retval, &data_type, reinterpret_cast<void**>(&data),
+ &kernel_buffer_size);
ASSERT(!Dart_IsError(val));
- ASSERT(data_type == Dart_TypedData_kUint64);
- ASSERT(data_len == 1);
- kernel_program = reinterpret_cast<kernel::Program*>(data);
+ ASSERT(data_type == Dart_TypedData_kUint8);
+ kernel_buffer = reinterpret_cast<uint8_t*>(malloc(kernel_buffer_size));
+ memmove(kernel_buffer, data, kernel_buffer_size);
Dart_TypedDataReleaseData(retval);
+
+ kernel_program =
+ kernel::Program::ReadFromBuffer(kernel_buffer, kernel_buffer_size);
+ } else {
+ THR_Print("tag handler failed: %s\n", Dart_GetError(retval));
}
}
return kernel_program;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index daee540..ba05ff0 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -16,10 +16,11 @@
namespace dart {
namespace kernel {
-// Keep in sync with package:kernel/lib/binary/tag.dart.
+// Keep in sync with package:kernel/lib/binary/tag.dart,
+// package:kernel/binary.md.
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kBinaryFormatVersion = 5;
+static const uint32_t kBinaryFormatVersion = 6;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \
@@ -156,10 +157,9 @@
static const int SpecializedIntLiteralBias = 3;
static const int LibraryCountFieldCountFromEnd = 1;
-static const int SourceTableFieldCountFromFirstLibraryOffset = 4;
+static const int SourceTableFieldCountFromFirstLibraryOffset = 6;
static const int HeaderSize = 8; // 'magic', 'formatVersion'.
-static const int MetadataPayloadOffset = HeaderSize; // Right after header.
class Reader : public ValueObject {
public:
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index cf12542..c22b3f5 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -52,6 +52,7 @@
const int KernelIsolate::kUpdateSourcesTag = 1;
const int KernelIsolate::kAcceptTag = 2;
const int KernelIsolate::kTrainTag = 3;
+const int KernelIsolate::kCompileExpressionTag = 4;
Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
Monitor* KernelIsolate::monitor_ = new Monitor();
@@ -87,6 +88,7 @@
api_flags.enable_error_on_bad_override = false;
api_flags.reify_generic_functions = false;
api_flags.strong = false;
+ api_flags.sync_async = false;
#if !defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC)
api_flags.use_field_guards = true;
#endif
@@ -134,9 +136,6 @@
OS::Print(DART_KERNEL_ISOLATE_NAME ": ShutdownIsolate\n");
}
Isolate* I = reinterpret_cast<Isolate*>(parameter);
- ASSERT(KernelIsolate::IsKernelIsolate(I));
- KernelIsolate::SetKernelIsolate(NULL);
- KernelIsolate::SetLoadPort(ILLEGAL_PORT);
I->WaitForOutstandingSpawns();
{
// Print the error if there is one. This may execute dart code to
@@ -158,8 +157,14 @@
OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Error: %s\n",
error.ToErrorCString());
}
+ TransitionVMToNative transition(T);
Dart::RunShutdownCallback();
}
+
+ ASSERT(KernelIsolate::IsKernelIsolate(I));
+ KernelIsolate::SetKernelIsolate(NULL);
+ KernelIsolate::SetLoadPort(ILLEGAL_PORT);
+
// Shut the isolate down.
Dart::ShutdownIsolate(I);
if (FLAG_trace_kernel) {
@@ -341,6 +346,125 @@
}
Dart_KernelCompilationResult SendAndWaitForResponse(
+ Dart_Port kernel_port,
+ const char* expression,
+ const Array& definitions,
+ const Array& type_definitions,
+ char const* library_uri,
+ char const* klass,
+ bool is_static) {
+ Dart_CObject tag;
+ tag.type = Dart_CObject_kInt32;
+ tag.value.as_int32 = KernelIsolate::kCompileExpressionTag;
+
+ Dart_CObject send_port;
+ send_port.type = Dart_CObject_kSendPort;
+ send_port.value.as_send_port.id = port_;
+ send_port.value.as_send_port.origin_id = ILLEGAL_PORT;
+
+ Dart_CObject expression_object;
+ expression_object.type = Dart_CObject_kString;
+ expression_object.value.as_string = const_cast<char*>(expression);
+
+ Dart_CObject definitions_object;
+ intptr_t num_definitions = definitions.Length();
+ definitions_object.type = Dart_CObject_kArray;
+ definitions_object.value.as_array.length = num_definitions;
+
+ Dart_CObject** definitions_array = new Dart_CObject*[num_definitions];
+ for (intptr_t i = 0; i < num_definitions; ++i) {
+ definitions_array[i] = new Dart_CObject;
+ definitions_array[i]->type = Dart_CObject_kString;
+ definitions_array[i]->value.as_string = const_cast<char*>(
+ String::CheckedHandle(definitions.At(i)).ToCString());
+ }
+ definitions_object.value.as_array.values = definitions_array;
+
+ Dart_CObject type_definitions_object;
+ intptr_t num_type_definitions = type_definitions.Length();
+ type_definitions_object.type = Dart_CObject_kArray;
+ type_definitions_object.value.as_array.length = num_type_definitions;
+
+ Dart_CObject** type_definitions_array =
+ new Dart_CObject*[num_type_definitions];
+ for (intptr_t i = 0; i < num_type_definitions; ++i) {
+ type_definitions_array[i] = new Dart_CObject;
+ type_definitions_array[i]->type = Dart_CObject_kString;
+ type_definitions_array[i]->value.as_string = const_cast<char*>(
+ String::CheckedHandle(type_definitions.At(i)).ToCString());
+ }
+ type_definitions_object.value.as_array.values = type_definitions_array;
+
+ Dart_CObject library_uri_object;
+ library_uri_object.type = Dart_CObject_kString;
+ library_uri_object.value.as_string = const_cast<char*>(library_uri);
+
+ Dart_CObject class_object;
+ if (klass != NULL) {
+ class_object.type = Dart_CObject_kString;
+ class_object.value.as_string = const_cast<char*>(klass);
+ } else {
+ class_object.type = Dart_CObject_kNull;
+ }
+
+ Dart_CObject is_static_object;
+ is_static_object.type = Dart_CObject_kBool;
+ is_static_object.value.as_bool = is_static;
+
+ Isolate* isolate =
+ Thread::Current() != NULL ? Thread::Current()->isolate() : NULL;
+ ASSERT(isolate != NULL);
+ Dart_CObject isolate_id;
+ isolate_id.type = Dart_CObject_kInt64;
+ isolate_id.value.as_int64 =
+ isolate != NULL ? static_cast<int64_t>(isolate->main_port()) : 0;
+
+ Dart_CObject message;
+ message.type = Dart_CObject_kArray;
+ Dart_CObject suppress_warnings;
+ suppress_warnings.type = Dart_CObject_kBool;
+ suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
+
+ Dart_CObject dart_sync_async;
+ dart_sync_async.type = Dart_CObject_kBool;
+ dart_sync_async.value.as_bool = isolate->sync_async();
+
+ Dart_CObject* message_arr[] = {&tag,
+ &send_port,
+ &isolate_id,
+ &expression_object,
+ &definitions_object,
+ &type_definitions_object,
+ &library_uri_object,
+ &class_object,
+ &is_static_object,
+ &suppress_warnings,
+ &dart_sync_async};
+ message.value.as_array.values = message_arr;
+ message.value.as_array.length = ARRAY_SIZE(message_arr);
+ // Send the message.
+ Dart_PostCObject(kernel_port, &message);
+
+ // Wait for reply to arrive.
+ MonitorLocker ml(monitor_);
+ while (result_.status == Dart_KernelCompilationStatus_Unknown) {
+ ml.Wait();
+ }
+
+ for (intptr_t i = 0; i < num_definitions; ++i) {
+ delete definitions_array[i];
+ }
+ delete[] definitions_array;
+
+ for (intptr_t i = 0; i < num_type_definitions; ++i) {
+ delete type_definitions_array[i];
+ }
+ delete[] type_definitions_array;
+
+ return result_;
+ }
+
+ Dart_KernelCompilationResult SendAndWaitForResponse(
int request_tag,
Dart_Port kernel_port,
const char* script_uri,
@@ -421,7 +545,7 @@
Dart_CObject dart_sync_async;
dart_sync_async.type = Dart_CObject_kBool;
- dart_sync_async.value.as_bool = FLAG_sync_async;
+ dart_sync_async.value.as_bool = isolate->sync_async();
Dart_CObject package_config_uri;
if (package_config != NULL) {
@@ -602,6 +726,27 @@
0, NULL, true, NULL);
}
+Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
+ const char* expression,
+ const Array& definitions,
+ const Array& type_definitions,
+ const char* library_url,
+ const char* klass,
+ bool is_static) {
+ Dart_Port kernel_port = WaitForKernelPort();
+ if (kernel_port == ILLEGAL_PORT) {
+ Dart_KernelCompilationResult result;
+ result.status = Dart_KernelCompilationStatus_Unknown;
+ result.error = strdup("Error while initializing Kernel isolate");
+ return result;
+ }
+
+ KernelCompilationRequest request;
+ return request.SendAndWaitForResponse(kernel_port, expression, definitions,
+ type_definitions, library_url, klass,
+ is_static);
+}
+
Dart_KernelCompilationResult KernelIsolate::UpdateInMemorySources(
int source_files_count,
Dart_SourceFile source_files[]) {
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index f9084cf..2e45b52 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -8,6 +8,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
#include "include/dart_api.h"
+#include "include/dart_native_api.h"
#include "vm/allocation.h"
#include "vm/dart.h"
@@ -22,6 +23,7 @@
static const int kUpdateSourcesTag;
static const int kAcceptTag;
static const int kTrainTag;
+ static const int kCompileExpressionTag;
static void Run();
@@ -46,6 +48,14 @@
int source_files_count,
Dart_SourceFile source_files[]);
+ static Dart_KernelCompilationResult CompileExpressionToKernel(
+ const char* expression,
+ const Array& definitions,
+ const Array& type_definitions,
+ const char* library_url,
+ const char* klass,
+ bool is_static);
+
protected:
static Monitor* monitor_;
static Dart_IsolateCreateCallback create_callback_;
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 6a3358c..abbc676 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -195,7 +195,7 @@
bool process_pending_classes) {
if (program->is_single_program()) {
KernelLoader loader(program);
- return loader.LoadProgram(process_pending_classes);
+ return Object::Handle(loader.LoadProgram(process_pending_classes));
}
kernel::Reader reader(program->kernel_data(), program->kernel_data_size());
@@ -216,7 +216,7 @@
Program* subprogram = Program::ReadFrom(&reader, false);
ASSERT(subprogram->is_single_program());
KernelLoader loader(subprogram);
- Object& load_result = loader.LoadProgram(false);
+ Object& load_result = Object::Handle(loader.LoadProgram(false));
if (load_result.IsError()) return load_result;
if (library.IsNull() && load_result.IsLibrary()) {
@@ -293,27 +293,18 @@
names.SetUint32(i << 2, reader.ReadUInt());
}
- // Metadata mappings immediately follow names table.
- const intptr_t metadata_mappings_start = reader.offset();
-
// Copy metadata payloads into the VM's heap
- // TODO(alexmarkov): add more info to program index instead of guessing
- // the end of metadata payloads by offsets of the libraries.
- intptr_t metadata_payloads_end = program_->source_table_offset();
- for (intptr_t i = 0; i < program_->library_count(); ++i) {
- metadata_payloads_end =
- Utils::Minimum(metadata_payloads_end, library_offset(i));
- }
- ASSERT(metadata_payloads_end >= MetadataPayloadOffset);
+ const intptr_t metadata_payloads_start = program_->metadata_payloads_offset();
const intptr_t metadata_payloads_size =
- metadata_payloads_end - MetadataPayloadOffset;
+ program_->metadata_mappings_offset() - metadata_payloads_start;
TypedData& metadata_payloads =
TypedData::Handle(Z, TypedData::New(kTypedDataUint8ArrayCid,
metadata_payloads_size, Heap::kOld));
- reader.CopyDataToVMHeap(metadata_payloads, MetadataPayloadOffset,
+ reader.CopyDataToVMHeap(metadata_payloads, metadata_payloads_start,
metadata_payloads_size);
// Copy metadata mappings into the VM's heap
+ const intptr_t metadata_mappings_start = program_->metadata_mappings_offset();
const intptr_t metadata_mappings_size =
program_->string_table_offset() - metadata_mappings_start;
TypedData& metadata_mappings =
@@ -545,7 +536,7 @@
potential_extension_libraries_ = GrowableObjectArray::null();
}
-Object& KernelLoader::LoadProgram(bool process_pending_classes) {
+RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
ASSERT(kernel_program_info_.constants() == Array::null());
if (!program_->is_single_program()) {
@@ -557,15 +548,15 @@
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
const intptr_t length = program_->library_count();
+ Object& last_library = Library::Handle(Z);
for (intptr_t i = 0; i < length; i++) {
- LoadLibrary(i);
+ last_library = LoadLibrary(i);
}
if (process_pending_classes) {
if (!ClassFinalizer::ProcessPendingClasses()) {
// Class finalization failed -> sticky error would be set.
- Error& error = Error::Handle(Z);
- error = H.thread()->sticky_error();
+ RawError* error = H.thread()->sticky_error();
H.thread()->clear_sticky_error();
return error;
}
@@ -586,19 +577,18 @@
NameIndex main = program_->main_method();
if (main == -1) {
- return Library::Handle(Z);
+ return Library::null();
}
NameIndex main_library = H.EnclosingName(main);
Library& library = LookupLibrary(main_library);
- return library;
+ return library.raw();
}
// Either class finalization failed or we caught a compile error.
// In both cases sticky error would be set.
- Error& error = Error::Handle(Z);
- error = thread_->sticky_error();
+ RawError* error = thread_->sticky_error();
thread_->clear_sticky_error();
return error;
}
@@ -683,7 +673,7 @@
field.set_has_initializer(false);
}
-void KernelLoader::LoadLibrary(intptr_t index) {
+RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
if (!program_->is_single_program()) {
FATAL(
"Trying to load a concatenated dill file at a time where that is "
@@ -713,15 +703,16 @@
// snapshot so we skip loading 'dart:vmservice_io'.
skip_vmservice_library_ = library_helper.canonical_name_;
ASSERT(H.IsLibrary(skip_vmservice_library_));
- return;
+ return Library::null();
}
}
- Library& library = LookupLibrary(library_helper.canonical_name_);
+ Library& library =
+ Library::Handle(Z, LookupLibrary(library_helper.canonical_name_).raw());
// The Kernel library is external implies that it is already loaded.
ASSERT(!library_helper.IsExternal() || library.Loaded());
- if (library.Loaded()) return;
+ if (library.Loaded()) return library.raw();
library_kernel_data_ =
TypedData::New(kTypedDataUint8ArrayCid, library_size, Heap::kOld);
@@ -846,6 +837,8 @@
toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray()));
classes.Add(toplevel_class, Heap::kOld);
if (!library.Loaded()) library.SetLoaded();
+
+ return library.raw();
}
void KernelLoader::LoadLibraryImportsAndExports(Library* library) {
@@ -1304,8 +1297,6 @@
const String& name = H.DartProcedureName(procedure_helper.canonical_name_);
bool is_method = in_class && !procedure_helper.IsStatic();
bool is_abstract = procedure_helper.IsAbstract();
- bool is_no_such_method_forwarder = procedure_helper.IsNoSuchMethodForwarder();
-
bool is_external = procedure_helper.IsExternal();
String* native_name = NULL;
intptr_t annotation_count;
@@ -1384,10 +1375,9 @@
Z, Function::New(name, kind,
!is_method, // is_static
false, // is_const
- is_abstract && !is_no_such_method_forwarder, is_external,
+ is_abstract, is_external,
native_name != NULL, // is_native
script_class, procedure_helper.position_));
- function.set_is_no_such_method_forwarder(is_no_such_method_forwarder);
function.set_end_token_pos(procedure_helper.end_position_);
functions_.Add(&function);
function.set_kernel_offset(procedure_offset);
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index ed47893..21f4bb2 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -128,7 +128,7 @@
// Returns the library containing the main procedure, null if there
// was no main procedure, or a failure object if there was an error.
- Object& LoadProgram(bool process_pending_classes = true);
+ RawObject* LoadProgram(bool process_pending_classes = true);
// Finds all libraries that have been modified in this incremental
// version of the kernel program file.
@@ -137,7 +137,7 @@
BitVector* modified_libs,
bool force_reload);
- void LoadLibrary(intptr_t index);
+ RawLibrary* LoadLibrary(intptr_t index);
static void FinishLoading(const Class& klass);
diff --git a/runtime/vm/longjump.cc b/runtime/vm/longjump.cc
index e0a3ca7..e41a8c4 100644
--- a/runtime/vm/longjump.cc
+++ b/runtime/vm/longjump.cc
@@ -7,6 +7,7 @@
#include "include/dart_api.h"
#include "vm/dart_api_impl.h"
+#include "vm/interpreter.h"
#include "vm/isolate.h"
#include "vm/object.h"
#include "vm/object_store.h"
@@ -26,12 +27,22 @@
// assumes the stack grows from high to low.
Thread* thread = Thread::Current();
uword jumpbuf_addr = OSThread::GetCurrentStackPointer();
+
+#if defined(USING_SIMULATOR) && defined(DART_USE_INTERPRETER)
+#error "Simultaneous usage of simulator and interpreter not yet supported."
+#endif // defined(USING_SIMULATOR) && defined(DART_USE_INTERPRETER)
+
#if defined(USING_SIMULATOR)
Simulator* sim = Simulator::Current();
// When using simulator, only mutator thread should refer to Simulator
// since there can be only one per isolate.
uword top_exit_frame_info =
thread->IsMutatorThread() ? sim->top_exit_frame_info() : 0;
+#elif defined(DART_USE_INTERPRETER)
+ Interpreter* interpreter = Interpreter::Current();
+ ASSERT(interpreter->top_exit_frame_info() == 0);
+ uword top_exit_frame_info = 0;
+ // TODO(regis): Determine if top exit frame is jitted or interpreted.
#else
uword top_exit_frame_info = thread->top_exit_frame_info();
#endif
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 910e2d6..ea9d33c 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -223,7 +223,7 @@
RawObject** argv,
RawObject** retval)
: thread_(thread),
- argc_tag_(ReverseArgOrderBit::update(kReverseArgOrderBit, argc_tag)),
+ argc_tag_(ReverseArgOrderBit::update(true, argc_tag)),
argv_(argv),
retval_(retval) {}
#endif
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index caa190c..c50f3ee 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -34,6 +34,8 @@
#include "vm/heap.h"
#include "vm/isolate_reload.h"
#include "vm/kernel.h"
+#include "vm/kernel_isolate.h"
+#include "vm/kernel_loader.h"
#include "vm/native_symbol.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@@ -1293,12 +1295,14 @@
// A non-NULL kernel argument indicates (1). A NULL kernel indicates (2) or
// (3), depending on whether the VM is compiled with DART_NO_SNAPSHOT defined or
// not.
-RawError* Object::Init(Isolate* isolate, kernel::Program* kernel_program) {
+RawError* Object::Init(Isolate* isolate,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(isolate == thread->isolate());
#if !defined(DART_PRECOMPILED_RUNTIME)
- const bool is_kernel = (kernel_program != NULL);
+ const bool is_kernel = (kernel_buffer != NULL);
#endif
NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
"Object::Init");)
@@ -1813,8 +1817,8 @@
// Finish the initialization by compiling the bootstrap scripts containing
// the base interfaces and the implementation of the internal classes.
- const Error& error =
- Error::Handle(zone, Bootstrap::DoBootstrapping(kernel_program));
+ const Error& error = Error::Handle(
+ zone, Bootstrap::DoBootstrapping(kernel_buffer, kernel_buffer_size));
if (!error.IsNull()) {
return error.raw();
}
@@ -3195,6 +3199,15 @@
return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces)));
}
+static RawObject* EvaluateWithDFEHelper(const String& expression,
+ const Array& definitions,
+ const Array& type_definitions,
+ const String& library_url,
+ const String& klass,
+ bool is_static,
+ const Array& arguments,
+ const TypeArguments& type_arguments);
+
RawFunction* Function::EvaluateHelper(const Class& cls,
const String& expr,
const Array& param_names,
@@ -3221,9 +3234,24 @@
return func.raw();
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
+static void ReleaseFetchedBytes(uint8_t* buffer) {
+ free(buffer);
+}
+#endif
+
RawObject* Class::Evaluate(const String& expr,
const Array& param_names,
const Array& param_values) const {
+ return Evaluate(expr, param_names, param_values, Object::empty_array(),
+ Object::null_type_arguments());
+}
+
+RawObject* Class::Evaluate(const String& expr,
+ const Array& param_names,
+ const Array& param_values,
+ const Array& type_param_names,
+ const TypeArguments& type_param_values) const {
ASSERT(Thread::Current()->IsMutatorThread());
if (id() < kInstanceCid) {
const Instance& exception = Instance::Handle(
@@ -3232,11 +3260,18 @@
return UnhandledException::New(exception, stacktrace);
}
- const Function& eval_func = Function::Handle(
- Function::EvaluateHelper(*this, expr, param_names, true));
- const Object& result =
- Object::Handle(DartEntry::InvokeFunction(eval_func, param_values));
- return result.raw();
+ if (Library::Handle(library()).kernel_data() == TypedData::null() ||
+ !FLAG_enable_kernel_expression_compilation) {
+ const Function& eval_func = Function::Handle(
+ Function::EvaluateHelper(*this, expr, param_names, true));
+ return DartEntry::InvokeFunction(eval_func, param_values);
+ }
+
+ return EvaluateWithDFEHelper(
+ expr, param_names, type_param_names,
+ String::Handle(Library::Handle(library()).url()),
+ IsTopLevel() ? String::Handle() : String::Handle(UserVisibleName()),
+ !IsTopLevel(), param_values, type_param_values);
}
// Ensure that top level parsing of the class has been done.
@@ -4637,7 +4672,7 @@
}
return false;
}
- uword Hash() const { return key_.ComputeCanonicalTableHash(); }
+ uword Hash() const { return key_.CanonicalizeHash(); }
const Instance& key_;
private:
@@ -4662,7 +4697,7 @@
static uword Hash(const Object& key) {
ASSERT(!(key.IsString() || key.IsNumber() || key.IsAbstractType()));
ASSERT(key.IsInstance());
- return Instance::Cast(key).ComputeCanonicalTableHash();
+ return Instance::Cast(key).CanonicalizeHash();
}
static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); }
static RawObject* NewKey(const CanonicalInstanceKey& obj) {
@@ -6067,6 +6102,9 @@
// This field is heavily overloaded:
// eval function: Script expression source
+// kernel eval function: Array[0] = Script
+// Array[1] = Kernel data
+// Array[2] = Kernel offset of enclosing library
// signature function: SignatureData
// method extractor: Function extracted closure function
// noSuchMethod dispatcher: Array arguments descriptor
@@ -7057,6 +7095,7 @@
NOT_IN_PRECOMPILED(result.set_inlining_depth(0));
NOT_IN_PRECOMPILED(result.set_kernel_offset(0));
result.set_is_optimizable(is_native ? false : true);
+ result.set_is_background_optimizable(is_native ? false : true);
result.set_is_inlinable(true);
result.set_allows_hoisting_check_class(true);
result.set_allows_bounds_check_generalization(true);
@@ -7539,9 +7578,26 @@
return PatchClass::Cast(obj).origin_class();
}
+void Function::SetKernelDataAndScript(const Script& script,
+ const TypedData& data,
+ intptr_t offset) {
+ Array& data_field = Array::Handle(Array::New(3));
+ data_field.SetAt(0, script);
+ data_field.SetAt(1, data);
+ data_field.SetAt(2, Smi::Handle(Smi::New(offset)));
+ set_data(data_field);
+}
+
RawScript* Function::script() const {
// NOTE(turnidge): If you update this function, you probably want to
// update Class::PatchFieldsAndFunctions() at the same time.
+ Object& data = Object::Handle(raw_ptr()->data_);
+ if (data.IsArray()) {
+ Object& script = Object::Handle(Array::Cast(data).At(0));
+ if (script.IsScript()) {
+ return Script::Cast(script).raw();
+ }
+ }
if (token_pos() == TokenPosition::kMinSource) {
// Testing for position 0 is an optimization that relies on temporary
// eval functions having token position 0.
@@ -7566,6 +7622,13 @@
}
RawTypedData* Function::KernelData() const {
+ Object& data = Object::Handle(raw_ptr()->data_);
+ if (data.IsArray()) {
+ Object& script = Object::Handle(Array::Cast(data).At(0));
+ if (script.IsScript()) {
+ return TypedData::RawCast(Array::Cast(data).At(1));
+ }
+ }
if (IsClosureFunction()) {
Function& parent = Function::Handle(parent_function());
ASSERT(!parent.IsNull());
@@ -7582,6 +7645,13 @@
}
intptr_t Function::KernelDataProgramOffset() const {
+ Object& data = Object::Handle(raw_ptr()->data_);
+ if (data.IsArray()) {
+ Object& script = Object::Handle(Array::Cast(data).At(0));
+ if (script.IsScript()) {
+ return Smi::Value(Smi::RawCast(Array::Cast(data).At(2)));
+ }
+ }
if (IsClosureFunction()) {
Function& parent = Function::Handle(parent_function());
ASSERT(!parent.IsNull());
@@ -11344,10 +11414,25 @@
RawObject* Library::Evaluate(const String& expr,
const Array& param_names,
const Array& param_values) const {
- // Evaluate the expression as a static function of the toplevel class.
- Class& top_level_class = Class::Handle(toplevel_class());
- ASSERT(top_level_class.is_finalized());
- return top_level_class.Evaluate(expr, param_names, param_values);
+ return Evaluate(expr, param_names, param_values, Array::empty_array(),
+ TypeArguments::null_type_arguments());
+}
+
+RawObject* Library::Evaluate(const String& expr,
+ const Array& param_names,
+ const Array& param_values,
+ const Array& type_param_names,
+ const TypeArguments& type_param_values) const {
+ if (kernel_data() == TypedData::null() ||
+ !FLAG_enable_kernel_expression_compilation) {
+ // Evaluate the expression as a static function of the toplevel class.
+ Class& top_level_class = Class::Handle(toplevel_class());
+ ASSERT(top_level_class.is_finalized());
+ return top_level_class.Evaluate(expr, param_names, param_values);
+ }
+ return EvaluateWithDFEHelper(expr, param_names, type_param_names,
+ String::Handle(url()), String::Handle(), false,
+ param_values, type_param_values);
}
void Library::InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel) {
@@ -11404,6 +11489,136 @@
};
typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap;
+static RawObject* EvaluateWithDFEHelper(const String& expression,
+ const Array& definitions,
+ const Array& type_definitions,
+ const String& library_url,
+ const String& klass,
+ bool is_static,
+ const Array& arguments,
+ const TypeArguments& type_arguments) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ const String& error_str = String::Handle(
+ String::New("Kernel service isolate not available in precompiled mode."));
+ return ApiError::New(error_str);
+#else
+ Isolate* I = Isolate::Current();
+ Thread* T = Thread::Current();
+
+ Dart_KernelCompilationResult compilation_result;
+ {
+ TransitionVMToNative transition(T);
+ compilation_result = KernelIsolate::CompileExpressionToKernel(
+ expression.ToCString(), definitions, type_definitions,
+ library_url.ToCString(), klass.IsNull() ? NULL : klass.ToCString(),
+ is_static);
+ }
+
+ Function& callee = Function::Handle();
+ intptr_t num_cids = I->class_table()->NumCids();
+ intptr_t num_libs =
+ GrowableObjectArray::Handle(I->object_store()->libraries()).Length();
+
+ if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
+ const String& prefix =
+ String::Handle(String::New("Kernel isolate rejected this request:\n"));
+ const String& error_str = String::Handle(String::Concat(
+ prefix, String::Handle(String::New(compilation_result.error))));
+ free(compilation_result.error);
+ return ApiError::New(error_str);
+ }
+
+ const uint8_t* kernel_file = compilation_result.kernel;
+ intptr_t kernel_length = compilation_result.kernel_size;
+ ASSERT(kernel_file != NULL);
+
+ kernel::Program* kernel_pgm =
+ kernel::Program::ReadFromBuffer(kernel_file, kernel_length, true);
+
+ if (kernel_pgm == NULL) {
+ return ApiError::New(String::Handle(
+ String::New("Kernel isolate returned ill-formed kernel.")));
+ }
+
+ kernel_pgm->set_release_buffer_callback(ReleaseFetchedBytes);
+
+ // Load the program with the debug procedure as a regular, independent
+ // program.
+ kernel::KernelLoader loader(kernel_pgm);
+ loader.LoadProgram();
+ ASSERT(I->class_table()->NumCids() > num_cids &&
+ GrowableObjectArray::Handle(I->object_store()->libraries()).Length() ==
+ num_libs + 1);
+ const String& fake_library_url =
+ String::Handle(String::New("evaluate:source"));
+ const Library& loaded =
+ Library::Handle(Library::LookupLibrary(T, fake_library_url));
+ ASSERT(!loaded.IsNull());
+
+ String& debug_name = String::Handle(
+ String::New(Symbols::Symbol(Symbols::kDebugProcedureNameId)));
+ Class& fake_class = Class::Handle();
+ if (!klass.IsNull()) {
+ fake_class = loaded.LookupClass(String::Handle(String::New(klass)));
+ ASSERT(!fake_class.IsNull());
+ callee = fake_class.LookupFunctionAllowPrivate(debug_name);
+ } else {
+ callee = loaded.LookupFunctionAllowPrivate(debug_name);
+ }
+ ASSERT(!callee.IsNull());
+
+ // Save the loaded library's kernel data to the generic "data" field of the
+ // callee, so it doesn't require access it's parent library during
+ // compilation.
+ callee.SetKernelDataAndScript(Script::Handle(callee.script()),
+ TypedData::Handle(loaded.kernel_data()),
+ loaded.kernel_offset());
+
+ // Reparent the callee to the real enclosing class so we can remove the fake
+ // class and library from the object store.
+ const Library& real_library =
+ Library::Handle(Library::LookupLibrary(T, library_url));
+ ASSERT(!real_library.IsNull());
+ Class& real_class = Class::Handle();
+ if (!klass.IsNull()) {
+ real_class = real_library.LookupClass(String::Handle(String::New(klass)));
+ } else {
+ real_class = real_library.toplevel_class();
+ }
+ ASSERT(!real_class.IsNull());
+
+ callee.set_owner(real_class);
+
+ // Unlink the fake library and class from the object store.
+ GrowableObjectArray::Handle(I->object_store()->libraries())
+ .SetLength(num_libs);
+ I->class_table()->SetNumCids(num_cids);
+ if (!fake_class.IsNull()) {
+ fake_class.set_id(kIllegalCid);
+ }
+ LibraryLookupMap libraries_map(I->object_store()->libraries_map());
+ bool removed = libraries_map.Remove(fake_library_url);
+ ASSERT(removed);
+ I->object_store()->set_libraries_map(libraries_map.Release());
+
+ if (type_definitions.Length() == 0) {
+ return DartEntry::InvokeFunction(callee, arguments);
+ }
+
+ intptr_t num_type_args = type_arguments.Length();
+ Array& real_arguments = Array::Handle(Array::New(arguments.Length() + 1));
+ real_arguments.SetAt(0, type_arguments);
+ Object& arg = Object::Handle();
+ for (intptr_t i = 0; i < arguments.Length(); ++i) {
+ arg = arguments.At(i);
+ real_arguments.SetAt(i + 1, arg);
+ }
+ const Array& args_desc = Array::Handle(
+ ArgumentsDescriptor::New(num_type_args, real_arguments.Length()));
+ return DartEntry::InvokeFunction(callee, real_arguments, args_desc);
+#endif
+}
+
// Returns library with given url in current isolate, or NULL.
RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) {
Zone* zone = thread->zone();
@@ -12722,6 +12937,10 @@
}
ASSERT(pc_offset >= 0);
result.SetPcOffset(pc_offset);
+ if (payload_size > 0) {
+ // Ensure leftover bits are deterministic.
+ result.raw()->ptr()->data()[payload_size - 1] = 0;
+ }
for (intptr_t i = 0; i < length; ++i) {
result.SetBit(i, bmap->Get(i));
}
@@ -14625,9 +14844,11 @@
code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
// TODO(regis): Do we need to notify CodeObservers for bytecode too?
// If so, provide a better name using ToLibNamePrefixedQualifiedCString().
+#ifndef PRODUCT
CodeObservers::NotifyAll("bytecode", instrs.PayloadStart(),
0 /* prologue_offset */, instrs.Size(),
false /* optimized */);
+#endif
{
NoSafepointScope no_safepoint;
@@ -15614,8 +15835,16 @@
const String& expr,
const Array& param_names,
const Array& param_values) const {
- const Function& eval_func = Function::Handle(
- Function::EvaluateHelper(method_cls, expr, param_names, false));
+ return Evaluate(method_cls, expr, param_names, param_values,
+ Object::empty_array(), TypeArguments::null_type_arguments());
+}
+
+RawObject* Instance::Evaluate(const Class& method_cls,
+ const String& expr,
+ const Array& param_names,
+ const Array& param_values,
+ const Array& type_param_names,
+ const TypeArguments& type_param_values) const {
const Array& args = Array::Handle(Array::New(1 + param_values.Length()));
PassiveObject& param = PassiveObject::Handle();
args.SetAt(0, *this);
@@ -15623,7 +15852,19 @@
param = param_values.At(i);
args.SetAt(i + 1, param);
}
- return DartEntry::InvokeFunction(eval_func, args);
+
+ const Library& library = Library::Handle(method_cls.library());
+ if (library.kernel_data() == TypedData::null() ||
+ !FLAG_enable_kernel_expression_compilation) {
+ const Function& eval_func = Function::Handle(
+ Function::EvaluateHelper(method_cls, expr, param_names, false));
+ return DartEntry::InvokeFunction(eval_func, args);
+ }
+ return EvaluateWithDFEHelper(
+ expr, param_names, type_param_names,
+ String::Handle(Library::Handle(method_cls.library()).url()),
+ String::Handle(method_cls.UserVisibleName()), false, args,
+ type_param_values);
}
RawObject* Instance::HashCode() const {
@@ -15668,20 +15909,22 @@
return true;
}
-uword Instance::ComputeCanonicalTableHash() const {
- ASSERT(!IsNull());
+uint32_t Instance::CanonicalizeHash() const {
+ if (IsNull()) {
+ return 2011;
+ }
NoSafepointScope no_safepoint;
const intptr_t instance_size = SizeFromClass();
ASSERT(instance_size != 0);
- uword hash = instance_size;
+ uint32_t hash = instance_size;
uword this_addr = reinterpret_cast<uword>(this->raw_ptr());
+ Instance& member = Instance::Handle();
for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
offset += kWordSize) {
- uword value = reinterpret_cast<uword>(
- *reinterpret_cast<RawObject**>(this_addr + offset));
- hash = CombineHashes(hash, value);
+ member ^= *reinterpret_cast<RawObject**>(this_addr + offset);
+ hash = CombineHashes(hash, member.CanonicalizeHash());
}
- return FinalizeHash(hash, (kBitsPerWord - 1));
+ return FinalizeHash(hash, String::kHashBits);
}
#if defined(DEBUG)
@@ -19381,6 +19624,10 @@
return BitwiseEqualsToDouble(Double::Cast(other).value());
}
+uint32_t Double::CanonicalizeHash() const {
+ return Hash64To32(bit_cast<uint64_t>(value()));
+}
+
RawDouble* Double::New(double d, Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->double_class() != Class::null());
Double& result = Double::Handle();
@@ -21782,16 +22029,18 @@
return true;
}
-uword Array::ComputeCanonicalTableHash() const {
- ASSERT(!IsNull());
+uint32_t Array::CanonicalizeHash() const {
NoSafepointScope no_safepoint;
intptr_t len = Length();
- uword hash = len;
- uword value = reinterpret_cast<uword>(GetTypeArguments());
- hash = CombineHashes(hash, value);
+ if (len == 0) {
+ return 1;
+ }
+ uint32_t hash = len;
+ Instance& member = Instance::Handle(GetTypeArguments());
+ hash = CombineHashes(hash, member.CanonicalizeHash());
for (intptr_t i = 0; i < len; i++) {
- value = reinterpret_cast<uword>(At(i));
- hash = CombineHashes(hash, value);
+ member ^= At(i);
+ hash = CombineHashes(hash, member.CanonicalizeHash());
}
return FinalizeHash(hash, kHashBits);
}
@@ -22408,12 +22657,12 @@
(memcmp(DataAddr(0), other_typed_data.DataAddr(0), len) == 0);
}
-uword TypedData::ComputeCanonicalTableHash() const {
+uint32_t TypedData::CanonicalizeHash() const {
const intptr_t len = this->LengthInBytes();
if (len == 0) {
return 1;
}
- uword hash = len;
+ uint32_t hash = len;
for (intptr_t i = 0; i < len; i++) {
hash = CombineHashes(len, GetUint8(i));
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a422fe0..c7749c5 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -558,7 +558,9 @@
// Initialize a new isolate either from a Kernel IR, from source, or from a
// snapshot.
- static RawError* Init(Isolate* isolate, kernel::Program* program);
+ static RawError* Init(Isolate* isolate,
+ const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size);
static void MakeUnusedSpaceTraversable(const Object& obj,
intptr_t original_size,
@@ -1363,14 +1365,19 @@
// Return true on success, or false and error otherwise.
bool ApplyPatch(const Class& patch, Error* error) const;
- // Evaluate the given expression as if it appeared in a static
- // method of this class and return the resulting value, or an
- // error object if evaluating the expression fails. The method has
- // the formal parameters given in param_names, and is invoked with
- // the argument values given in param_values.
+ // Evaluate the given expression as if it appeared in a static method of this
+ // class and return the resulting value, or an error object if evaluating the
+ // expression fails. The method has the formal (type) parameters given in
+ // (type_)param_names, and is invoked with the (type)argument values given in
+ // (type_)param_values.
RawObject* Evaluate(const String& expr,
const Array& param_names,
const Array& param_values) const;
+ RawObject* Evaluate(const String& expr,
+ const Array& param_names,
+ const Array& param_values,
+ const Array& type_param_names,
+ const TypeArguments& type_param_values) const;
RawError* EnsureIsFinalized(Thread* thread) const;
@@ -2136,6 +2143,7 @@
void ZeroEdgeCounters() const;
RawClass* Owner() const;
+ void set_owner(const Object& value) const;
RawClass* origin() const;
RawScript* script() const;
RawObject* RawOwner() const { return raw_ptr()->owner_; }
@@ -2504,6 +2512,10 @@
set_optimized_call_site_count(value);
}
+ void SetKernelDataAndScript(const Script& script,
+ const TypedData& data,
+ intptr_t offset);
+
intptr_t KernelDataProgramOffset() const;
RawTypedData* KernelData() const;
@@ -2857,6 +2869,18 @@
FOR_EACH_FUNCTION_KIND_BIT(DEFINE_ACCESSORS)
#undef DEFINE_ACCESSORS
+ // Indicates whether this function can be optimized on the background compiler
+ // thread.
+ bool is_background_optimizable() const {
+ return RawFunction::BackgroundOptimizableBit::decode(
+ raw_ptr()->packed_fields_);
+ }
+
+ void set_is_background_optimizable(bool value) const {
+ set_packed_fields(RawFunction::BackgroundOptimizableBit::update(
+ value, raw_ptr()->packed_fields_));
+ }
+
private:
void set_ic_data_array(const Array& value) const;
void SetInstructionsSafe(const Code& value) const;
@@ -2904,7 +2928,6 @@
void set_name(const String& value) const;
void set_kind(RawFunction::Kind value) const;
void set_parent_function(const Function& value) const;
- void set_owner(const Object& value) const;
RawFunction* implicit_closure_function() const;
void set_implicit_closure_function(const Function& value) const;
RawInstance* implicit_static_closure() const;
@@ -3695,15 +3718,21 @@
static RawLibrary* New(const String& url);
- // Evaluate the given expression as if it appeared in an top-level
- // method of this library and return the resulting value, or an
- // error object if evaluating the expression fails. The method has
- // the formal parameters given in param_names, and is invoked with
- // the argument values given in param_values.
+ // Evaluate the given expression as if it appeared in an top-level method of
+ // this library and return the resulting value, or an error object if
+ // evaluating the expression fails. The method has the formal (type)
+ // parameters given in (type_)param_names, and is invoked with the (type)
+ // argument values given in (type_)param_values.
RawObject* Evaluate(const String& expr,
const Array& param_names,
const Array& param_values) const;
+ RawObject* Evaluate(const String& expr,
+ const Array& param_names,
+ const Array& param_values,
+ const Array& type_param_names,
+ const TypeArguments& type_arguments) const;
+
// Library scope name dictionary.
//
// TODO(turnidge): The Lookup functions are not consistent in how
@@ -5487,7 +5516,7 @@
virtual bool OperatorEquals(const Instance& other) const;
bool IsIdenticalTo(const Instance& other) const;
virtual bool CanonicalizeEquals(const Instance& other) const;
- virtual uword ComputeCanonicalTableHash() const;
+ virtual uint32_t CanonicalizeHash() const;
intptr_t SizeFromClass() const {
#if defined(DEBUG)
@@ -5561,16 +5590,23 @@
// (if not NULL) to call.
bool IsCallable(Function* function) const;
- // Evaluate the given expression as if it appeared in an instance
- // method of this instance and return the resulting value, or an
- // error object if evaluating the expression fails. The method has
- // the formal parameters given in param_names, and is invoked with
- // the argument values given in param_values.
+ // Evaluate the given expression as if it appeared in an instance method of
+ // this instance and return the resulting value, or an error object if
+ // evaluating the expression fails. The method has the formal (type)
+ // parameters given in (type_)param_names, and is invoked with the (type)
+ // argument values given in (type_)param_values.
RawObject* Evaluate(const Class& method_cls,
const String& expr,
const Array& param_names,
const Array& param_values) const;
+ RawObject* Evaluate(const Class& method_cls,
+ const String& expr,
+ const Array& param_names,
+ const Array& param_values,
+ const Array& type_param_names,
+ const TypeArguments& type_param_values) const;
+
// Equivalent to invoking hashCode on this instance.
virtual RawObject* HashCode() const;
@@ -5878,6 +5914,10 @@
(len * kBytesPerElement));
}
+ virtual uint32_t CanonicalizeHash() const {
+ // Hash() is not stable until finalization is done.
+ return 0;
+ }
intptr_t Hash() const;
static RawTypeArguments* New(intptr_t len, Heap::Space space = Heap::kOld);
@@ -5957,6 +5997,7 @@
virtual bool CanonicalizeEquals(const Instance& other) const {
return Equals(other);
}
+ virtual uint32_t CanonicalizeHash() const { return Hash(); }
virtual bool Equals(const Instance& other) const {
return IsEquivalent(other);
}
@@ -6733,10 +6774,7 @@
virtual bool CanonicalizeEquals(const Instance& other) const {
return Equals(other);
}
- virtual uword ComputeCanonicalTableHash() const {
- UNREACHABLE();
- return 0;
- }
+ virtual uint32_t CanonicalizeHash() const { return AsTruncatedUint32Value(); }
virtual bool Equals(const Instance& other) const;
virtual RawObject* HashCode() const { return raw(); }
@@ -7013,10 +7051,7 @@
bool BitwiseEqualsToDouble(double value) const;
virtual bool OperatorEquals(const Instance& other) const;
virtual bool CanonicalizeEquals(const Instance& other) const;
- virtual uword ComputeCanonicalTableHash() const {
- UNREACHABLE();
- return 0;
- }
+ virtual uint32_t CanonicalizeHash() const;
static RawDouble* New(double d, Heap::Space space = Heap::kNew);
@@ -7166,10 +7201,7 @@
virtual bool CanonicalizeEquals(const Instance& other) const {
return Equals(other);
}
- virtual uword ComputeCanonicalTableHash() const {
- UNREACHABLE();
- return 0;
- }
+ virtual uint32_t CanonicalizeHash() const { return Hash(); }
virtual bool Equals(const Instance& other) const;
intptr_t CompareTo(const String& other) const;
@@ -7844,6 +7876,10 @@
return value ? Bool::True() : Bool::False();
}
+ virtual uint32_t CanonicalizeHash() const {
+ return raw() == True().raw() ? 1231 : 1237;
+ }
+
private:
void set_value(bool value) const {
StoreNonPointer(&raw_ptr()->value_, value);
@@ -7900,7 +7936,7 @@
}
virtual bool CanonicalizeEquals(const Instance& other) const;
- virtual uword ComputeCanonicalTableHash() const;
+ virtual uint32_t CanonicalizeHash() const;
static const intptr_t kBytesPerElement = kWordSize;
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
@@ -8074,10 +8110,6 @@
UNREACHABLE();
return false;
}
- virtual uword ComputeCanonicalTableHash() const {
- UNREACHABLE();
- return 0;
- }
// We don't expect a growable object array to be canonicalized.
virtual RawInstance* CheckAndCanonicalize(Thread* thread,
@@ -8253,7 +8285,7 @@
}
virtual bool CanonicalizeEquals(const Instance& other) const;
- virtual uword ComputeCanonicalTableHash() const;
+ virtual uint32_t CanonicalizeHash() const;
#define TYPED_GETTER_SETTER(name, type) \
type Get##name(intptr_t byte_offset) const { \
@@ -8778,7 +8810,9 @@
// None of the fields of a closure are instances.
return true;
}
-
+ virtual uint32_t CanonicalizeHash() const {
+ return Function::Handle(function()).Hash();
+ }
int64_t ComputeHash() const;
static RawClosure* New(const TypeArguments& instantiator_type_arguments,
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 4890d04..0fc1385 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4495,6 +4495,7 @@
LinkedHashMap& cc_map = LinkedHashMap::Handle(LinkedHashMap::NewDefault());
// 3. Expect them to have identical structure.
+ TransitionNativeToVM transition(thread);
CheckIdenticalHashStructure(dart_map, cc_map);
}
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 879df86..727542f 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -14,7 +14,7 @@
#include <zircon/syscalls/object.h>
#include <zircon/types.h>
-#include <fuchsia/cpp/time_zone.h>
+#include <time_zone/cpp/fidl.h>
#include "lib/app/cpp/environment_services.h"
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 6c28bd6..169b5c9 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -11,6 +11,7 @@
#include <fcntl.h> // NOLINT
#include <limits.h> // NOLINT
#include <malloc.h> // NOLINT
+#include <sys/mman.h> // NOLINT
#include <sys/resource.h> // NOLINT
#include <sys/stat.h> // NOLINT
#include <sys/syscall.h> // NOLINT
@@ -38,7 +39,21 @@
false,
"Generate events symbols for profiling with perf");
+DEFINE_FLAG(bool,
+ generate_perf_jitdump,
+ false,
+ "Generate jitdump file to use with perf-inject");
+
+DECLARE_FLAG(bool, write_protect_code);
+
// Linux CodeObservers.
+
+// Simple perf support: generate /tmp/perf-<pid>.map file that maps
+// memory ranges to symbol names for JIT generated code. This allows
+// perf-report to resolve addresses falling into JIT generated code.
+// However perf-annotate does not work in this mode because JIT code
+// is transient and does not exist anymore at the moment when you
+// invoke perf-report.
class PerfCodeObserver : public CodeObserver {
public:
PerfCodeObserver() : out_file_(NULL) {
@@ -89,6 +104,197 @@
DISALLOW_COPY_AND_ASSIGN(PerfCodeObserver);
};
+// Code observer that generates a JITDUMP[1] file that can be interpreted by
+// perf-inject to generate ELF images for JIT generated code objects, which
+// allows both perf-report and perf-annotate to recognize them.
+//
+// Usage:
+//
+// $ perf record -k mono dart --generate-perf-jitdump benchmark.dart
+// $ perf inject -j -i perf.data -o perf.data.jitted
+// $ perf report -i perf.data.jitted
+//
+// [1] see linux/tools/perf/Documentation/jitdump-specification.txt for
+// JITDUMP binary format.
+class JitDumpCodeObserver : public CodeObserver {
+ public:
+ JitDumpCodeObserver()
+ : out_file_(nullptr), mapped_(nullptr), mapped_size_(0), code_id_(0) {
+ const intptr_t pid = getpid();
+ char* const filename = OS::SCreate(nullptr, "/tmp/jit-%" Pd ".dump", pid);
+ const int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR);
+ free(filename);
+
+ if (fd == -1) {
+ return;
+ }
+
+ // Map JITDUMP file, this mapping will be recorded by perf. This allows
+ // perf-inject to find this file later.
+ const long page_size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int)
+ if (page_size == -1) {
+ close(fd);
+ return;
+ }
+
+ mapped_ =
+ mmap(nullptr, page_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
+ if (mapped_ == nullptr) {
+ close(fd);
+ return;
+ }
+ mapped_size_ = page_size;
+
+ out_file_ = fdopen(fd, "w+");
+ if (out_file_ == nullptr) {
+ close(fd);
+ return;
+ }
+
+ // Buffer the output to avoid high IO overheads - we are going to be
+ // writing all JIT generated code out.
+ setvbuf(out_file_, nullptr, _IOFBF, 2 * MB);
+
+ // Disable code write protection, constant flickering of page attributes
+ // confuses perf.
+ FLAG_write_protect_code = false;
+
+ // Write JITDUMP header.
+ WriteHeader();
+ }
+
+ ~JitDumpCodeObserver() {
+ if (mapped_ != nullptr) {
+ munmap(mapped_, mapped_size_);
+ mapped_ = nullptr;
+ }
+
+ if (out_file_ != nullptr) {
+ fclose(out_file_);
+ out_file_ = nullptr;
+ }
+ }
+
+ virtual bool IsActive() const {
+ return FLAG_generate_perf_jitdump && (out_file_ != nullptr);
+ }
+
+ virtual void Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized) {
+ const char* marker = optimized ? "*" : "";
+ char* buffer = OS::SCreate(Thread::Current()->zone(), "%s%s", marker, name);
+ const size_t name_length = strlen(buffer);
+
+ CodeLoadEvent ev;
+ ev.event = BaseEvent::kLoad;
+ ev.size = sizeof(ev) + (name_length + 1) + size;
+ ev.time_stamp = OS::GetCurrentMonotonicTicks();
+ ev.process_id = getpid();
+ ev.thread_id = syscall(SYS_gettid);
+ ev.vma = base;
+ ev.code_address = base;
+ ev.code_size = size;
+
+ {
+ MutexLocker ml(CodeObservers::mutex());
+ ev.code_id = code_id_++;
+
+ WriteFully(&ev, sizeof(ev));
+ WriteFully(buffer, name_length + 1);
+ WriteFully(reinterpret_cast<void*>(base), size);
+ }
+ }
+
+ private:
+ struct Header {
+ const uint32_t magic = 0x4A695444;
+ const uint32_t version = 1;
+ const uint32_t size = sizeof(Header);
+ uint32_t elf_mach_target;
+ const uint32_t reserved = 0xDEADBEEF;
+ uint32_t process_id;
+ uint64_t time_stamp;
+ const uint64_t flags = 0;
+ };
+
+ struct BaseEvent {
+ enum Event {
+ kLoad = 0,
+ kMove = 1,
+ kDebugInfo = 2,
+ kClose = 3,
+ kUnwindingInfo = 4
+ };
+
+ uint32_t event;
+ uint32_t size;
+ uint64_t time_stamp;
+ };
+
+ struct CodeLoadEvent : BaseEvent {
+ uint32_t process_id;
+ uint32_t thread_id;
+ uint64_t vma;
+ uint64_t code_address;
+ uint64_t code_size;
+ uint64_t code_id;
+ };
+
+ // ELF machine architectures
+ // From linux/include/uapi/linux/elf-em.h
+ static const uint32_t EM_386 = 3;
+ static const uint32_t EM_X86_64 = 62;
+ static const uint32_t EM_ARM = 40;
+ static const uint32_t EM_AARCH64 = 183;
+
+ static uint32_t GetElfMachineArchitecture() {
+#if TARGET_ARCH_IA32
+ return EM_386;
+#elif TARGET_ARCH_X64
+ return EM_X86_64;
+#elif TARGET_ARCH_ARM
+ return EM_ARM;
+#elif TARGET_ARCH_ARM64
+ return EM_AARCH64;
+#else
+ UNREACHABLE();
+ return 0;
+#endif
+ }
+
+ void WriteHeader() {
+ Header header;
+ header.elf_mach_target = GetElfMachineArchitecture();
+ header.process_id = getpid();
+ header.time_stamp = OS::GetCurrentTimeMicros();
+ WriteFully(&header, sizeof(header));
+ }
+
+ void WriteFully(void* buffer, size_t size) {
+ const char* ptr = static_cast<char*>(buffer);
+ while (size > 0) {
+ const size_t written = fwrite(ptr, 1, size, out_file_);
+ if (written == 0) {
+ UNREACHABLE();
+ break;
+ }
+ size -= written;
+ ptr += written;
+ }
+ }
+
+ FILE* out_file_;
+ void* mapped_;
+ long mapped_size_; // NOLINT(runtime/int)
+
+ intptr_t code_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(JitDumpCodeObserver);
+};
+
#endif // !PRODUCT
const char* OS::Name() {
@@ -329,6 +535,10 @@
if (FLAG_generate_perf_events_symbols) {
CodeObservers::Register(new PerfCodeObserver);
}
+
+ if (FLAG_generate_perf_jitdump) {
+ CodeObservers::Register(new JitDumpCodeObserver);
+ }
#endif // !PRODUCT
}
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index ff43451..df7e04a 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -1075,14 +1075,6 @@
set_tasks(tasks() - 1);
ml.NotifyAll();
}
-
- if (compact) {
- // Const object tables are hashed by address: rehash.
- SafepointOperationScope safepoint(thread);
- StackZone zone(thread);
- HANDLESCOPE(thread);
- thread->isolate()->RehashConstants();
- }
}
void PageSpace::BlockingSweep() {
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 29fb803..ac5cd08 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -7588,7 +7588,7 @@
const TokenPosition token_pos = ST(closure_body->token_pos());
Function& completer_constructor = Function::ZoneHandle(Z);
- if (FLAG_sync_async) {
+ if (I->sync_async()) {
const Class& completer_class = Class::Handle(
Z, async_lib.LookupClassAllowPrivate(Symbols::_AsyncAwaitCompleter()));
ASSERT(!completer_class.IsNull());
@@ -7698,7 +7698,7 @@
current_block_->statements->Add(store_async_catch_error_callback);
- if (FLAG_sync_async) {
+ if (I->sync_async()) {
// Add to AST:
// :async_completer.start(:async_op);
ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index 14148be..a6400e8 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -311,9 +311,7 @@
static Value ValueOf(Pair kv) { return kv; }
- static inline intptr_t Hashcode(Key key) {
- return key->ComputeCanonicalTableHash();
- }
+ static inline intptr_t Hashcode(Key key) { return key->CanonicalizeHash(); }
static inline bool IsKeyEqual(Pair pair, Key key) {
return pair->CanonicalizeEquals(*key);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 2e3e2f1..e62baec 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -779,9 +779,10 @@
switch (kind) {
case Snapshot::kFull:
case Snapshot::kScript:
- case Snapshot::kFullJIT:
case Snapshot::kFullAOT:
return reinterpret_cast<RawObject**>(&ptr()->direct_subclasses_);
+ case Snapshot::kFullJIT:
+ return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -888,7 +889,7 @@
};
static constexpr intptr_t kMaxFixedParametersBits = 15;
- static constexpr intptr_t kMaxOptionalParametersBits = 15;
+ static constexpr intptr_t kMaxOptionalParametersBits = 14;
private:
// So that the SkippedCodeFunctions::DetachCode can null out the code fields.
@@ -951,8 +952,13 @@
typedef BitField<uint32_t, bool, PackedIsNoSuchMethodForwarder::kNextBit, 1>
PackedHasNamedOptionalParameters;
typedef BitField<uint32_t,
- uint16_t,
+ bool,
PackedHasNamedOptionalParameters::kNextBit,
+ 1>
+ BackgroundOptimizableBit;
+ typedef BitField<uint32_t,
+ uint16_t,
+ BackgroundOptimizableBit::kNextBit,
kMaxFixedParametersBits>
PackedNumFixedParameters;
typedef BitField<uint32_t,
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index aadb840..645f1ea 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2015,7 +2015,8 @@
if (FLAG_enable_inlining_annotations) {
FATAL("Cannot enable inlining annotations and background compilation");
}
- if (!BackgroundCompiler::IsDisabled(isolate)) {
+ if (!BackgroundCompiler::IsDisabled(isolate) &&
+ function.is_background_optimizable()) {
if (FLAG_background_compilation_stop_alot) {
BackgroundCompiler::Stop(isolate);
}
@@ -2026,6 +2027,7 @@
function.SetUsageCounter(INT_MIN);
BackgroundCompiler::Start(isolate);
isolate->background_compiler()->CompileOptimized(function);
+
// Continue in the same code.
arguments.SetReturn(function);
return;
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index e07e393..e38d191 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -268,6 +268,10 @@
// Keep :async_stack_trace for asynchronous debugging.
return false;
}
+ if (str.raw() == Symbols::FunctionTypeArgumentsVar().raw()) {
+ // Keep :function_type_arguments for accessing type variables in debugging.
+ return false;
+ }
return str.CharAt(0) == ':';
}
@@ -644,7 +648,8 @@
(variable->name().raw() == Symbols::ExceptionVar().raw()) ||
(variable->name().raw() == Symbols::SavedTryContextVar().raw()) ||
(variable->name().raw() == Symbols::ArgDescVar().raw()) ||
- (variable->name().raw() == Symbols::FunctionTypeArgumentsVar().raw())) {
+ (variable->name().raw() ==
+ Symbols::FunctionTypeArgumentsVar().raw())) {
// Don't capture those variables because the VM expects them to be on
// the stack.
continue;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index d756a0f..bfbbe3f 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -241,7 +241,7 @@
If the type of a response begins with the _@_ character, then that
response is a _reference_. If the type name of a response does not
-begin with the _@_ character, it is the an _object_. A reference is
+begin with the _@_ character, it is an _object_. A reference is
intended to be a subset of an object which provides enough information
to generate a reasonable looking reference to the object.
@@ -355,7 +355,7 @@
```
ReturnType methodName(parameterType1 parameterName1,
- parameterType2, parameterName2,
+ parameterType2 parameterName2,
...)
```
@@ -377,7 +377,7 @@
_[optional]_ following the parameter name:
```
-ReturnType methodName(parameterType parameterName [optional)
+ReturnType methodName(parameterType parameterName [optional])
```
A description of the return types and parameter types is provided
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 04581b5..a15efee 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -244,7 +244,7 @@
If the type of a response begins with the _@_ character, then that
response is a _reference_. If the type name of a response does not
-begin with the _@_ character, it is the an _object_. A reference is
+begin with the _@_ character, it is an _object_. A reference is
intended to be a subset of an object which provides enough information
to generate a reasonable looking reference to the object.
@@ -358,7 +358,7 @@
```
ReturnType methodName(parameterType1 parameterName1,
- parameterType2, parameterName2,
+ parameterType2 parameterName2,
...)
```
@@ -380,7 +380,7 @@
_[optional]_ following the parameter name:
```
-ReturnType methodName(parameterType parameterName [optional)
+ReturnType methodName(parameterType parameterName [optional])
```
A description of the return types and parameter types is provided
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 96acbe5..8431c2a 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -330,8 +330,6 @@
}
Isolate* I = reinterpret_cast<Isolate*>(parameter);
ASSERT(ServiceIsolate::IsServiceIsolate(I));
- ServiceIsolate::SetServiceIsolate(NULL);
- ServiceIsolate::SetServicePort(ILLEGAL_PORT);
I->WaitForOutstandingSpawns();
{
// Print the error if there is one. This may execute dart code to
@@ -351,8 +349,13 @@
if (!error.IsNull() && !error.IsUnwindError()) {
OS::PrintErr("vm-service: Error: %s\n", error.ToErrorCString());
}
+ TransitionVMToNative transition(T);
Dart::RunShutdownCallback();
}
+ ASSERT(ServiceIsolate::IsServiceIsolate(I));
+ ServiceIsolate::SetServiceIsolate(NULL);
+ ServiceIsolate::SetServicePort(ILLEGAL_PORT);
+
// Shut the isolate down.
Dart::ShutdownIsolate(I);
if (FLAG_trace_service) {
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 4b3f6bc..576e903 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -325,6 +325,7 @@
V(ForwardingCorpse, "ForwardingCorpse") \
V(InvocationMirror, "_InvocationMirror") \
V(AllocateInvocationMirror, "_allocateInvocationMirror") \
+ V(AllocateInvocationMirrorForClosure, "_allocateInvocationMirrorForClosure") \
V(toString, "toString") \
V(_lookupHandler, "_lookupHandler") \
V(_handleMessage, "_handleMessage") \
@@ -450,7 +451,8 @@
V(PrependTypeArguments, "_prependTypeArguments") \
V(DartDeveloperCausalAsyncStacks, "dart.developer.causal_async_stacks") \
V(_AsyncStarListenHelper, "_asyncStarListenHelper") \
- V(GrowRegExpStack, "_growRegExpStack")
+ V(GrowRegExpStack, "_growRegExpStack") \
+ V(DebugProcedureName, ":Eval")
// Contains a list of frequently used strings in a canonicalized form. This
// list is kept in the vm_isolate in order to share the copy across isolates
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 10795eb..08becf9 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -81,8 +81,6 @@
}
}
-static void NoopRelease(uint8_t* data) {}
-
Dart_Isolate TestCase::CreateIsolate(const uint8_t* data_buffer,
intptr_t len,
const uint8_t* instr_buffer,
@@ -97,13 +95,8 @@
isolate = Dart_CreateIsolate(name, NULL, data_buffer, instr_buffer, NULL,
NULL, &api_flags, data, &err);
} else {
- kernel::Program* program = reinterpret_cast<kernel::Program*>(
- Dart_ReadKernelBinary(data_buffer, len, NoopRelease));
- if (program != NULL) {
- isolate = Dart_CreateIsolateFromKernel(name, NULL, program, &api_flags,
- data, &err);
- delete program;
- }
+ isolate = Dart_CreateIsolateFromKernel(name, NULL, data_buffer, len,
+ &api_flags, data, &err);
}
if (isolate == NULL) {
OS::PrintErr("Creation of isolate failed '%s'\n", err);
@@ -237,7 +230,8 @@
char* TestCase::CompileTestScriptWithDFE(const char* url,
const char* source,
- void** kernel_pgm,
+ const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
bool incrementally) {
// clang-format off
Dart_SourceFile sourcefiles[] = {
@@ -248,14 +242,12 @@
"file:///.packages", "untitled:/"
}};
// clang-format on
- return CompileTestScriptWithDFE(url,
- sizeof(sourcefiles) / sizeof(Dart_SourceFile),
- sourcefiles, kernel_pgm, incrementally);
+ return CompileTestScriptWithDFE(
+ url, sizeof(sourcefiles) / sizeof(Dart_SourceFile), sourcefiles,
+ kernel_buffer, kernel_buffer_size, incrementally);
}
-static void ReleaseFetchedBytes(uint8_t* buffer) {
- free(buffer);
-}
+#if 0
char* TestCase::CompileTestScriptWithDFE(const char* url,
int sourcefiles_count,
@@ -267,7 +259,13 @@
url, FLAG_strong ? platform_strong_dill : platform_dill,
FLAG_strong ? platform_strong_dill_size : platform_dill_size,
sourcefiles_count, sourcefiles, incrementally, NULL);
+ return ValidateCompilationResult(zone, compilation_result, kernel_pgm);
+}
+char* TestCase::ValidateCompilationResult(
+ Zone* zone,
+ Dart_KernelCompilationResult compilation_result,
+ void** kernel_pgm) {
if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
char* result =
OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
@@ -286,6 +284,41 @@
}
return NULL;
}
+#endif
+
+char* TestCase::CompileTestScriptWithDFE(const char* url,
+ int sourcefiles_count,
+ Dart_SourceFile sourcefiles[],
+ const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
+ bool incrementally) {
+ Zone* zone = Thread::Current()->zone();
+ Dart_KernelCompilationResult compilation_result = Dart_CompileSourcesToKernel(
+ url, FLAG_strong ? platform_strong_dill : platform_dill,
+ FLAG_strong ? platform_strong_dill_size : platform_dill_size,
+ sourcefiles_count, sourcefiles, incrementally, NULL);
+ return ValidateCompilationResult(zone, compilation_result, kernel_buffer,
+ kernel_buffer_size);
+}
+
+char* TestCase::ValidateCompilationResult(
+ Zone* zone,
+ Dart_KernelCompilationResult compilation_result,
+ const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size) {
+ if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
+ char* result =
+ OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
+ free(compilation_result.error);
+ return result;
+ }
+ *kernel_buffer = compilation_result.kernel;
+ *kernel_buffer_size = compilation_result.kernel_size;
+ if (kernel_buffer == NULL) {
+ return OS::SCreate(zone, "front end generated a NULL kernel file");
+ }
+ return NULL;
+}
static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
@@ -456,17 +489,25 @@
const char* prefixed_lib_uri =
OS::SCreate(Thread::Current()->zone(), "file:///%s", lib_uri);
Dart_SourceFile sourcefiles[] = {{prefixed_lib_uri, script}};
- void* kernel_pgm = NULL;
+ const uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
int sourcefiles_count = sizeof(sourcefiles) / sizeof(Dart_SourceFile);
char* error = TestCase::CompileTestScriptWithDFE(
- sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_pgm, true);
+ sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_buffer,
+ &kernel_buffer_size, true);
if (error != NULL) {
return Dart_NewApiError(error);
}
- Dart_Handle url = NewString(prefixed_lib_uri);
- Dart_Handle lib = Dart_LoadLibrary(
- url, Dart_Null(), reinterpret_cast<Dart_Handle>(kernel_pgm), 0, 0);
+ Dart_Handle lib =
+ Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
EXPECT_VALID(lib);
+
+ // TODO(32618): Kernel doesn't correctly represent the root library.
+ lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri));
+ DART_CHECK_VALID(lib);
+ Dart_Handle result = Dart_SetRootLibrary(lib);
+ DART_CHECK_VALID(result);
+
Dart_SetNativeResolver(lib, resolver, NULL);
return lib;
} else {
@@ -482,19 +523,27 @@
bool finalize,
bool incrementally) {
// First script is the main script.
- Dart_Handle url = NewString(sourcefiles[0].uri);
Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
EXPECT_VALID(result);
- void* kernel_pgm = NULL;
+ const uint8_t* kernel_buffer = NULL;
+ intptr_t kernel_buffer_size = 0;
char* error = TestCase::CompileTestScriptWithDFE(
- sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_pgm,
- incrementally);
+ sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_buffer,
+ &kernel_buffer_size, incrementally);
if (error != NULL) {
return Dart_NewApiError(error);
}
- Dart_Handle lib = Dart_LoadScript(
- url, Dart_Null(), reinterpret_cast<Dart_Handle>(kernel_pgm), 0, 0);
+
+ Dart_Handle lib =
+ Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
DART_CHECK_VALID(lib);
+
+ // BOGUS: Kernel doesn't correctly represent the root library.
+ lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri));
+ DART_CHECK_VALID(lib);
+ result = Dart_SetRootLibrary(lib);
+ DART_CHECK_VALID(result);
+
result = Dart_SetNativeResolver(lib, resolver, NULL);
DART_CHECK_VALID(result);
if (finalize) {
@@ -586,7 +635,8 @@
return TriggerReload();
}
-Dart_Handle TestCase::ReloadTestKernel(const void* kernel) {
+Dart_Handle TestCase::ReloadTestKernel(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size) {
return TriggerReload();
}
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 5aa1d6a..edb8b8e 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -316,12 +316,14 @@
static char* CompileTestScriptWithDFE(const char* url,
const char* source,
- void** kernel_pgm,
+ const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
bool incrementally = true);
static char* CompileTestScriptWithDFE(const char* url,
int sourcefiles_count,
Dart_SourceFile sourcefiles[],
- void** kernel_pgm,
+ const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size,
bool incrementally = true);
static Dart_Handle LoadTestScript(const char* script,
Dart_NativeEntryResolver resolver,
@@ -362,7 +364,8 @@
// Helper function which reloads the current isolate using |script|.
static Dart_Handle ReloadTestScript(const char* script);
- static Dart_Handle ReloadTestKernel(const void* kernel);
+ static Dart_Handle ReloadTestKernel(const uint8_t* kernel_buffer,
+ intptr_t kernel_buffer_size);
static void AddTestLib(const char* url, const char* source);
static const char* GetTestLib(const char* url);
@@ -379,6 +382,11 @@
const char* name,
void* data = NULL);
+ static char* ValidateCompilationResult(Zone* zone,
+ Dart_KernelCompilationResult result,
+ const uint8_t** kernel_buffer,
+ intptr_t* kernel_buffer_size);
+
RunEntry* const run_;
};
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 5a3cf37..62ea806 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -46,6 +46,7 @@
# ........dartdevk.dart.snapshot
# ........kernel_summary_worker.dart.snapshot
# ........pub.dart.snapshot
+# ........pub2.dart.snapshot
#.........resources/
#...........dartdoc/
#..............packages
@@ -133,6 +134,10 @@
"pub",
"../utils/pub",
],
+ [
+ "pub2",
+ "../utils/pub:pub2",
+ ],
]
_full_sdk_snapshots = [
@@ -173,6 +178,10 @@
"../utils/pub",
],
[
+ "pub2",
+ "../utils/pub:pub2",
+ ],
+ [
"kernel-service",
"../utils/kernel-service",
],
diff --git a/sdk/bin/dartdevc b/sdk/bin/dartdevc
index 5b75ad2..e0c8e7a 100755
--- a/sdk/bin/dartdevc
+++ b/sdk/bin/dartdevc
@@ -45,4 +45,4 @@
DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart"
-exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"
+exec "$DART" "--preview-dart-2" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"
diff --git a/sdk/bin/dartdevc.bat b/sdk/bin/dartdevc.bat
index fec39e4..d636eee 100644
--- a/sdk/bin/dartdevc.bat
+++ b/sdk/bin/dartdevc.bat
@@ -36,7 +36,7 @@
set DEV_COMPILER=%DART_ROOT%\third_party\pkg\dev_compiler\bin\dartdevc.dart
-"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %*
+"%DART%" "--preview-dart-2" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %*
endlocal
diff --git a/sdk/bin/dartdevc_sdk b/sdk/bin/dartdevc_sdk
index 7bc98de..aebe28d 100755
--- a/sdk/bin/dartdevc_sdk
+++ b/sdk/bin/dartdevc_sdk
@@ -28,4 +28,4 @@
# We are running the snapshot in the built SDK.
DART="$BIN_DIR/dart"
-exec "$DART" "$SNAPSHOT" "$SDK_ARG" "$@"
+exec "$DART" "--preview-dart-2" "$SNAPSHOT" "$SDK_ARG" "$@"
diff --git a/sdk/bin/dartdevc_sdk.bat b/sdk/bin/dartdevc_sdk.bat
index 5dbf707..f931a28 100644
--- a/sdk/bin/dartdevc_sdk.bat
+++ b/sdk/bin/dartdevc_sdk.bat
@@ -22,7 +22,7 @@
set SDK_ARG=--dart-sdk=%SDK_DIR%
-"%DART%" "%SNAPSHOT%" "%SDK_ARG%" %*
+"%DART%" "--preview-dart-2" "%SNAPSHOT%" "%SDK_ARG%" %*
endlocal
diff --git a/sdk/bin/pub_sdk b/sdk/bin/pub_sdk
index f42f609..74a86ca 100755
--- a/sdk/bin/pub_sdk
+++ b/sdk/bin/pub_sdk
@@ -15,13 +15,20 @@
echo "$file"
}
+function array_contains() {
+ local needle="$1"
+ local element
+ shift
+ for element; do [ "$element" = "$needle" ] && return 0; done
+ return 1
+}
+
# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
PROG_NAME="$(follow_links "$BASH_SOURCE")"
# Handle the case where dart-sdk/bin has been symlinked to.
BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
-SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
unset VM_OPTIONS
declare -a VM_OPTIONS
@@ -34,4 +41,10 @@
# Run the pub snapshot.
DART="$BIN_DIR/dart"
-exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
+if array_contains "--preview-dart-2" "${VM_OPTIONS[@]}"; then
+ SNAPSHOT="$BIN_DIR/snapshots/pub2.dart.snapshot"
+ exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
+else
+ SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
+ exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
+fi
diff --git a/sdk/bin/pub_sdk.bat b/sdk/bin/pub_sdk.bat
index 3ea8f13..1c400bd 100644
--- a/sdk/bin/pub_sdk.bat
+++ b/sdk/bin/pub_sdk.bat
@@ -18,13 +18,21 @@
IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
set VM_OPTIONS=
+set USING_DART_2=
rem We allow extra vm options to be passed in through an environment variable.
if not "_%DART_VM_OPTIONS%_" == "__" (
set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS%
+ for %%o in (%DART_VM_OPTIONS%) do (
+ if "%%o" equ "--preview-dart-2" set USING_DART_2=y
+ )
)
-"%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub.dart.snapshot" %*
+if defined USING_DART_2 (
+ "%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub2.dart.snapshot" %*
+) else (
+ "%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub.dart.snapshot" %*
+)
endlocal
@@ -42,4 +50,4 @@
endlocal & set %~2=%result%
goto :eof
-:end
\ No newline at end of file
+:end
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index eef525c..5ef35ee 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -14,8 +14,6 @@
wrapException,
unwrapException;
-import 'dart:_isolate_helper' show TimerImpl;
-
import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
import 'dart:_async_await_error_codes' as async_error_codes;
@@ -111,7 +109,7 @@
static Timer _createTimer(Duration duration, void callback()) {
int milliseconds = duration.inMilliseconds;
if (milliseconds < 0) milliseconds = 0;
- return new TimerImpl(milliseconds, callback);
+ return new _TimerImpl(milliseconds, callback);
}
@patch
@@ -119,10 +117,81 @@
Duration duration, void callback(Timer timer)) {
int milliseconds = duration.inMilliseconds;
if (milliseconds < 0) milliseconds = 0;
- return new TimerImpl.periodic(milliseconds, callback);
+ return new _TimerImpl.periodic(milliseconds, callback);
}
}
+class _TimerImpl implements Timer {
+ final bool _once;
+ int _handle;
+ int _tick = 0;
+
+ _TimerImpl(int milliseconds, void callback()) : _once = true {
+ if (_hasTimer()) {
+ void internalCallback() {
+ _handle = null;
+ this._tick = 1;
+ callback();
+ }
+
+ _handle = JS('int', 'self.setTimeout(#, #)',
+ convertDartClosureToJS(internalCallback, 0), milliseconds);
+ } else {
+ throw new UnsupportedError('`setTimeout()` not found.');
+ }
+ }
+
+ _TimerImpl.periodic(int milliseconds, void callback(Timer timer))
+ : _once = false {
+ if (_hasTimer()) {
+ int start = JS('int', 'Date.now()');
+ _handle = JS(
+ 'int',
+ 'self.setInterval(#, #)',
+ convertDartClosureToJS(() {
+ int tick = this._tick + 1;
+ if (milliseconds > 0) {
+ int duration = JS('int', 'Date.now()') - start;
+ if (duration > (tick + 1) * milliseconds) {
+ tick = duration ~/ milliseconds;
+ }
+ }
+ this._tick = tick;
+ callback(this);
+ }, 0),
+ milliseconds);
+ } else {
+ throw new UnsupportedError('Periodic timer.');
+ }
+ }
+
+ @override
+ bool get isActive => _handle != null;
+
+ @override
+ int get tick => _tick;
+
+ @override
+ void cancel() {
+ if (_hasTimer()) {
+ if (_handle == null) return;
+ if (_once) {
+ JS('void', 'self.clearTimeout(#)', _handle);
+ } else {
+ JS('void', 'self.clearInterval(#)', _handle);
+ }
+ _handle = null;
+ } else {
+ throw new UnsupportedError('Canceling a timer.');
+ }
+ }
+}
+
+bool _hasTimer() {
+ requiresPreamble();
+ return JS('', 'self.setTimeout') != null;
+}
+
class _AsyncAwaitCompleter<T> implements Completer<T> {
final _completer = new Completer<T>.sync();
bool isSync;
diff --git a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
index aab714a..c5d1177 100644
--- a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -125,10 +125,10 @@
V operator [](Object key) {
if (_isStringKey(key)) {
var strings = _strings;
- return (strings == null) ? null : _getTableEntry(strings, key);
+ return JS('', '#', strings == null ? null : _getTableEntry(strings, key));
} else if (_isNumericKey(key)) {
var nums = _nums;
- return (nums == null) ? null : _getTableEntry(nums, key);
+ return JS('', '#', nums == null ? null : _getTableEntry(nums, key));
} else {
return _get(key);
}
@@ -139,7 +139,7 @@
if (rest == null) return null;
var bucket = _getBucket(rest, key);
int index = _findBucketIndex(bucket, key);
- return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1);
+ return (index < 0) ? null : JS('', '#[#]', bucket, index + 1);
}
void operator []=(K key, V value) {
diff --git a/sdk/lib/_internal/js_runtime/lib/constant_map.dart b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
index 9f571b9..3d92fd8 100644
--- a/sdk/lib/_internal/js_runtime/lib/constant_map.dart
+++ b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
@@ -125,7 +125,7 @@
V operator [](Object key) {
if (!containsKey(key)) return null;
- return _fetch(key);
+ return JS('', '#', _fetch(key));
}
// [_fetch] is the indexer for keys for which `containsKey(key)` is true.
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 1b0f1aa..c6ffb11 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -590,10 +590,16 @@
@patch
class NoSuchMethodError {
+ final Object _receiver;
+ final Symbol _memberName;
+ final List _arguments;
+ final Map<Symbol, dynamic> _namedArguments;
+ final List _existingArgumentNames;
+
@patch
- NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) {
- // UNIMPLEMENTED
- }
+ NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
+ : this(receiver, invocation.memberName, invocation.positionalArguments,
+ invocation.namedArguments);
@patch
NoSuchMethodError(Object receiver, Symbol memberName,
diff --git a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
index 4c6b4ab..a95f0e4 100644
--- a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
@@ -177,19 +177,6 @@
arg19]);
/**
- * Returns the isolate in which this code is running.
- */
-external IsolateContext JS_CURRENT_ISOLATE_CONTEXT();
-
-abstract class IsolateContext {
- int get id;
-
- /// Holds a (native) JavaScript instance of Isolate, see
- /// finishIsolateConstructorFunction in emitter.dart.
- get isolateStatics;
-}
-
-/**
* Converts the Dart closure [function] into a JavaScript closure.
*
* Warning: This is no different from [RAW_DART_FUNCTION_REF] which means care
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
deleted file mode 100644
index 01f890b..0000000
--- a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library _isolate_helper;
-
-import 'dart:async';
-import 'dart:isolate';
-
-import 'dart:_js_embedded_names' show CURRENT_SCRIPT;
-
-import 'dart:_js_helper'
- show convertDartClosureToJS, random64, requiresPreamble;
-
-import 'dart:_foreign_helper' show JS, JS_EMBEDDED_GLOBAL;
-
-import 'dart:_interceptors' show JSExtendableArray;
-
-/// Returns true if we are currently in a worker context.
-bool isWorker() {
- requiresPreamble();
- return JS('', '!self.window && !!self.postMessage');
-}
-
-/// The src url for the script tag that loaded this code.
-String thisScript = computeThisScript();
-
-/// The src url for the script tag that loaded this function.
-///
-/// Used to create JavaScript workers and load deferred libraries.
-String computeThisScript() {
- var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
- if (currentScript != null) {
- return JS('String', 'String(#.src)', currentScript);
- }
- // A worker has no script tag - so get an url from a stack-trace.
- if (isWorker()) return _computeThisScriptFromTrace();
- // An isolate that doesn't support workers, but doesn't have a
- // currentScript either. This is most likely a Chrome extension.
- return null;
-}
-
-String _computeThisScriptFromTrace() {
- var stack = JS('String|Null', 'new Error().stack');
- if (stack == null) {
- // According to Internet Explorer documentation, the stack
- // property is not set until the exception is thrown. The stack
- // property was not provided until IE10.
- stack = JS(
- 'String|Null',
- '(function() {'
- 'try { throw new Error() } catch(e) { return e.stack }'
- '})()');
- if (stack == null) throw new UnsupportedError('No stack trace');
- }
- var pattern, matches;
-
- // This pattern matches V8, Chrome, and Internet Explorer stack
- // traces that look like this:
- // Error
- // at methodName (URI:LINE:COLUMN)
- pattern = JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');
-
- matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
- if (matches != null) return JS('String', '#[1]', matches);
-
- // This pattern matches Firefox stack traces that look like this:
- // methodName@URI:LINE
- pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")');
-
- matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
- if (matches != null) return JS('String', '#[1]', matches);
-
- throw new UnsupportedError('Cannot extract URI from "$stack"');
-}
-
-class ReceivePortImpl extends Stream implements ReceivePort {
- ReceivePortImpl();
-
- StreamSubscription listen(void onData(var event),
- {Function onError, void onDone(), bool cancelOnError}) {
- throw new UnsupportedError("ReceivePort.listen");
- }
-
- void close() {}
-
- SendPort get sendPort => throw new UnsupportedError("ReceivePort.sendPort");
-}
-
-class TimerImpl implements Timer {
- final bool _once;
- int _handle;
- int _tick = 0;
-
- TimerImpl(int milliseconds, void callback()) : _once = true {
- if (_hasTimer()) {
- void internalCallback() {
- _handle = null;
- this._tick = 1;
- callback();
- }
-
- _handle = JS('int', 'self.setTimeout(#, #)',
- convertDartClosureToJS(internalCallback, 0), milliseconds);
- } else {
- throw new UnsupportedError('`setTimeout()` not found.');
- }
- }
-
- TimerImpl.periodic(int milliseconds, void callback(Timer timer))
- : _once = false {
- if (_hasTimer()) {
- int start = JS('int', 'Date.now()');
- _handle = JS(
- 'int',
- 'self.setInterval(#, #)',
- convertDartClosureToJS(() {
- int tick = this._tick + 1;
- if (milliseconds > 0) {
- int duration = JS('int', 'Date.now()') - start;
- if (duration > (tick + 1) * milliseconds) {
- tick = duration ~/ milliseconds;
- }
- }
- this._tick = tick;
- callback(this);
- }, 0),
- milliseconds);
- } else {
- throw new UnsupportedError('Periodic timer.');
- }
- }
-
- @override
- bool get isActive => _handle != null;
-
- @override
- int get tick => _tick;
-
- @override
- void cancel() {
- if (_hasTimer()) {
- if (_handle == null) return;
- if (_once) {
- JS('void', 'self.clearTimeout(#)', _handle);
- } else {
- JS('void', 'self.clearInterval(#)', _handle);
- }
- _handle = null;
- } else {
- throw new UnsupportedError('Canceling a timer.');
- }
- }
-}
-
-bool _hasTimer() {
- requiresPreamble();
- return JS('', 'self.setTimeout') != null;
-}
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
index cdb840b..37e6090 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -7,7 +7,6 @@
import "dart:async";
import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper' show patch;
-import 'dart:_isolate_helper' show ReceivePortImpl;
@patch
class Isolate {
@@ -107,7 +106,7 @@
@patch
class ReceivePort {
@patch
- factory ReceivePort() = ReceivePortImpl;
+ factory ReceivePort() = _ReceivePortImpl;
@patch
factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
@@ -115,6 +114,17 @@
}
}
+class _ReceivePortImpl extends Stream implements ReceivePort {
+ StreamSubscription listen(void onData(var event),
+ {Function onError, void onDone(), bool cancelOnError}) {
+ throw new UnsupportedError("ReceivePort.listen");
+ }
+
+ void close() {}
+
+ SendPort get sendPort => throw new UnsupportedError("ReceivePort.sendPort");
+}
+
@patch
class RawReceivePort {
@patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 2af7e18..af67c0e 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -25,8 +25,6 @@
import 'dart:collection';
-import 'dart:_isolate_helper' show thisScript, isWorker;
-
import 'dart:async' show Completer, DeferredLoadException, Future;
import 'dart:_foreign_helper'
@@ -710,26 +708,6 @@
}
class Primitives {
- /// Isolate-unique ID for caching [JsClosureMirror.function].
- /// Note the initial value is used by the first isolate (or if there are no
- /// isolates), new isolates will update this value to avoid conflicts by
- /// calling [initializeStatics].
- static String mirrorFunctionCacheName = '\$cachedFunction';
-
- /// Isolate-unique ID for caching [JsInstanceMirror._invoke].
- static String mirrorInvokeCacheName = '\$cachedInvocation';
-
- /// Called when creating a new isolate (see _IsolateContext constructor in
- /// isolate_helper.dart).
- /// Please don't add complicated code to this method, as it will impact
- /// start-up performance.
- static void initializeStatics(int id) {
- // Benchmarking shows significant performance improvements if this is a
- // fixed value.
- mirrorFunctionCacheName += '_$id';
- mirrorInvokeCacheName += '_$id';
- }
-
static int objectHashCode(object) {
int hash = JS('int|Null', r'#.$identityHash', object);
if (hash == null) {
@@ -3513,11 +3491,6 @@
throw new CastErrorImplementation(value, self);
}
-checkMalformedType(value, message) {
- if (value == null) return value;
- throw new TypeErrorImplementation.fromMessage(message);
-}
-
futureOrTest(o, futureOrRti) => checkSubtypeOfRuntimeType(o, futureOrRti);
futureOrCheck(o, futureOrRti) => assertSubtypeOfRuntimeType(o, futureOrRti);
@@ -3798,6 +3771,64 @@
return JS('String', 'String(#.nonce)', currentScript);
}
+/// Returns true if we are currently in a worker context.
+bool _isWorker() {
+ requiresPreamble();
+ return JS('', '!self.window && !!self.postMessage');
+}
+
+/// The src url for the script tag that loaded this code.
+String thisScript = _computeThisScript();
+
+/// The src url for the script tag that loaded this function.
+///
+/// Used to create JavaScript workers and load deferred libraries.
+String _computeThisScript() {
+ var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
+ if (currentScript != null) {
+ return JS('String', 'String(#.src)', currentScript);
+ }
+ // A worker has no script tag - so get an url from a stack-trace.
+ if (_isWorker()) return _computeThisScriptFromTrace();
+ // An isolate that doesn't support workers, but doesn't have a
+ // currentScript either. This is most likely a Chrome extension.
+ return null;
+}
+
+String _computeThisScriptFromTrace() {
+ var stack = JS('String|Null', 'new Error().stack');
+ if (stack == null) {
+ // According to Internet Explorer documentation, the stack
+ // property is not set until the exception is thrown. The stack
+ // property was not provided until IE10.
+ stack = JS(
+ 'String|Null',
+ '(function() {'
+ 'try { throw new Error() } catch(e) { return e.stack }'
+ '})()');
+ if (stack == null) throw new UnsupportedError('No stack trace');
+ }
+ var pattern, matches;
+
+ // This pattern matches V8, Chrome, and Internet Explorer stack
+ // traces that look like this:
+ // Error
+ // at methodName (URI:LINE:COLUMN)
+ pattern = JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');
+
+ matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
+ if (matches != null) return JS('String', '#[1]', matches);
+
+ // This pattern matches Firefox stack traces that look like this:
+ // methodName@URI:LINE
+ pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")');
+
+ matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
+ if (matches != null) return JS('String', '#[1]', matches);
+
+ throw new UnsupportedError('Cannot extract URI from "$stack"');
+}
+
Future<Null> _loadHunk(String hunkName) {
Future<Null> future = _loadingLibraries[hunkName];
_eventLog.add(' - _loadHunk: $hunkName');
@@ -3843,7 +3874,7 @@
} catch (error, stackTrace) {
failure(error, "invoking dartDeferredLibraryLoader hook", stackTrace);
}
- } else if (isWorker()) {
+ } else if (_isWorker()) {
// We are in a web worker. Load the code with an XMLHttpRequest.
int index = uri.lastIndexOf('/');
uri = '${uri.substring(0, index + 1)}$hunkName';
diff --git a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
deleted file mode 100644
index 7aebc9e..0000000
--- a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
+++ /dev/null
@@ -1,3096 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart._js_mirrors;
-
-import 'dart:_js_embedded_names'
- show
- JsGetName,
- ALL_CLASSES,
- LAZIES,
- LIBRARIES,
- STATICS,
- TYPE_INFORMATION,
- TYPEDEF_PREDICATE_PROPERTY_NAME,
- TYPEDEF_TYPE_PROPERTY_NAME;
-
-import 'dart:collection' show UnmodifiableListView, UnmodifiableMapView;
-
-import 'dart:mirrors';
-
-import 'dart:_foreign_helper'
- show
- JS,
- JS_GET_FLAG,
- JS_GET_STATIC_STATE,
- JS_CURRENT_ISOLATE_CONTEXT,
- JS_EMBEDDED_GLOBAL,
- JS_GET_NAME;
-
-import 'dart:_internal' as _symbol_dev;
-
-import 'dart:_js_helper'
- show
- BoundClosure,
- CachedInvocation,
- Closure,
- JSInvocationMirror,
- JsCache,
- Primitives,
- ReflectionInfo,
- RuntimeError,
- TearOffClosure,
- TypeVariable,
- UnimplementedNoSuchMethodError,
- createRuntimeType,
- createUnmangledInvocationMirror,
- extractFunctionTypeObjectFrom,
- getMangledTypeName,
- getMetadata,
- getType,
- getRuntimeType,
- isDartFunctionType,
- runtimeTypeToString,
- setRuntimeTypeInfo,
- throwInvalidReflectionError,
- TypeImpl,
- deferredLoadHook;
-
-import 'dart:_interceptors'
- show Interceptor, JSArray, JSExtendableArray, getInterceptor;
-
-import 'dart:_js_names';
-
-const String METHODS_WITH_OPTIONAL_ARGUMENTS = r'$methodsWithOptionalArguments';
-
-bool hasReflectableProperty(var jsFunction) {
- return JS('bool', '# in #', JS_GET_NAME(JsGetName.REFLECTABLE), jsFunction);
-}
-
-/// No-op method that is called to inform the compiler that tree-shaking needs
-/// to be disabled.
-disableTreeShaking() => preserveNames();
-
-/// No-op method that is called to inform the compiler that metadata must be
-/// preserved at runtime.
-preserveMetadata() {}
-
-/// No-op method that is called to inform the compiler that the compiler must
-/// preserve the URIs.
-preserveUris() {}
-
-/// No-op method that is called to inform the compiler that the compiler must
-/// preserve the library names.
-preserveLibraryNames() {}
-
-String getName(Symbol symbol) {
- preserveNames();
- return n(symbol);
-}
-
-class JsMirrorSystem implements MirrorSystem {
- UnmodifiableMapView<Uri, LibraryMirror> _cachedLibraries;
-
- final IsolateMirror isolate = new JsIsolateMirror();
-
- JsTypeMirror get dynamicType => _dynamicType;
- JsTypeMirror get voidType => _voidType;
-
- static final JsTypeMirror _dynamicType =
- new JsTypeMirror(const Symbol('dynamic'));
- static final JsTypeMirror _voidType = new JsTypeMirror(const Symbol('void'));
-
- static Map<String, List<LibraryMirror>> _librariesByName;
-
- // Will be set to `true` when we have installed a hook on [deferredLoadHook]
- // to avoid installing it multiple times.
- static bool _hasInstalledDeferredLoadHook = false;
-
- static Map<String, List<LibraryMirror>> get librariesByName {
- if (_librariesByName == null) {
- _librariesByName = computeLibrariesByName();
- if (!_hasInstalledDeferredLoadHook) {
- _hasInstalledDeferredLoadHook = true;
- // After a deferred import has been loaded new libraries might have
- // been created, so in the hook we erase _librariesByName, so it will be
- // recomputed on the next access.
- deferredLoadHook = () => _librariesByName = null;
- }
- }
- return _librariesByName;
- }
-
- Map<Uri, LibraryMirror> get libraries {
- if (_cachedLibraries != null) return _cachedLibraries;
- Map<Uri, LibraryMirror> result = new Map();
- for (List<LibraryMirror> list in librariesByName.values) {
- for (LibraryMirror library in list) {
- result[library.uri] = library;
- }
- }
- return _cachedLibraries =
- new UnmodifiableMapView<Uri, LibraryMirror>(result);
- }
-
- LibraryMirror findLibrary(Symbol libraryName) {
- return librariesByName[n(libraryName)].single;
- }
-
- static Map<String, List<LibraryMirror>> computeLibrariesByName() {
- disableTreeShaking();
- var result = new Map<String, List<LibraryMirror>>();
- var jsLibraries = JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
- if (jsLibraries == null) return result;
- for (List data in jsLibraries) {
- String name = data[0];
- String uriString = data[1];
- Uri uri;
- // The Uri has been compiled out. Create a URI from the simple name.
- if (uriString != '') {
- uri = Uri.parse(uriString);
- } else {
- uri = new Uri(
- scheme: 'https',
- host: 'dartlang.org',
- path: 'dart2js-stripped-uri',
- queryParameters: {'lib': name});
- }
- List<String> classes = data[2];
- List<String> functions = data[3];
- var metadataFunction = data[4];
- var fields = data[5];
- bool isRoot = data[6];
- var globalObject = data[7];
- List metadata = (metadataFunction == null)
- ? const []
- : JS('List', '#()', metadataFunction);
- var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]);
- libraries.add(new JsLibraryMirror(s(name), uri, classes, functions,
- metadata, fields, isRoot, globalObject));
- }
- return result;
- }
-}
-
-abstract class JsMirror implements Mirror {
- const JsMirror();
-
- String get _prettyName;
-
- String toString() => _prettyName;
-
- // TODO(ahe): Remove this method from the API.
- MirrorSystem get mirrors => currentJsMirrorSystem;
-
- _getField(JsMirror receiver) {
- throw new UnimplementedError();
- }
-
- void _setField(JsMirror receiver, Object arg) {
- throw new UnimplementedError();
- }
-
- _loadField(String name) {
- throw new UnimplementedError();
- }
-
- void _storeField(String name, Object arg) {
- throw new UnimplementedError();
- }
-}
-
-// This class is somewhat silly in the current implementation.
-class JsIsolateMirror extends JsMirror implements IsolateMirror {
- final _isolateContext = JS_CURRENT_ISOLATE_CONTEXT();
-
- String get _prettyName => 'Isolate';
-
- String get debugName {
- String id = _isolateContext == null ? 'X' : _isolateContext.id.toString();
- // Using name similar to what the VM uses.
- return '${n(rootLibrary.simpleName)}-$id';
- }
-
- bool get isCurrent => JS_CURRENT_ISOLATE_CONTEXT() == _isolateContext;
-
- LibraryMirror get rootLibrary {
- return currentJsMirrorSystem.libraries.values.firstWhere((LibraryMirror l) {
- JsLibraryMirror library = l;
- return library._isRoot;
- });
- }
-}
-
-abstract class JsDeclarationMirror extends JsMirror
- implements DeclarationMirror {
- final Symbol simpleName;
-
- const JsDeclarationMirror(this.simpleName);
-
- Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
-
- bool get isPrivate => n(simpleName).startsWith('_');
-
- bool get isTopLevel => owner != null && owner is LibraryMirror;
-
- // TODO(ahe): This should use qualifiedName.
- String toString() => "$_prettyName on '${n(simpleName)}'";
-
- List<JsMethodMirror> get _methods {
- throw new RuntimeError('Should not call _methods');
- }
-
- _invoke(List positionalArguments, Map<Symbol, dynamic> namedArguments) {
- throw new RuntimeError('Should not call _invoke');
- }
-
- // TODO(ahe): Implement this.
- SourceLocation get location => throw new UnimplementedError();
-}
-
-class JsTypeVariableMirror extends JsTypeMirror implements TypeVariableMirror {
- final DeclarationMirror owner;
- final TypeVariable _typeVariable;
- final int _metadataIndex;
- TypeMirror _cachedUpperBound;
-
- JsTypeVariableMirror(
- TypeVariable typeVariable, this.owner, this._metadataIndex)
- : this._typeVariable = typeVariable,
- super(s(typeVariable.name));
-
- bool operator ==(other) {
- return (other is JsTypeVariableMirror &&
- simpleName == other.simpleName &&
- owner == other.owner);
- }
-
- int get hashCode {
- int code = 0x3FFFFFFF & (JsTypeVariableMirror).hashCode;
- code ^= 17 * simpleName.hashCode;
- code ^= 19 * owner.hashCode;
- return code;
- }
-
- String get _prettyName => 'TypeVariableMirror';
-
- bool get isTopLevel => false;
- bool get isStatic => false;
-
- TypeMirror get upperBound {
- if (_cachedUpperBound != null) return _cachedUpperBound;
- return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation(
- owner, getType(_typeVariable.bound));
- }
-
- bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
- bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-
- _asRuntimeType() => _metadataIndex;
-}
-
-class JsTypeMirror extends JsDeclarationMirror implements TypeMirror {
- JsTypeMirror(Symbol simpleName) : super(simpleName);
-
- String get _prettyName => 'TypeMirror';
-
- DeclarationMirror get owner => null;
-
- // TODO(ahe): Doesn't match the specification, see http://dartbug.com/11569.
- bool get isTopLevel => true;
-
- // TODO(ahe): Implement these.
- List<InstanceMirror> get metadata => throw new UnimplementedError();
-
- bool get hasReflectedType => false;
- Type get reflectedType {
- throw new UnsupportedError('This type does not support reflectedType');
- }
-
- List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[];
- List<TypeMirror> get typeArguments => const <TypeMirror>[];
-
- bool get isOriginalDeclaration => true;
- TypeMirror get originalDeclaration => this;
-
- bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
- bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-
- _asRuntimeType() {
- if (this == JsMirrorSystem._dynamicType) return null;
- if (this == JsMirrorSystem._voidType) return null;
- throw new RuntimeError('Should not call _asRuntimeType');
- }
-}
-
-class JsLibraryMirror extends JsDeclarationMirror
- with JsObjectMirror
- implements LibraryMirror {
- final Uri _uri;
- final List<String> _classes;
- final List<String> _functions;
- final List _metadata;
- final String _compactFieldSpecification;
- final bool _isRoot;
- final _globalObject;
- List<JsMethodMirror> _cachedFunctionMirrors;
- List<VariableMirror> _cachedFields;
- UnmodifiableMapView<Symbol, ClassMirror> _cachedClasses;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedFunctions;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
- UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
- UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
- UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
- UnmodifiableListView<InstanceMirror> _cachedMetadata;
-
- JsLibraryMirror(
- Symbol simpleName,
- this._uri,
- this._classes,
- this._functions,
- this._metadata,
- this._compactFieldSpecification,
- this._isRoot,
- this._globalObject)
- : super(simpleName) {
- preserveLibraryNames();
- }
-
- String get _prettyName => 'LibraryMirror';
-
- Uri get uri {
- preserveUris();
- return _uri;
- }
-
- Symbol get qualifiedName => simpleName;
-
- List<JsMethodMirror> get _methods => _functionMirrors;
-
- Map<Symbol, ClassMirror> get __classes {
- if (_cachedClasses != null) return _cachedClasses;
- var result = new Map();
- for (String className in _classes) {
- var cls = reflectClassByMangledName(className);
- if (cls is ClassMirror) {
- cls = cls.originalDeclaration;
- }
- if (cls is JsClassMirror) {
- result[cls.simpleName] = cls;
- cls._owner = this;
- } else if (cls is JsTypedefMirror) {
- result[cls.simpleName] = cls;
- }
- }
- return _cachedClasses =
- new UnmodifiableMapView<Symbol, ClassMirror>(result);
- }
-
- InstanceMirror setField(Symbol fieldName, Object arg) {
- String name = n(fieldName);
- if (name.endsWith('=')) throw new ArgumentError('');
- dynamic mirror = __functions[s('$name=')];
- if (mirror == null) mirror = __variables[fieldName];
- if (mirror == null) {
- throw new NoSuchStaticMethodError.method(
- null, setterSymbol(fieldName), [arg], null);
- }
- mirror._setField(this, arg);
- return reflect(arg);
- }
-
- InstanceMirror getField(Symbol fieldName) {
- JsMirror mirror = __members[fieldName];
- if (mirror == null) {
- throw new NoSuchStaticMethodError.method(null, fieldName, [], null);
- }
- if (mirror is! MethodMirror) return reflect(mirror._getField(this));
- JsMethodMirror methodMirror = mirror;
- if (methodMirror.isGetter) return reflect(mirror._getField(this));
- assert(methodMirror.isRegularMethod);
- var getter = JS('', "#['\$getter']", methodMirror._jsFunction);
- if (getter == null) throw new UnimplementedError();
- return reflect(JS('', '#()', getter));
- }
-
- InstanceMirror invoke(Symbol memberName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null && !namedArguments.isEmpty) {
- throw new UnsupportedError('Named arguments are not implemented.');
- }
- JsDeclarationMirror mirror = __members[memberName];
-
- if (mirror is JsMethodMirror && !mirror.canInvokeReflectively()) {
- throwInvalidReflectionError(n(memberName));
- }
- if (mirror == null || mirror is JsMethodMirror && mirror.isSetter) {
- throw new NoSuchStaticMethodError.method(
- null, memberName, positionalArguments, namedArguments);
- }
- if (mirror is JsMethodMirror && !mirror.isGetter) {
- return reflect(mirror._invoke(positionalArguments, namedArguments));
- }
- return getField(memberName)
- .invoke(#call, positionalArguments, namedArguments);
- }
-
- delegate(Invocation invocation) {
- throw new UnimplementedError();
- }
-
- _loadField(String name) {
- // TODO(ahe): What about lazily initialized fields? See
- // [JsClassMirror.getField].
-
- // '$' (JS_GET_STATIC_STATE()) stores state which is read directly, so we
- // shouldn't use [_globalObject] here.
- assert(JS('bool', '# in #', name, JS_GET_STATIC_STATE()));
- return JS('', '#[#]', JS_GET_STATIC_STATE(), name);
- }
-
- void _storeField(String name, Object arg) {
- // '$' (JS_GET_STATIC_STATE()) stores state which is stored directly, so we
- // shouldn't use [_globalObject] here.
- assert(JS('bool', '# in #', name, JS_GET_STATIC_STATE()));
- JS('void', '#[#] = #', JS_GET_STATIC_STATE(), name, arg);
- }
-
- List<JsMethodMirror> get _functionMirrors {
- if (_cachedFunctionMirrors != null) return _cachedFunctionMirrors;
- var result = new List<JsMethodMirror>();
- for (int i = 0; i < _functions.length; i++) {
- String name = _functions[i];
- var jsFunction = JS('', '#[#]', _globalObject, name);
- String unmangledName = mangledGlobalNames[name];
- if (unmangledName == null ||
- JS('bool', "!!#['\$getterStub']", jsFunction)) {
- // If there is no unmangledName, [jsFunction] is either a synthetic
- // implementation detail, or something that is excluded
- // by @MirrorsUsed.
- // If it has a getterStub property it is a synthetic stub.
- // TODO(floitsch): Remove the getterStub hack.
- continue;
- }
- bool isConstructor = unmangledName.startsWith('new ');
- // Top-level functions are static, but constructors are not.
- bool isStatic = !isConstructor;
- if (isConstructor) {
- unmangledName = unmangledName.substring(4).replaceAll(r'$', '.');
- }
- JsMethodMirror mirror = new JsMethodMirror.fromUnmangledName(
- unmangledName, jsFunction, isStatic, isConstructor);
- result.add(mirror);
- mirror._owner = this;
- }
- return _cachedFunctionMirrors = result;
- }
-
- List<VariableMirror> get _fields {
- if (_cachedFields != null) return _cachedFields;
- var result = <VariableMirror>[];
- parseCompactFieldSpecification(
- this, _compactFieldSpecification, true, result);
- return _cachedFields = result;
- }
-
- Map<Symbol, MethodMirror> get __functions {
- if (_cachedFunctions != null) return _cachedFunctions;
- var result = new Map();
- for (JsMethodMirror mirror in _functionMirrors) {
- if (!mirror.isConstructor) result[mirror.simpleName] = mirror;
- }
- return _cachedFunctions =
- new UnmodifiableMapView<Symbol, MethodMirror>(result);
- }
-
- Map<Symbol, MethodMirror> get __getters {
- if (_cachedGetters != null) return _cachedGetters;
- var result = new Map();
- // TODO(ahe): Implement this.
- return _cachedGetters =
- new UnmodifiableMapView<Symbol, MethodMirror>(result);
- }
-
- Map<Symbol, MethodMirror> get __setters {
- if (_cachedSetters != null) return _cachedSetters;
- var result = new Map();
- // TODO(ahe): Implement this.
- return _cachedSetters =
- new UnmodifiableMapView<Symbol, MethodMirror>(result);
- }
-
- Map<Symbol, VariableMirror> get __variables {
- if (_cachedVariables != null) return _cachedVariables;
- var result = new Map();
- for (JsVariableMirror mirror in _fields) {
- result[mirror.simpleName] = mirror;
- }
- return _cachedVariables =
- new UnmodifiableMapView<Symbol, VariableMirror>(result);
- }
-
- Map<Symbol, Mirror> get __members {
- if (_cachedMembers != null) return _cachedMembers;
- Map<Symbol, Mirror> result = new Map.from(__classes);
- addToResult(Symbol key, Mirror value) {
- result[key] = value;
- }
-
- __functions.forEach(addToResult);
- __getters.forEach(addToResult);
- __setters.forEach(addToResult);
- __variables.forEach(addToResult);
- return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result);
- }
-
- Map<Symbol, DeclarationMirror> get declarations {
- if (_cachedDeclarations != null) return _cachedDeclarations;
- var result = new Map<Symbol, DeclarationMirror>();
- addToResult(Symbol key, Mirror value) {
- result[key] = value;
- }
-
- __members.forEach(addToResult);
- return _cachedDeclarations =
- new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
- }
-
- List<InstanceMirror> get metadata {
- if (_cachedMetadata != null) return _cachedMetadata;
- preserveMetadata();
- return _cachedMetadata =
- new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
- }
-
- // TODO(ahe): Test this getter.
- DeclarationMirror get owner => null;
-
- List<LibraryDependencyMirror> get libraryDependencies =>
- throw new UnimplementedError();
-}
-
-String n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
-
-Symbol s(String name) {
- if (name == null) return null;
- return new _symbol_dev.Symbol.unvalidated(name);
-}
-
-Symbol setterSymbol(Symbol symbol) => s('${n(symbol)}=');
-
-final JsMirrorSystem currentJsMirrorSystem = new JsMirrorSystem();
-
-InstanceMirror reflect(Object reflectee) {
- // TODO(sra): This test should be a quick test for something like 'is
- // Function', but only for classes that implement `Function` via a `call`
- // method. The JS form of the test could be something like
- //
- // if (reflectee instanceof P.Object && reflectee.$isFunction) ...
- //
- // We don't currently have a way get that generated. We should ensure type
- // analysis can express 'not Interceptor' and recognize a negative type test
- // against Interceptor can be optimized to the above test. For now we have to
- // accept the following is compiled to an interceptor-based type check.
- if (reflectee is Function) {
- return new JsClosureMirror(reflectee);
- } else {
- return new JsInstanceMirror(reflectee);
- }
-}
-
-TypeMirror reflectType(Type key, [List<Type> typeArguments]) {
- String mangledName = getMangledTypeName(key);
- if (typeArguments != null) {
- if (typeArguments.isEmpty || !typeArguments.every((_) => _ is TypeImpl)) {
- var message = typeArguments.isEmpty
- ? 'Type arguments list can not be empty.'
- : 'Type arguments list must contain only instances of Type.';
- throw new ArgumentError.value(typeArguments, 'typeArguments', message);
- }
- var mangledTypeArguments = typeArguments.map(getMangledTypeName);
- mangledName = "${mangledName}<${mangledTypeArguments.join(', ')}>";
- }
- return reflectClassByMangledName(mangledName);
-}
-
-TypeMirror reflectClassByMangledName(String mangledName) {
- String unmangledName = mangledGlobalNames[mangledName];
- if (mangledName == 'dynamic') return JsMirrorSystem._dynamicType;
- if (mangledName == 'void') return JsMirrorSystem._voidType;
- if (unmangledName == null) unmangledName = mangledName;
- return reflectClassByName(s(unmangledName), mangledName);
-}
-
-var classMirrors;
-
-TypeMirror reflectClassByName(Symbol symbol, String mangledName) {
- if (classMirrors == null) classMirrors = JsCache.allocate();
- var mirror = JsCache.fetch(classMirrors, mangledName);
- if (mirror != null) return mirror;
- disableTreeShaking();
- int typeArgIndex = mangledName.indexOf('<');
- if (typeArgIndex != -1) {
- TypeMirror originalDeclaration =
- reflectClassByMangledName(mangledName.substring(0, typeArgIndex))
- .originalDeclaration;
- if (originalDeclaration is JsTypedefMirror) {
- throw new UnimplementedError();
- }
- mirror = new JsTypeBoundClassMirror(
- originalDeclaration,
- // Remove the angle brackets enclosing the type arguments.
- mangledName.substring(typeArgIndex + 1, mangledName.length - 1));
- JsCache.update(classMirrors, mangledName, mirror);
- return mirror;
- }
- var allClasses = JS_EMBEDDED_GLOBAL('', ALL_CLASSES);
- var constructor = JS('var', '#[#]', allClasses, mangledName);
- if (constructor == null) {
- // Probably an intercepted class.
- // TODO(ahe): How to handle intercepted classes?
- throw new UnsupportedError('Cannot find class for: ${n(symbol)}');
- }
- var descriptor = JS('', '#["@"]', constructor);
- var fields;
- var fieldsMetadata;
- if (descriptor == null) {
- // This is a native class, or an intercepted class.
- // TODO(ahe): Preserve descriptor for such classes.
- } else if (JS(
- 'bool', '# in #', TYPEDEF_PREDICATE_PROPERTY_NAME, descriptor)) {
- // Typedefs are represented as normal classes with two special properties:
- // TYPEDEF_PREDICATE_PROPERTY_NAME and TYPEDEF_TYPE_PROPERTY_NAME.
- // For example:
- // MyTypedef: {
- // "^": "Object;",
- // $typedefType: 58,
- // $$isTypedef: true
- // }
- // The typedefType is the index into the metadata table.
- int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME);
- mirror = new JsTypedefMirror(symbol, mangledName, getType(index));
- } else {
- fields = JS('', '#[#]', descriptor,
- JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY));
- if (fields is List) {
- fieldsMetadata = fields.getRange(1, fields.length).toList();
- fields = fields[0];
- }
- if (fields is! String) {
- // TODO(ahe): This is CSP mode. Find a way to determine the
- // fields of this class.
- fields = '';
- }
- }
-
- if (mirror == null) {
- var superclassName = fields.split(';')[0];
- var mixins = superclassName.split('+');
- if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) {
- mirror = reflectMixinApplication(mixins, mangledName);
- } else {
- ClassMirror classMirror = new JsClassMirror(
- symbol, mangledName, constructor, fields, fieldsMetadata);
- List typeVariables =
- JS('JSExtendableArray|Null', '#.prototype["<>"]', constructor);
- if (typeVariables == null || typeVariables.length == 0) {
- mirror = classMirror;
- } else {
- String typeArguments = 'dynamic';
- for (int i = 1; i < typeVariables.length; i++) {
- typeArguments += ',dynamic';
- }
- mirror = new JsTypeBoundClassMirror(classMirror, typeArguments);
- }
- }
- }
-
- JsCache.update(classMirrors, mangledName, mirror);
- return mirror;
-}
-
-/// Splits input `typeArguments` string into a list of strings for each argument.
-/// Takes into account nested generic types.
-/// For example, `Map<int, String>, String` will become a list of two items:
-/// `Map<int, String>` and `String`.
-List<String> splitTypeArguments(String typeArguments) {
- if (typeArguments.indexOf('<') == -1) {
- return typeArguments.split(',');
- }
- var argumentList = new List<String>();
- int level = 0;
- String currentTypeArgument = '';
-
- for (int i = 0; i < typeArguments.length; i++) {
- var character = typeArguments[i];
- if (character == ' ') {
- continue;
- } else if (character == '<') {
- currentTypeArgument += character;
- level++;
- } else if (character == '>') {
- currentTypeArgument += character;
- level--;
- } else if (character == ',') {
- if (level > 0) {
- currentTypeArgument += character;
- } else {
- argumentList.add(currentTypeArgument);
- currentTypeArgument = '';
- }
- } else {
- currentTypeArgument += character;
- }
- }
- argumentList.add(currentTypeArgument);
- return argumentList;
-}
-
-Map<Symbol, MethodMirror> filterMethods(List<MethodMirror> methods) {
- var result = new Map();
- for (JsMethodMirror method in methods) {
- if (!method.isConstructor && !method.isGetter && !method.isSetter) {
- result[method.simpleName] = method;
- }
- }
- return result;
-}
-
-Map<Symbol, MethodMirror> filterConstructors(methods) {
- var result = new Map();
- for (JsMethodMirror method in methods) {
- if (method.isConstructor) {
- result[method.simpleName] = method;
- }
- }
- return result;
-}
-
-Map<Symbol, MethodMirror> filterGetters(
- List<MethodMirror> methods, Map<Symbol, VariableMirror> fields) {
- var result = new Map();
- for (JsMethodMirror method in methods) {
- if (method.isGetter) {
- // TODO(ahe): This is a hack to remove getters corresponding to a field.
- if (fields[method.simpleName] != null) continue;
-
- result[method.simpleName] = method;
- }
- }
- return result;
-}
-
-Map<Symbol, MethodMirror> filterSetters(
- List<MethodMirror> methods, Map<Symbol, VariableMirror> fields) {
- var result = new Map();
- for (JsMethodMirror method in methods) {
- if (method.isSetter) {
- // TODO(ahe): This is a hack to remove setters corresponding to a field.
- String name = n(method.simpleName);
- name = name.substring(0, name.length - 1); // Remove '='.
- if (fields[s(name)] != null) continue;
-
- result[method.simpleName] = method;
- }
- }
- return result;
-}
-
-Map<Symbol, Mirror> filterMembers(
- List<MethodMirror> methods, Map<Symbol, VariableMirror> variables) {
- Map<Symbol, Mirror> result = new Map.from(variables);
- for (JsMethodMirror method in methods) {
- if (method.isSetter) {
- String name = n(method.simpleName);
- name = name.substring(0, name.length - 1);
- // Filter-out setters corresponding to variables.
- if (result[s(name)] is VariableMirror) continue;
- }
- // Constructors aren't 'members'.
- if (method.isConstructor) continue;
- // Filter out synthetic tear-off stubs
- if (JS('bool', r'!!#.$getterStub', method._jsFunction)) continue;
- // Use putIfAbsent to filter-out getters corresponding to variables.
- result.putIfAbsent(method.simpleName, () => method);
- }
- return result;
-}
-
-int counter = 0;
-
-ClassMirror reflectMixinApplication(mixinNames, String mangledName) {
- disableTreeShaking();
- var mixins = [];
- for (String mangledName in mixinNames) {
- mixins.add(reflectClassByMangledName(mangledName));
- }
- var it = mixins.iterator;
- it.moveNext();
- var superclass = it.current;
- while (it.moveNext()) {
- superclass = new JsMixinApplication(superclass, it.current, mangledName);
- }
- return superclass;
-}
-
-class JsMixinApplication extends JsTypeMirror
- with JsObjectMirror
- implements ClassMirror {
- final ClassMirror superclass;
- final ClassMirror mixin;
- Symbol _cachedSimpleName;
- Map<Symbol, MethodMirror> _cachedInstanceMembers;
-
- JsMixinApplication(
- ClassMirror superclass, ClassMirror mixin, String mangledName)
- : this.superclass = superclass,
- this.mixin = mixin,
- super(s(mangledName));
-
- String get _prettyName => 'ClassMirror';
-
- Symbol get simpleName {
- if (_cachedSimpleName != null) return _cachedSimpleName;
- String superName = n(superclass.qualifiedName);
- return _cachedSimpleName = (superName.contains(' with '))
- ? s('$superName, ${n(mixin.qualifiedName)}')
- : s('$superName with ${n(mixin.qualifiedName)}');
- }
-
- Symbol get qualifiedName => simpleName;
-
- // TODO(ahe): Remove this method, only here to silence warning.
- get _mixin => mixin;
-
- Map<Symbol, Mirror> get __members => _mixin.__members;
-
- Map<Symbol, MethodMirror> get __methods => _mixin.__methods;
-
- Map<Symbol, MethodMirror> get __getters => _mixin.__getters;
-
- Map<Symbol, MethodMirror> get __setters => _mixin.__setters;
-
- Map<Symbol, VariableMirror> get __variables => _mixin.__variables;
-
- Map<Symbol, DeclarationMirror> get declarations => mixin.declarations;
-
- Map<Symbol, MethodMirror> get instanceMembers {
- if (_cachedInstanceMembers == null) {
- var result = new Map<Symbol, MethodMirror>();
- if (superclass != null) {
- result.addAll(superclass.instanceMembers);
- }
- result.addAll(mixin.instanceMembers);
- _cachedInstanceMembers = result;
- }
- return _cachedInstanceMembers;
- }
-
- Map<Symbol, MethodMirror> get staticMembers => mixin.staticMembers;
-
- _asRuntimeType() => null;
-
- InstanceMirror invoke(Symbol memberName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- throw new NoSuchStaticMethodError.method(
- null, memberName, positionalArguments, namedArguments);
- }
-
- InstanceMirror getField(Symbol fieldName) {
- throw new NoSuchStaticMethodError.method(null, fieldName, null, null);
- }
-
- InstanceMirror setField(Symbol fieldName, Object arg) {
- throw new NoSuchStaticMethodError.method(
- null, setterSymbol(fieldName), [arg], null);
- }
-
- delegate(Invocation invocation) {
- throw new UnimplementedError();
- }
-
- List<ClassMirror> get superinterfaces => [mixin];
-
- Map<Symbol, MethodMirror> get __constructors => _mixin.__constructors;
-
- InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- throw new UnsupportedError(
- "Can't instantiate mixin application '${n(qualifiedName)}'");
- }
-
- bool get isOriginalDeclaration => true;
-
- ClassMirror get originalDeclaration => this;
-
- // TODO(ahe): Implement this.
- List<TypeVariableMirror> get typeVariables {
- throw new UnimplementedError();
- }
-
- List<TypeMirror> get typeArguments => const <TypeMirror>[];
-
- bool get isAbstract => throw new UnimplementedError();
-
- bool get isEnum => throw new UnimplementedError();
-
- bool isSubclassOf(ClassMirror other) {
- superclass.isSubclassOf(other) || mixin.isSubclassOf(other);
- }
-
- bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-
- bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-}
-
-abstract class JsObjectMirror implements ObjectMirror {}
-
-class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
- final reflectee;
-
- JsInstanceMirror(this.reflectee);
-
- bool get hasReflectee => true;
-
- ClassMirror get type {
- // The spec guarantees that `null` is the singleton instance of the `Null`
- // class.
- if (reflectee == null) return reflectClass(Null);
- return reflectType(getRuntimeType(reflectee));
- }
-
- InstanceMirror invoke(Symbol memberName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments == null) namedArguments = const {};
- // We can safely pass positionalArguments to _invoke as it will wrap it in
- // a JSArray if needed.
- return _invoke(memberName, JSInvocationMirror.METHOD, positionalArguments,
- namedArguments);
- }
-
- InstanceMirror _invokeMethodWithNamedArguments(String reflectiveName,
- List positionalArguments, Map<Symbol, dynamic> namedArguments) {
- assert(namedArguments.isNotEmpty);
- var interceptor = getInterceptor(reflectee);
-
- var jsFunction = JS('', '#[#]', interceptor, reflectiveName);
- if (jsFunction == null) {
- // TODO(ahe): Invoke noSuchMethod.
- throw new UnimplementedNoSuchMethodError(
- 'Invoking noSuchMethod with named arguments not implemented');
- }
- ReflectionInfo info = new ReflectionInfo(jsFunction);
- if (jsFunction == null) {
- // TODO(ahe): Invoke noSuchMethod.
- throw new UnimplementedNoSuchMethodError(
- 'Invoking noSuchMethod with named arguments not implemented');
- }
-
- positionalArguments = new List.from(positionalArguments);
- // Check the number of positional arguments is valid.
- if (info.requiredParameterCount != positionalArguments.length) {
- // TODO(ahe): Invoke noSuchMethod.
- throw new UnimplementedNoSuchMethodError(
- 'Invoking noSuchMethod with named arguments not implemented');
- }
- var defaultArguments = new Map();
- for (int i = 0; i < info.optionalParameterCount; i++) {
- var parameterName = info.parameterName(i + info.requiredParameterCount);
- var defaultValue =
- getMetadata(info.defaultValue(i + info.requiredParameterCount));
- defaultArguments[parameterName] = defaultValue;
- }
- namedArguments.forEach((Symbol symbol, value) {
- String parameter = n(symbol);
- if (defaultArguments.containsKey(parameter)) {
- defaultArguments[parameter] = value;
- } else {
- // Extraneous named argument.
- // TODO(ahe): Invoke noSuchMethod.
- throw new UnimplementedNoSuchMethodError(
- 'Invoking noSuchMethod with named arguments not implemented');
- }
- });
- positionalArguments.addAll(defaultArguments.values);
- // TODO(ahe): Handle intercepted methods.
- return reflect(
- JS('', '#.apply(#, #)', jsFunction, reflectee, positionalArguments));
- }
-
- /// Grabs hold of the class-specific invocation cache for the reflectee.
- /// All reflectees with the same class share the same cache. The cache
- /// maps reflective names to cached invocation objects with enough decoded
- /// reflective information to know how to to invoke a specific member.
- get _classInvocationCache {
- String cacheName = Primitives.mirrorInvokeCacheName;
- var cacheHolder = (reflectee == null) ? getInterceptor(null) : reflectee;
- var cache = JS('', r'#.constructor[#]', cacheHolder, cacheName);
- if (cache == null) {
- cache = JsCache.allocate();
- JS('void', r'#.constructor[#] = #', cacheHolder, cacheName, cache);
- }
- return cache;
- }
-
- String _computeReflectiveName(Symbol symbolName, int type,
- List positionalArguments, Map<Symbol, dynamic> namedArguments) {
- String name = n(symbolName);
- switch (type) {
- case JSInvocationMirror.GETTER:
- return name;
- case JSInvocationMirror.SETTER:
- return '$name=';
- case JSInvocationMirror.METHOD:
- if (namedArguments.isNotEmpty) return '$name*';
- int nbArgs = positionalArguments.length as int;
- return '$name:$nbArgs';
- }
- throw new RuntimeError('Could not compute reflective name for $name');
- }
-
- /**
- * Returns a `CachedInvocation` or `CachedNoSuchMethodInvocation` for the
- * given member.
- *
- * Caches the result.
- */
- _getCachedInvocation(Symbol name, int type, String reflectiveName,
- List positionalArguments, Map<Symbol, dynamic> namedArguments) {
- var cache = _classInvocationCache;
- var cacheEntry = JsCache.fetch(cache, reflectiveName);
- var result;
- if (cacheEntry == null) {
- disableTreeShaking();
- String mangledName = reflectiveNames[reflectiveName];
- List<String> argumentNames = const [];
-
- // TODO(ahe): We don't need to create an invocation mirror here. The
- // logic from JSInvocationMirror.getCachedInvocation could easily be
- // inlined here.
- Invocation invocation = createUnmangledInvocationMirror(
- name, mangledName, type, positionalArguments, argumentNames);
-
- cacheEntry =
- JSInvocationMirror.getCachedInvocation(invocation, reflectee);
- JsCache.update(cache, reflectiveName, cacheEntry);
- }
- return cacheEntry;
- }
-
- bool _isReflectable(CachedInvocation cachedInvocation) {
- // TODO(floitsch): tear-off closure does not guarantee that the
- // function is reflectable.
- var method = cachedInvocation.jsFunction;
- return hasReflectableProperty(method) || reflectee is TearOffClosure;
- }
-
- /// Invoke the member specified through name and type on the reflectee.
- /// As a side-effect, this populates the class-specific invocation cache
- /// for the reflectee.
- InstanceMirror _invoke(Symbol name, int type, List positionalArguments,
- Map<Symbol, dynamic> namedArguments) {
- String reflectiveName =
- _computeReflectiveName(name, type, positionalArguments, namedArguments);
-
- if (namedArguments.isNotEmpty) {
- // TODO(floitsch): first, make sure it's not a getter.
- return _invokeMethodWithNamedArguments(
- reflectiveName, positionalArguments, namedArguments);
- }
- var cacheEntry = _getCachedInvocation(
- name, type, reflectiveName, positionalArguments, namedArguments);
-
- if (cacheEntry.isNoSuchMethod || !_isReflectable(cacheEntry)) {
- // Could be that we want to invoke a getter, or get a method.
- if (type == JSInvocationMirror.METHOD && _instanceFieldExists(name)) {
- return getField(name)
- .invoke(#call, positionalArguments, namedArguments);
- }
-
- if (type == JSInvocationMirror.SETTER) {
- // For setters we report the setter name "field=".
- name = s('${n(name)}=');
- }
-
- if (!cacheEntry.isNoSuchMethod) {
- // Not reflectable.
- throwInvalidReflectionError(reflectiveName);
- }
-
- String mangledName = reflectiveNames[reflectiveName];
- // TODO(ahe): Get the argument names.
- List<String> argumentNames = [];
- Invocation invocation = createUnmangledInvocationMirror(
- name, mangledName, type, positionalArguments, argumentNames);
- return reflect(cacheEntry.invokeOn(reflectee, invocation));
- } else {
- return reflect(cacheEntry.invokeOn(reflectee, positionalArguments));
- }
- }
-
- InstanceMirror setField(Symbol fieldName, Object arg) {
- _invoke(fieldName, JSInvocationMirror.SETTER, [arg], const {});
- return reflect(arg);
- }
-
- // JS helpers for getField optimizations.
- static bool isUndefined(x) => JS('bool', 'typeof # == "undefined"', x);
- static bool isMissingCache(x) => JS('bool', 'typeof # == "number"', x);
- static bool isMissingProbe(Symbol symbol) =>
- JS('bool', 'typeof #.\$p == "undefined"', symbol);
- static bool isEvalAllowed() => !JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');
-
- /// The getter cache is lazily allocated after a couple
- /// of invocations of [InstanceMirror.getField]. The delay is
- /// used to avoid too aggressive caching and dynamic function
- /// generation for rarely used mirrors. The cache is specific to
- /// this [InstanceMirror] and maps reflective names to functions
- /// that will invoke the corresponding getter on the reflectee.
- /// The reflectee is passed to the function as the first argument
- /// to avoid the overhead of fetching it from this mirror repeatedly.
- /// The cache is lazily initialized to a JS object so we can
- /// benefit from "map transitions" in the underlying JavaScript
- /// engine to speed up cache probing.
- var _getterCache = 4;
-
- bool _instanceFieldExists(Symbol name) {
- int getterType = JSInvocationMirror.GETTER;
- String getterName =
- _computeReflectiveName(name, getterType, const [], const {});
- var getterCacheEntry =
- _getCachedInvocation(name, getterType, getterName, const [], const {});
- return !getterCacheEntry.isNoSuchMethod && !getterCacheEntry.isGetterStub;
- }
-
- InstanceMirror getField(Symbol fieldName) {
- FASTPATH:
- {
- var cache = _getterCache;
- if (isMissingCache(cache) || isMissingProbe(fieldName)) break FASTPATH;
- // If the [fieldName] has an associated probe function, we can use
- // it to read from the getter cache specific to this [InstanceMirror].
- var getter = JS('', '#.\$p(#)', fieldName, cache);
- if (isUndefined(getter)) break FASTPATH;
- // Call the getter passing the reflectee as the first argument.
- var value = JS('', '#(#)', getter, reflectee);
- // The getter has an associate cache of the last [InstanceMirror]
- // returned to avoid repeated invocations of [reflect]. To validate
- // the cache, we check that the value returned by the getter is the
- // same value as last time.
- if (JS('bool', '# === #.v', value, getter)) {
- return JS('InstanceMirror', '#.m', getter);
- } else {
- var result = reflect(value);
- JS('void', '#.v = #', getter, value);
- JS('void', '#.m = #', getter, result);
- return result;
- }
- }
- return _getFieldSlow(fieldName);
- }
-
- InstanceMirror _getFieldSlow(Symbol fieldName) {
- // First do the slow-case getter invocation. As a side-effect of this,
- // the invocation cache is filled in so we can query it afterwards.
- var result =
- _invoke(fieldName, JSInvocationMirror.GETTER, const [], const {});
- String name = n(fieldName);
- var cacheEntry = JsCache.fetch(_classInvocationCache, name);
- if (cacheEntry.isNoSuchMethod) {
- return result;
- }
-
- // Make sure we have a getter cache in this [InstanceMirror].
- var cache = _getterCache;
- if (isMissingCache(cache)) {
- if ((_getterCache = --cache) != 0) return result;
- cache = _getterCache = JS('=Object', 'Object.create(null)');
- }
-
- // Make sure that symbol [fieldName] has a cache probing function ($p).
- bool useEval = isEvalAllowed();
- if (isMissingProbe(fieldName)) {
- var probe = _newProbeFn(name, useEval);
- JS('void', '#.\$p = #', fieldName, probe);
- }
-
- // Create a new getter function and install it in the cache.
- var mangledName = cacheEntry.mangledName;
- var getter = (cacheEntry.isIntercepted)
- ? _newInterceptedGetterFn(mangledName, useEval)
- : _newGetterFn(mangledName, useEval);
- JS('void', '#[#] = #', cache, name, getter);
-
- // Initialize the last value (v) and last mirror (m) on the
- // newly generated getter to be a sentinel value that is hard
- // to get hold of through user code.
- JS('void', '#.v = #.m = #', getter, getter, cache);
-
- // Return the result of the slow-path getter invocation.
- return result;
- }
-
- _newProbeFn(String id, bool useEval) {
- if (useEval) {
- String body = 'return c.$id;';
- return JS('', 'new Function("c", #)', body);
- } else {
- return JS('', '(function(n){return(function(c){return c[n]})})(#)', id);
- }
- }
-
- _newGetterFn(String name, bool useEval) {
- if (!useEval) return _newGetterNoEvalFn(name);
- // We use a comment that associates the generated function with the
- // class of the reflectee. This makes it more likely that the underlying
- // JavaScript engine will only share the generated code for accessors on the
- // same class (through caching of eval'ed code). This makes the
- // generated call to the getter - e.g. o.get$foo() - much more likely
- // to be monomorphic and inlineable.
- String className = JS('String', '#.constructor.name', reflectee);
- String body = '/* $className */ return o.$name();';
- return JS('', 'new Function("o", #)', body);
- }
-
- _newGetterNoEvalFn(n) =>
- JS('', '(function(n){return(function(o){return o[n]()})})(#)', n);
-
- _newInterceptedGetterFn(String name, bool useEval) {
- var object = reflectee;
- // It is possible that the interceptor for a given object is the object
- // itself, so it is important not to share the code that captures the
- // interceptor between multiple different instances of [InstanceMirror].
- var interceptor = getInterceptor(object);
- if (!useEval) return _newInterceptGetterNoEvalFn(name, interceptor);
- String className = JS('String', '#.constructor.name', interceptor);
- String functionName = '$className\$$name';
- String body = ' function $functionName(o){return i.$name(o)}'
- ' return $functionName;';
- return JS('', '(new Function("i", #))(#)', body, interceptor);
- }
-
- _newInterceptGetterNoEvalFn(n, i) =>
- JS('', '(function(n,i){return(function(o){return i[n](o)})})(#,#)', n, i);
-
- delegate(Invocation invocation) {
- return JSInvocationMirror.invokeFromMirror(invocation, reflectee);
- }
-
- operator ==(other) {
- return other is JsInstanceMirror && identical(reflectee, other.reflectee);
- }
-
- int get hashCode {
- // Avoid hash collisions with the reflectee. This constant is in Smi range
- // and happens to be the inner padding from RFC 2104.
- return identityHashCode(reflectee) ^ 0x36363636;
- }
-
- String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}';
-
- // TODO(ahe): Remove this method from the API.
- MirrorSystem get mirrors => currentJsMirrorSystem;
-}
-
-/**
- * ClassMirror for generic classes where the type parameters are bound.
- *
- * [typeArguments] will return a list of the type arguments, in contrast
- * to JsClassMirror that returns an empty list since it represents original
- * declarations and classes that are not generic.
- */
-class JsTypeBoundClassMirror extends JsDeclarationMirror
- implements ClassMirror {
- final JsClassMirror _class;
-
- /**
- * When instantiated this field will hold a string representing the list of
- * type arguments for the class, i.e. what is inside the outermost angle
- * brackets. Then, when get typeArguments is called the first time, the string
- * is parsed into the actual list of TypeMirrors, and stored in
- * [_cachedTypeArguments]. Due to type substitution of, for instance,
- * superclasses the mangled name of the class and hence this string is needed
- * after [_cachedTypeArguments] has been computed.
- *
- * If an integer is encountered as a type argument, it represents the type
- * variable at the corresponding entry in [emitter.globalMetadata].
- */
- String _typeArguments;
-
- UnmodifiableListView<TypeMirror> _cachedTypeArguments;
- UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
- UnmodifiableMapView<Symbol, DeclarationMirror> _cachedMembers;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors;
- Map<Symbol, VariableMirror> _cachedVariables;
- Map<Symbol, MethodMirror> _cachedGetters;
- Map<Symbol, MethodMirror> _cachedSetters;
- Map<Symbol, MethodMirror> _cachedMethodsMap;
- List<JsMethodMirror> _cachedMethods;
- ClassMirror _superclass;
- List<ClassMirror> _cachedSuperinterfaces;
- Map<Symbol, MethodMirror> _cachedInstanceMembers;
- Map<Symbol, MethodMirror> _cachedStaticMembers;
-
- JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
- : _class = originalDeclaration,
- super(originalDeclaration.simpleName);
-
- String get _prettyName => 'ClassMirror';
-
- String toString() {
- String result = '$_prettyName on ${n(simpleName)}';
- if (typeArguments != null) {
- result = "$result<${typeArguments.join(', ')}>";
- }
- return result;
- }
-
- String get _mangledName {
- for (TypeMirror typeArgument in typeArguments) {
- if (typeArgument != JsMirrorSystem._dynamicType) {
- return '${_class._mangledName}<$_typeArguments>';
- }
- }
- // When all type arguments are dynamic, the canonical representation is to
- // drop them.
- return _class._mangledName;
- }
-
- List<TypeVariableMirror> get typeVariables => _class.typeVariables;
-
- List<TypeMirror> get typeArguments {
- if (_cachedTypeArguments != null) return _cachedTypeArguments;
- var result = <TypeMirror>[];
-
- addTypeArgument(String typeArgument) {
- int parsedIndex = int.parse(typeArgument, onError: (_) => -1);
- if (parsedIndex == -1) {
- result.add(reflectClassByMangledName(typeArgument.trim()));
- } else {
- TypeVariable typeVariable = getMetadata(parsedIndex);
- TypeMirror owner = reflectClass(typeVariable.owner);
- TypeVariableMirror typeMirror =
- new JsTypeVariableMirror(typeVariable, owner, parsedIndex);
- result.add(typeMirror);
- }
- }
-
- splitTypeArguments(_typeArguments).forEach(addTypeArgument);
- return _cachedTypeArguments = new UnmodifiableListView(result);
- }
-
- List<JsMethodMirror> get _methods {
- if (_cachedMethods != null) return _cachedMethods;
- return _cachedMethods = _class._getMethodsWithOwner(this);
- }
-
- Map<Symbol, MethodMirror> get __methods {
- if (_cachedMethodsMap != null) return _cachedMethodsMap;
- return _cachedMethodsMap =
- new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
- }
-
- Map<Symbol, MethodMirror> get __constructors {
- if (_cachedConstructors != null) return _cachedConstructors;
- return _cachedConstructors = new UnmodifiableMapView<Symbol, MethodMirror>(
- filterConstructors(_methods));
- }
-
- Map<Symbol, MethodMirror> get __getters {
- if (_cachedGetters != null) return _cachedGetters;
- return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
- filterGetters(_methods, __variables));
- }
-
- Map<Symbol, MethodMirror> get __setters {
- if (_cachedSetters != null) return _cachedSetters;
- return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
- filterSetters(_methods, __variables));
- }
-
- Map<Symbol, VariableMirror> get __variables {
- if (_cachedVariables != null) return _cachedVariables;
- var result = new Map();
- for (JsVariableMirror mirror in _class._getFieldsWithOwner(this)) {
- result[mirror.simpleName] = mirror;
- }
- return _cachedVariables =
- new UnmodifiableMapView<Symbol, VariableMirror>(result);
- }
-
- Map<Symbol, DeclarationMirror> get __members {
- if (_cachedMembers != null) return _cachedMembers;
- return _cachedMembers = new UnmodifiableMapView<Symbol, DeclarationMirror>(
- filterMembers(_methods, __variables));
- }
-
- Map<Symbol, DeclarationMirror> get declarations {
- if (_cachedDeclarations != null) return _cachedDeclarations;
- Map<Symbol, DeclarationMirror> result =
- new Map<Symbol, DeclarationMirror>();
- result.addAll(__members);
- result.addAll(__constructors);
- typeVariables.forEach((tv) => result[tv.simpleName] = tv);
- return _cachedDeclarations =
- new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
- }
-
- Map<Symbol, MethodMirror> get staticMembers {
- if (_cachedStaticMembers == null) {
- var result = new Map<Symbol, MethodMirror>();
- declarations.values.forEach((decl) {
- if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
- result[decl.simpleName] = decl;
- }
- if (decl is VariableMirror && decl.isStatic) {
- var getterName = decl.simpleName;
- result[getterName] = new JsSyntheticAccessor(
- this, getterName, true, true, false, decl);
- if (!decl.isFinal) {
- var setterName = setterSymbol(decl.simpleName);
- result[setterName] = new JsSyntheticAccessor(
- this, setterName, false, true, false, decl);
- }
- }
- });
- _cachedStaticMembers = result;
- }
- return _cachedStaticMembers;
- }
-
- Map<Symbol, MethodMirror> get instanceMembers {
- if (_cachedInstanceMembers == null) {
- var result = new Map<Symbol, MethodMirror>();
- if (superclass != null) {
- result.addAll(superclass.instanceMembers);
- }
- declarations.values.forEach((decl) {
- if (decl is MethodMirror &&
- !decl.isStatic &&
- !decl.isConstructor &&
- !decl.isAbstract) {
- result[decl.simpleName] = decl;
- }
- if (decl is VariableMirror && !decl.isStatic) {
- var getterName = decl.simpleName;
- result[getterName] = new JsSyntheticAccessor(
- this, getterName, true, false, false, decl);
- if (!decl.isFinal) {
- var setterName = setterSymbol(decl.simpleName);
- result[setterName] = new JsSyntheticAccessor(
- this, setterName, false, false, false, decl);
- }
- }
- });
- _cachedInstanceMembers = result;
- }
- return _cachedInstanceMembers;
- }
-
- InstanceMirror setField(Symbol fieldName, Object arg) {
- return _class.setField(fieldName, arg);
- }
-
- InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName);
-
- InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- var instance = _class._getInvokedInstance(
- constructorName, positionalArguments, namedArguments);
- return reflect(setRuntimeTypeInfo(
- instance, typeArguments.map(_toRuntimeType).toList()));
- }
-
- _asRuntimeType() {
- return [_class._jsConstructor].addAll(typeArguments.map(_toRuntimeType));
- }
-
- static _toRuntimeType(TypeMirror t) {
- JsTypeMirror typeMirror = t;
- return typeMirror._asRuntimeType();
- }
-
- JsLibraryMirror get owner => _class.owner;
-
- List<InstanceMirror> get metadata => _class.metadata;
-
- ClassMirror get superclass {
- if (_superclass != null) return _superclass;
-
- var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
- List<int> typeInformation =
- JS('List|Null', '#[#]', typeInformationContainer, _class._mangledName);
- assert(typeInformation != null);
- var type = getType(typeInformation[0]);
- return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
- }
-
- InstanceMirror invoke(Symbol memberName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return _class.invoke(memberName, positionalArguments, namedArguments);
- }
-
- delegate(Invocation invocation) {
- throw new UnimplementedError();
- }
-
- bool get isOriginalDeclaration => false;
-
- ClassMirror get originalDeclaration => _class;
-
- List<ClassMirror> get superinterfaces {
- if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
- return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this);
- }
-
- bool get isPrivate => _class.isPrivate;
-
- bool get isTopLevel => _class.isTopLevel;
-
- bool get isAbstract => _class.isAbstract;
-
- bool get isEnum => _class.isEnum;
-
- bool isSubclassOf(ClassMirror other) => _class.isSubclassOf(other);
-
- SourceLocation get location => _class.location;
-
- MirrorSystem get mirrors => _class.mirrors;
-
- Symbol get qualifiedName => _class.qualifiedName;
-
- bool get hasReflectedType => true;
-
- Type get reflectedType => createRuntimeType(_mangledName);
-
- Symbol get simpleName => _class.simpleName;
-
- // TODO(ahe): Implement this.
- ClassMirror get mixin => throw new UnimplementedError();
-
- bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-
- bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-}
-
-class JsSyntheticAccessor implements MethodMirror {
- final DeclarationMirror owner;
- final Symbol simpleName;
- final bool isGetter;
- final bool isStatic;
- final bool isTopLevel;
-
- /// The field or type that introduces the synthetic accessor.
- final _target;
-
- JsSyntheticAccessor(this.owner, this.simpleName, this.isGetter, this.isStatic,
- this.isTopLevel, this._target);
-
- bool get isSynthetic => true;
- bool get isRegularMethod => false;
- bool get isOperator => false;
- bool get isConstructor => false;
- bool get isConstConstructor => false;
- bool get isGenerativeConstructor => false;
- bool get isFactoryConstructor => false;
- bool get isRedirectingConstructor => false;
- bool get isAbstract => false;
-
- bool get isSetter => !isGetter;
- bool get isPrivate => n(simpleName).startsWith('_');
-
- Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
- Symbol get constructorName => Symbol.empty;
-
- TypeMirror get returnType => _target.type;
- List<ParameterMirror> get parameters {
- if (isGetter) return const [];
- return new UnmodifiableListView(
- [new JsSyntheticSetterParameter(this, this._target)]);
- }
-
- List<InstanceMirror> get metadata => const [];
- String get source => null;
- SourceLocation get location => throw new UnimplementedError();
-}
-
-class JsSyntheticSetterParameter implements ParameterMirror {
- final DeclarationMirror owner;
- final VariableMirror _target;
-
- JsSyntheticSetterParameter(this.owner, this._target);
-
- Symbol get simpleName => _target.simpleName;
- Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
- TypeMirror get type => _target.type;
-
- bool get isOptional => false;
- bool get isNamed => false;
- bool get isStatic => false;
- bool get isTopLevel => false;
- bool get isConst => false;
- bool get isFinal => true;
- bool get isPrivate => false;
- bool get hasDefaultValue => false;
- InstanceMirror get defaultValue => null;
- List<InstanceMirror> get metadata => const [];
- SourceLocation get location => throw new UnimplementedError();
-}
-
-class JsClassMirror extends JsTypeMirror
- with JsObjectMirror
- implements ClassMirror {
- final String _mangledName;
- final _jsConstructor;
- final String _fieldsDescriptor;
- final List _fieldsMetadata;
- final _jsConstructorCache = JsCache.allocate();
- List _metadata;
- ClassMirror _superclass;
- List<JsMethodMirror> _cachedMethods;
- List<VariableMirror> _cachedFields;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedMethodsMap;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
- UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
- UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
- UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
- UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
- UnmodifiableListView<InstanceMirror> _cachedMetadata;
- UnmodifiableListView<ClassMirror> _cachedSuperinterfaces;
- UnmodifiableListView<TypeVariableMirror> _cachedTypeVariables;
- Map<Symbol, MethodMirror> _cachedInstanceMembers;
- Map<Symbol, MethodMirror> _cachedStaticMembers;
-
- // Set as side-effect of accessing JsLibraryMirror.classes.
- JsLibraryMirror _owner;
-
- JsClassMirror(Symbol simpleName, this._mangledName, this._jsConstructor,
- this._fieldsDescriptor, this._fieldsMetadata)
- : super(simpleName);
-
- String get _prettyName => 'ClassMirror';
-
- Map<Symbol, MethodMirror> get __constructors {
- if (_cachedConstructors != null) return _cachedConstructors;
- return _cachedConstructors = new UnmodifiableMapView<Symbol, MethodMirror>(
- filterConstructors(_methods));
- }
-
- _asRuntimeType() {
- if (typeVariables.isEmpty) return _jsConstructor;
- var type = [_jsConstructor];
- for (int i = 0; i < typeVariables.length; i++) {
- type.add(JsMirrorSystem._dynamicType._asRuntimeType);
- }
- return type;
- }
-
- List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) {
- var prototype = JS('', '#.prototype', _jsConstructor);
- // The prototype might not have been processed yet, so do that now.
- JS('', '#[#]()', prototype,
- JS_GET_NAME(JsGetName.DEFERRED_ACTION_PROPERTY));
- List<String> keys = extractKeys(prototype);
- var result = <JsMethodMirror>[];
- for (String key in keys) {
- if (isReflectiveDataInPrototype(key)) continue;
- String simpleName = mangledNames[key];
- // [simpleName] can be null if [key] represents an implementation
- // detail, for example, a bailout method, or runtime type support.
- // It might also be null if the user has limited what is reified for
- // reflection with metadata.
- if (simpleName == null) continue;
- var function = JS('', '#[#]', prototype, key);
- if (!isOrdinaryReflectableMethod(function)) continue;
- if (isAliasedSuperMethod(function, key)) continue;
- var mirror = new JsMethodMirror.fromUnmangledName(
- simpleName, function, false, false);
- result.add(mirror);
- mirror._owner = methodOwner;
- }
-
- var statics = JS_EMBEDDED_GLOBAL('', STATICS);
- keys = extractKeys(JS('', '#[#]', statics, _mangledName));
- for (String mangledName in keys) {
- if (isReflectiveDataInPrototype(mangledName)) continue;
- String unmangledName = mangledName;
- var jsFunction = JS('', '#[#]', owner._globalObject, mangledName);
-
- bool isConstructor = false;
- if (hasReflectableProperty(jsFunction)) {
- String reflectionName =
- JS('String|Null', r'#.$reflectionName', jsFunction);
- if (reflectionName == null) continue;
- isConstructor = reflectionName.startsWith('new ');
- if (isConstructor) {
- reflectionName = reflectionName.substring(4).replaceAll(r'$', '.');
- }
- unmangledName = reflectionName;
- } else {
- continue;
- }
- bool isStatic = !isConstructor; // Constructors are not static.
- JsMethodMirror mirror = new JsMethodMirror.fromUnmangledName(
- unmangledName, jsFunction, isStatic, isConstructor);
- result.add(mirror);
- mirror._owner = methodOwner;
- }
-
- return result;
- }
-
- List<JsMethodMirror> get _methods {
- if (_cachedMethods != null) return _cachedMethods;
- return _cachedMethods = _getMethodsWithOwner(this);
- }
-
- List<VariableMirror> _getFieldsWithOwner(DeclarationMirror fieldOwner) {
- var result = <VariableMirror>[];
-
- dynamic instanceFieldSpecfication = _fieldsDescriptor.split(';')[1];
- if (_fieldsMetadata != null) {
- instanceFieldSpecfication = <dynamic>[instanceFieldSpecfication]
- ..addAll(_fieldsMetadata);
- }
- parseCompactFieldSpecification(
- fieldOwner, instanceFieldSpecfication, false, result);
-
- var statics = JS_EMBEDDED_GLOBAL('', STATICS);
- var staticDescriptor = JS('', '#[#]', statics, _mangledName);
- if (staticDescriptor != null) {
- parseCompactFieldSpecification(
- fieldOwner,
- JS('', '#[#]', staticDescriptor,
- JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY)),
- true,
- result);
- }
- return result;
- }
-
- List<VariableMirror> get _fields {
- if (_cachedFields != null) return _cachedFields;
- return _cachedFields = _getFieldsWithOwner(this);
- }
-
- Map<Symbol, MethodMirror> get __methods {
- if (_cachedMethodsMap != null) return _cachedMethodsMap;
- return _cachedMethodsMap =
- new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
- }
-
- Map<Symbol, MethodMirror> get __getters {
- if (_cachedGetters != null) return _cachedGetters;
- return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
- filterGetters(_methods, __variables));
- }
-
- Map<Symbol, MethodMirror> get __setters {
- if (_cachedSetters != null) return _cachedSetters;
- return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
- filterSetters(_methods, __variables));
- }
-
- Map<Symbol, VariableMirror> get __variables {
- if (_cachedVariables != null) return _cachedVariables;
- var result = new Map();
- for (JsVariableMirror mirror in _fields) {
- result[mirror.simpleName] = mirror;
- }
- return _cachedVariables =
- new UnmodifiableMapView<Symbol, VariableMirror>(result);
- }
-
- Map<Symbol, Mirror> get __members {
- if (_cachedMembers != null) return _cachedMembers;
- return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(
- filterMembers(_methods, __variables));
- }
-
- Map<Symbol, DeclarationMirror> get declarations {
- if (_cachedDeclarations != null) return _cachedDeclarations;
- var result = new Map<Symbol, DeclarationMirror>();
- addToResult(Symbol key, Mirror value) {
- result[key] = value;
- }
-
- __members.forEach(addToResult);
- __constructors.forEach(addToResult);
- typeVariables.forEach((tv) => result[tv.simpleName] = tv);
- return _cachedDeclarations =
- new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
- }
-
- Map<Symbol, MethodMirror> get staticMembers {
- if (_cachedStaticMembers == null) {
- var result = new Map<Symbol, MethodMirror>();
- declarations.values.forEach((decl) {
- if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
- result[decl.simpleName] = decl;
- }
- if (decl is VariableMirror && decl.isStatic) {
- var getterName = decl.simpleName;
- result[getterName] = new JsSyntheticAccessor(
- this, getterName, true, true, false, decl);
- if (!decl.isFinal) {
- var setterName = setterSymbol(decl.simpleName);
- result[setterName] = new JsSyntheticAccessor(
- this, setterName, false, true, false, decl);
- }
- }
- });
- _cachedStaticMembers = result;
- }
- return _cachedStaticMembers;
- }
-
- Map<Symbol, MethodMirror> get instanceMembers {
- if (_cachedInstanceMembers == null) {
- var result = new Map<Symbol, MethodMirror>();
- if (superclass != null) {
- result.addAll(superclass.instanceMembers);
- }
- declarations.values.forEach((decl) {
- if (decl is MethodMirror &&
- !decl.isStatic &&
- !decl.isConstructor &&
- !decl.isAbstract) {
- result[decl.simpleName] = decl;
- }
- if (decl is VariableMirror && !decl.isStatic) {
- var getterName = decl.simpleName;
- result[getterName] = new JsSyntheticAccessor(
- this, getterName, true, false, false, decl);
- if (!decl.isFinal) {
- var setterName = setterSymbol(decl.simpleName);
- result[setterName] = new JsSyntheticAccessor(
- this, setterName, false, false, false, decl);
- }
- }
- });
- _cachedInstanceMembers = result;
- }
- return _cachedInstanceMembers;
- }
-
- InstanceMirror setField(Symbol fieldName, Object arg) {
- JsVariableMirror mirror = __variables[fieldName];
- if (mirror != null && mirror.isStatic && !mirror.isFinal) {
- // '$' (JS_GET_STATIC_STATE()) stores state which is stored directly, so
- // we shouldn't use [JsLibraryMirror._globalObject] here.
- String jsName = mirror._jsName;
- if (!JS('bool', '# in #', jsName, JS_GET_STATIC_STATE())) {
- throw new RuntimeError('Cannot find "$jsName" in current isolate.');
- }
- JS('void', '#[#] = #', JS_GET_STATIC_STATE(), jsName, arg);
- return reflect(arg);
- }
- Symbol setterName = setterSymbol(fieldName);
- if (mirror == null) {
- JsMethodMirror setter = __setters[setterName];
- if (setter != null) {
- setter._invoke([arg], const {});
- return reflect(arg);
- }
- }
- throw new NoSuchStaticMethodError.method(null, setterName, [arg], null);
- }
-
- bool _staticFieldExists(Symbol fieldName) {
- JsVariableMirror mirror = __variables[fieldName];
- if (mirror != null) return mirror.isStatic;
- JsMethodMirror getter = __getters[fieldName];
- return getter != null && getter.isStatic;
- }
-
- InstanceMirror getField(Symbol fieldName) {
- JsVariableMirror mirror = __variables[fieldName];
- if (mirror != null && mirror.isStatic) {
- String jsName = mirror._jsName;
- // '$' (JS_GET_STATIC_STATE()) stores state which is read directly, so
- // we shouldn't use [JsLibraryMirror._globalObject] here.
- if (!JS('bool', '# in #', jsName, JS_GET_STATIC_STATE())) {
- throw new RuntimeError('Cannot find "$jsName" in current isolate.');
- }
- var lazies = JS_EMBEDDED_GLOBAL('', LAZIES);
- if (JS('bool', '# in #', jsName, lazies)) {
- String getterName = JS('String', '#[#]', lazies, jsName);
- return reflect(JS('', '#[#]()', JS_GET_STATIC_STATE(), getterName));
- } else {
- return reflect(JS('', '#[#]', JS_GET_STATIC_STATE(), jsName));
- }
- }
- JsMethodMirror getter = __getters[fieldName];
- if (getter != null && getter.isStatic) {
- return reflect(getter._invoke(const [], const {}));
- }
- // If the fieldName designates a static function we have to return
- // its closure.
- JsMethodMirror method = __methods[fieldName];
- if (method != null && method.isStatic) {
- // We invoke the same getter that Dart code would execute. During
- // initialization we have stored that getter on the function (so that
- // we can find it more easily here).
- var getter = JS('', "#['\$getter']", method._jsFunction);
- if (getter == null) throw new UnimplementedError();
- return reflect(JS('', '#()', getter));
- }
- throw new NoSuchStaticMethodError.method(null, fieldName, null, null);
- }
-
- _getInvokedInstance(Symbol constructorName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null && !namedArguments.isEmpty) {
- throw new UnsupportedError('Named arguments are not implemented.');
- }
- JsMethodMirror mirror =
- JsCache.fetch(_jsConstructorCache, n(constructorName));
- if (mirror == null) {
- mirror = __constructors.values
- .firstWhere((m) => m.constructorName == constructorName, orElse: () {
- throw new NoSuchStaticMethodError.method(
- null, constructorName, positionalArguments, namedArguments);
- });
- JsCache.update(_jsConstructorCache, n(constructorName), mirror);
- }
- return mirror._invoke(positionalArguments, namedArguments);
- }
-
- InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return reflect(_getInvokedInstance(
- constructorName, positionalArguments, namedArguments));
- }
-
- JsLibraryMirror get owner {
- if (_owner == null) {
- for (var list in JsMirrorSystem.librariesByName.values) {
- for (JsLibraryMirror library in list) {
- // This will set _owner field on all classes as a side
- // effect. This gives us a fast path to reflect on a
- // class without parsing reflection data.
- library.__classes;
- }
- }
- if (_owner == null) {
- throw new StateError('Class "${n(simpleName)}" has no owner');
- }
- }
- return _owner;
- }
-
- List<InstanceMirror> get metadata {
- if (_cachedMetadata != null) return _cachedMetadata;
- if (_metadata == null) {
- _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor));
- }
- return _cachedMetadata =
- new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
- }
-
- ClassMirror get superclass {
- if (_superclass == null) {
- var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
- List<int> typeInformation =
- JS('List|Null', '#[#]', typeInformationContainer, _mangledName);
- if (typeInformation != null) {
- var type = getType(typeInformation[0]);
- _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
- } else {
- var superclassName = _fieldsDescriptor.split(';')[0].split(':')[0];
- // TODO(zarah): Remove special handing of mixins.
- var mixins = superclassName.split('+');
- if (mixins.length > 1) {
- if (mixins.length != 2) {
- throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
- }
- _superclass = reflectClassByMangledName(mixins[0]);
- } else {
- // Use _superclass == this to represent class with no superclass
- // (Object).
- _superclass = (superclassName == '')
- ? this
- : reflectClassByMangledName(superclassName);
- }
- }
- }
- return _superclass == this ? null : _superclass;
- }
-
- InstanceMirror invoke(Symbol memberName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- // Mirror API gotcha: Calling [invoke] on a ClassMirror means invoke a
- // static method.
-
- if (namedArguments != null && !namedArguments.isEmpty) {
- throw new UnsupportedError('Named arguments are not implemented.');
- }
- JsMethodMirror mirror = __methods[memberName];
-
- if (mirror == null && _staticFieldExists(memberName)) {
- return getField(memberName)
- .invoke(#call, positionalArguments, namedArguments);
- }
- if (mirror == null || !mirror.isStatic) {
- throw new NoSuchStaticMethodError.method(
- null, memberName, positionalArguments, namedArguments);
- }
- if (!mirror.canInvokeReflectively()) {
- throwInvalidReflectionError(n(memberName));
- }
- return reflect(mirror._invoke(positionalArguments, namedArguments));
- }
-
- delegate(Invocation invocation) {
- throw new UnimplementedError();
- }
-
- bool get isOriginalDeclaration => true;
-
- ClassMirror get originalDeclaration => this;
-
- List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) {
- var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
- List<int> typeInformation =
- JS('List|Null', '#[#]', typeInformationContainer, _mangledName);
- List<ClassMirror> result = const <ClassMirror>[];
- if (typeInformation != null) {
- ClassMirror lookupType(int i) {
- var type = getType(i);
- return typeMirrorFromRuntimeTypeRepresentation(owner, type);
- }
-
- //We skip the first since it is the supertype.
- result = typeInformation.skip(1).map(lookupType).toList();
- }
-
- return new UnmodifiableListView<ClassMirror>(result);
- }
-
- List<ClassMirror> get superinterfaces {
- if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
- return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this);
- }
-
- List<TypeVariableMirror> get typeVariables {
- if (_cachedTypeVariables != null) return _cachedTypeVariables;
- var result = new List<TypeVariableMirror>();
- List typeVariables =
- JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
- if (typeVariables == null) return result;
- for (int i = 0; i < typeVariables.length; i++) {
- TypeVariable typeVariable = getMetadata(typeVariables[i]);
- result
- .add(new JsTypeVariableMirror(typeVariable, this, typeVariables[i]));
- }
- return _cachedTypeVariables = new UnmodifiableListView(result);
- }
-
- List<TypeMirror> get typeArguments => const <TypeMirror>[];
-
- bool get hasReflectedType => typeVariables.length == 0;
-
- Type get reflectedType {
- if (!hasReflectedType) {
- throw new UnsupportedError(
- 'Declarations of generics have no reflected type');
- }
- return createRuntimeType(_mangledName);
- }
-
- // TODO(ahe): Implement this.
- ClassMirror get mixin => throw new UnimplementedError();
-
- bool get isAbstract => throw new UnimplementedError();
-
- bool get isEnum => throw new UnimplementedError();
-
- bool isSubclassOf(ClassMirror other) {
- if (other is! ClassMirror) {
- throw new ArgumentError(other);
- }
- if (other is JsFunctionTypeMirror) {
- return false;
- }
- if (other is JsClassMirror &&
- JS('bool', '# == #', other._jsConstructor, _jsConstructor)) {
- return true;
- } else if (superclass == null) {
- return false;
- } else {
- return superclass.isSubclassOf(other);
- }
- }
-}
-
-class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
- // TODO(ahe): The values in these fields are virtually untested.
- final String _jsName;
- final bool isFinal;
- final bool isStatic;
- final _metadataFunction;
- final DeclarationMirror _owner;
- final int _type;
- List _metadata;
-
- JsVariableMirror(Symbol simpleName, this._jsName, this._type, this.isFinal,
- this.isStatic, this._metadataFunction, this._owner)
- : super(simpleName);
-
- factory JsVariableMirror.from(String descriptor, metadataFunction,
- JsDeclarationMirror owner, bool isStatic) {
- List<String> fieldInformation = descriptor.split('-');
- if (fieldInformation.length == 1) {
- // The field is not available for reflection.
- // TODO(ahe): Should return an unreflectable field.
- return null;
- }
-
- String field = fieldInformation[0];
- int length = field.length;
- var code = fieldCode(field.codeUnitAt(length - 1));
- bool isFinal = false;
- if (code == 0) return null; // Inherited field.
- bool hasGetter = (code & 3) != 0;
- bool hasSetter = (code >> 2) != 0;
- isFinal = !hasSetter;
- length--;
- String jsName;
- String accessorName = jsName = field.substring(0, length);
- int divider = field.indexOf(':');
- if (divider > 0) {
- accessorName = accessorName.substring(0, divider);
- jsName = field.substring(divider + 1);
- }
- var unmangledName;
- if (isStatic) {
- unmangledName = mangledGlobalNames[accessorName];
- } else {
- String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
- unmangledName = mangledNames['$getterPrefix$accessorName'];
- }
- if (unmangledName == null) unmangledName = accessorName;
- if (!hasSetter) {
- // TODO(ahe): This is a hack to handle checked setters in checked mode.
- var setterName = s('$unmangledName=');
- for (JsMethodMirror method in owner._methods) {
- if (method.simpleName == setterName) {
- isFinal = false;
- break;
- }
- }
- }
- int type = int.parse(fieldInformation[1], onError: (_) => null);
- return new JsVariableMirror(s(unmangledName), jsName, type, isFinal,
- isStatic, metadataFunction, owner);
- }
-
- String get _prettyName => 'VariableMirror';
-
- TypeMirror get type {
- return typeMirrorFromRuntimeTypeRepresentation(owner, getType(_type));
- }
-
- DeclarationMirror get owner => _owner;
-
- List<InstanceMirror> get metadata {
- preserveMetadata();
- if (_metadata == null) {
- _metadata = (_metadataFunction == null)
- ? const []
- : JS('', '#()', _metadataFunction);
- }
- return _metadata.map(reflect).toList();
- }
-
- static int fieldCode(int code) {
- if (code >= 60 && code <= 64) return code - 59;
- if (code >= 123 && code <= 126) return code - 117;
- if (code >= 37 && code <= 43) return code - 27;
- return 0;
- }
-
- _getField(JsMirror receiver) => receiver._loadField(_jsName);
-
- void _setField(JsMirror receiver, Object arg) {
- if (isFinal) {
- // TODO(floitsch): when the field is non-static we don't want to have
- // a mirror as receiver.
- if (isStatic) {
- throw new NoSuchStaticMethodError.method(
- null, setterSymbol(simpleName), [arg], null);
- }
- throw new NoSuchMethodError(this, setterSymbol(simpleName), [arg], null);
- }
- receiver._storeField(_jsName, arg);
- }
-
- // TODO(ahe): Implement this method.
- bool get isConst => throw new UnimplementedError();
-}
-
-class JsClosureMirror extends JsInstanceMirror implements ClosureMirror {
- JsClosureMirror(reflectee) : super(reflectee);
-
- MethodMirror get function {
- String cacheName = Primitives.mirrorFunctionCacheName;
- JsMethodMirror cachedFunction;
- // TODO(ahe): Restore caching.
- //= JS('JsMethodMirror|Null', r'#.constructor[#]', reflectee, cacheName);
- if (cachedFunction != null) return cachedFunction;
- disableTreeShaking();
- // TODO(ahe): What about optional parameters (named or not).
- String callPrefix = '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$';
-
- String callName = JS(
- 'String|Null',
- r'''
- (function(reflectee, callPrefix) {
- var properties = Object.keys(reflectee.constructor.prototype);
- var callPrefixLength = callPrefix.length;
- for (var i = 0; i < properties.length; i++) {
- var property = properties[i];
- if (callPrefix == property.substring(0, callPrefixLength) &&
- property[callPrefixLength] >= "0" &&
- property[callPrefixLength] <= "9") {
- return property;
- }
- }
- return null;
- })(#, #)''',
- reflectee,
- callPrefix);
-
- if (callName == null) {
- throw new RuntimeError('Cannot find callName on "$reflectee"');
- }
- // TODO(floitsch): What about optional parameters?
- int parameterCount = int.parse(callName.split(r'$')[1]);
- if (reflectee is BoundClosure) {
- var target = BoundClosure.targetOf(reflectee);
- var self = BoundClosure.selfOf(reflectee);
- var name = mangledNames[BoundClosure.nameOf(reflectee)];
- if (name == null) {
- throwInvalidReflectionError(name);
- }
- cachedFunction =
- new JsMethodMirror.fromUnmangledName(name, target, false, false);
- } else {
- bool isStatic = true; // TODO(ahe): Compute isStatic correctly.
- var jsFunction = JS('', '#[#]', reflectee, callName);
- var dummyOptionalParameterCount = 0;
- cachedFunction = new JsMethodMirror(
- s(callName),
- jsFunction,
- parameterCount,
- dummyOptionalParameterCount,
- false,
- false,
- isStatic,
- false,
- false);
- }
- JS('void', r'#.constructor[#] = #', reflectee, cacheName, cachedFunction);
- return cachedFunction;
- }
-
- InstanceMirror apply(List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) {
- return reflect(
- Function.apply(reflectee, positionalArguments, namedArguments));
- }
-
- ClassMirror get type {
- // Classes that implement [call] do not subclass [Closure], but only
- // implement [Function], so are rejected by this test.
- if (reflectee is Closure) {
- var functionRti = extractFunctionTypeObjectFrom(reflectee);
- if (functionRti != null) {
- return new JsFunctionTypeMirror(functionRti, null);
- }
- }
- // Use the JsInstanceMirror method to return the JsClassMirror.
- // TODO(sra): Should there be a TypeMirror that is both a ClassMirror and
- // FunctionTypeMirror?
- return super.type;
- }
-
- String toString() => "ClosureMirror on '${Error.safeToString(reflectee)}'";
-
- // TODO(ahe): Implement this method.
- String get source => throw new UnimplementedError();
-}
-
-class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
- final _jsFunction;
- final int _requiredParameterCount;
- final int _optionalParameterCount;
- final bool isGetter;
- final bool isSetter;
- final bool isStatic;
- final bool isConstructor;
- final bool isOperator;
- DeclarationMirror _owner;
- List _metadata;
- TypeMirror _returnType;
- UnmodifiableListView<ParameterMirror> _parameters;
-
- JsMethodMirror(
- Symbol simpleName,
- this._jsFunction,
- this._requiredParameterCount,
- this._optionalParameterCount,
- this.isGetter,
- this.isSetter,
- this.isStatic,
- this.isConstructor,
- this.isOperator)
- : super(simpleName);
-
- factory JsMethodMirror.fromUnmangledName(
- String name, jsFunction, bool isStatic, bool isConstructor) {
- List<String> info = name.split(':');
- name = info[0];
- bool isOperator = isOperatorName(name);
- bool isSetter = !isOperator && name.endsWith('=');
- int requiredParameterCount = 0;
- int optionalParameterCount = 0;
- bool isGetter = false;
- if (info.length == 1) {
- if (isSetter) {
- requiredParameterCount = 1;
- } else {
- isGetter = true;
- requiredParameterCount = 0;
- }
- } else {
- ReflectionInfo reflectionInfo = new ReflectionInfo(jsFunction);
- requiredParameterCount = reflectionInfo.requiredParameterCount;
- optionalParameterCount = reflectionInfo.optionalParameterCount;
- assert(int.parse(info[1]) ==
- requiredParameterCount + optionalParameterCount);
- }
- return new JsMethodMirror(
- s(name),
- jsFunction,
- requiredParameterCount,
- optionalParameterCount,
- isGetter,
- isSetter,
- isStatic,
- isConstructor,
- isOperator);
- }
-
- String get _prettyName => 'MethodMirror';
-
- int get _parameterCount => _requiredParameterCount + _optionalParameterCount;
-
- List<ParameterMirror> get parameters {
- if (_parameters != null) return _parameters;
- metadata; // Compute _parameters as a side-effect of extracting metadata.
- return _parameters;
- }
-
- bool canInvokeReflectively() {
- return hasReflectableProperty(_jsFunction);
- }
-
- DeclarationMirror get owner => _owner;
-
- TypeMirror get returnType {
- metadata; // Compute _returnType as a side-effect of extracting metadata.
- return _returnType;
- }
-
- List<InstanceMirror> get metadata {
- if (_metadata == null) {
- var raw = extractMetadata(_jsFunction);
- var formals = new List<ParameterMirror>(_parameterCount);
- ReflectionInfo info = new ReflectionInfo(_jsFunction);
- if (info != null) {
- assert(_parameterCount ==
- info.requiredParameterCount + info.optionalParameterCount);
- var functionType = info.functionType;
- var type;
- if (functionType is int) {
- type = new JsFunctionTypeMirror(info.computeFunctionRti(null), this);
- assert(_parameterCount == type.parameters.length);
- } else if (isTopLevel) {
- type = new JsFunctionTypeMirror(info.computeFunctionRti(null), owner);
- } else {
- TypeMirror ownerType = owner;
- JsClassMirror ownerClass = ownerType.originalDeclaration;
- type = new JsFunctionTypeMirror(
- info.computeFunctionRti(ownerClass._jsConstructor), owner);
- }
- // Constructors aren't reified with their return type.
- if (isConstructor) {
- _returnType = owner;
- } else {
- _returnType = type.returnType;
- }
- int i = 0;
- bool isNamed = info.areOptionalParametersNamed;
- for (JsParameterMirror parameter in type.parameters) {
- var name = info.parameterName(i);
- List<int> annotations = info.parameterMetadataAnnotations(i);
- var p;
- if (i < info.requiredParameterCount) {
- p = new JsParameterMirror(name, this, parameter._type,
- metadataList: annotations);
- } else {
- var defaultValue = info.defaultValue(i);
- p = new JsParameterMirror(name, this, parameter._type,
- metadataList: annotations,
- isOptional: true,
- isNamed: isNamed,
- defaultValue: defaultValue);
- }
- formals[i++] = p;
- }
- }
- _parameters = new UnmodifiableListView<ParameterMirror>(formals);
- _metadata = new UnmodifiableListView(raw.map(reflect));
- }
- return _metadata;
- }
-
- Symbol get constructorName {
- // TODO(ahe): I believe it is more appropriate to throw an exception or
- // return null.
- if (!isConstructor) return Symbol.empty;
- String name = n(simpleName);
- int index = name.indexOf('.');
- if (index == -1) return Symbol.empty;
- return s(name.substring(index + 1));
- }
-
- _invoke(List positionalArguments, Map<Symbol, dynamic> namedArguments) {
- if (namedArguments != null && !namedArguments.isEmpty) {
- throw new UnsupportedError('Named arguments are not implemented.');
- }
- if (!isStatic && !isConstructor) {
- throw new RuntimeError('Cannot invoke instance method without receiver.');
- }
- int positionalLength = positionalArguments.length;
- if (positionalLength < _requiredParameterCount ||
- positionalLength > _parameterCount ||
- _jsFunction == null) {
- // TODO(ahe): What receiver to use?
- throw new NoSuchMethodError(
- owner, simpleName, positionalArguments, namedArguments);
- }
- if (positionalLength < _parameterCount) {
- // Fill up with default values.
- // Make a copy so we don't modify the input.
- positionalArguments = positionalArguments.toList();
- for (int i = positionalLength; i < parameters.length; i++) {
- JsParameterMirror parameter = parameters[i];
- positionalArguments.add(parameter.defaultValue.reflectee);
- }
- }
- // Using JS_GET_STATIC_STATE() ('$') here is actually correct, although
- // _jsFunction may not be a property of '$', most static functions do not
- // care who their receiver is. But to lazy getters, it is important that
- // 'this' is '$'.
- return JS('', r'#.apply(#, #)', _jsFunction, JS_GET_STATIC_STATE(),
- new List.from(positionalArguments));
- }
-
- _getField(JsMirror receiver) {
- if (isGetter) {
- return _invoke([], null);
- } else {
- // TODO(ahe): Closurize method.
- throw new UnimplementedError('getField on $receiver');
- }
- }
-
- _setField(JsMirror receiver, Object arg) {
- if (isSetter) {
- return _invoke([arg], null);
- } else {
- throw new NoSuchMethodError(this, setterSymbol(simpleName), [], null);
- }
- }
-
- // Abstract methods are tree-shaken away.
- bool get isAbstract => false;
-
- // TODO(ahe, 14633): This might not be true for all cases.
- bool get isSynthetic => false;
-
- // TODO(ahe): Test this.
- bool get isRegularMethod => !isGetter && !isSetter && !isConstructor;
-
- // TODO(ahe): Implement this method.
- bool get isConstConstructor => throw new UnimplementedError();
-
- // TODO(ahe): Implement this method.
- bool get isGenerativeConstructor => throw new UnimplementedError();
-
- // TODO(ahe): Implement this method.
- bool get isRedirectingConstructor => throw new UnimplementedError();
-
- // TODO(ahe): Implement this method.
- bool get isFactoryConstructor => throw new UnimplementedError();
-
- // TODO(ahe): Implement this method.
- String get source => throw new UnimplementedError();
-}
-
-class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror {
- final DeclarationMirror owner;
- // A JS object representing the type.
- final _type;
-
- final bool isOptional;
-
- final bool isNamed;
-
- final int _defaultValue;
-
- final List<int> metadataList;
-
- JsParameterMirror(String unmangledName, this.owner, this._type,
- {this.metadataList: const <int>[],
- this.isOptional: false,
- this.isNamed: false,
- defaultValue})
- : _defaultValue = defaultValue,
- super(s(unmangledName));
-
- String get _prettyName => 'ParameterMirror';
-
- TypeMirror get type {
- return typeMirrorFromRuntimeTypeRepresentation(owner, _type);
- }
-
- // Only true for static fields, never for a parameter.
- bool get isStatic => false;
-
- // TODO(ahe): Implement this.
- bool get isFinal => false;
-
- // TODO(ahe): Implement this.
- bool get isConst => false;
-
- bool get hasDefaultValue => _defaultValue != null;
-
- get defaultValue {
- return hasDefaultValue ? reflect(getMetadata(_defaultValue)) : null;
- }
-
- List<InstanceMirror> get metadata {
- preserveMetadata();
- return metadataList.map((int i) => reflect(getMetadata(i))).toList();
- }
-}
-
-class JsTypedefMirror extends JsDeclarationMirror implements TypedefMirror {
- final String _mangledName;
- JsFunctionTypeMirror referent;
-
- JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData)
- : super(simpleName) {
- referent = new JsFunctionTypeMirror(_typeData, this);
- }
-
- JsFunctionTypeMirror get value => referent;
-
- String get _prettyName => 'TypedefMirror';
-
- bool get hasReflectedType => throw new UnimplementedError();
-
- Type get reflectedType => createRuntimeType(_mangledName);
-
- // TODO(floitsch): Implement this method.
- List<TypeVariableMirror> get typeVariables => throw new UnimplementedError();
-
- // TODO(floitsch): Implement this method.
- List<TypeMirror> get typeArguments => throw new UnimplementedError();
-
- bool get isOriginalDeclaration => true;
-
- TypeMirror get originalDeclaration => this;
-
- // TODO(floitsch): Implement this method.
- DeclarationMirror get owner => throw new UnimplementedError();
-
- // TODO(ahe): Implement this method.
- List<InstanceMirror> get metadata => throw new UnimplementedError();
-
- bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
- bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-}
-
-// TODO(ahe): Remove this class when API is updated.
-class BrokenClassMirror {
- bool get hasReflectedType => throw new UnimplementedError();
- Type get reflectedType => throw new UnimplementedError();
- ClassMirror get superclass => throw new UnimplementedError();
- List<ClassMirror> get superinterfaces => throw new UnimplementedError();
- Map<Symbol, DeclarationMirror> get declarations =>
- throw new UnimplementedError();
- Map<Symbol, MethodMirror> get instanceMembers =>
- throw new UnimplementedError();
- Map<Symbol, MethodMirror> get staticMembers => throw new UnimplementedError();
- ClassMirror get mixin => throw new UnimplementedError();
- InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) =>
- throw new UnimplementedError();
- InstanceMirror invoke(Symbol memberName, List positionalArguments,
- [Map<Symbol, dynamic> namedArguments]) =>
- throw new UnimplementedError();
- InstanceMirror getField(Symbol fieldName) => throw new UnimplementedError();
- InstanceMirror setField(Symbol fieldName, Object value) =>
- throw new UnimplementedError();
- delegate(Invocation invocation) => throw new UnimplementedError();
- List<TypeVariableMirror> get typeVariables => throw new UnimplementedError();
- List<TypeMirror> get typeArguments => throw new UnimplementedError();
- TypeMirror get originalDeclaration => throw new UnimplementedError();
- Symbol get simpleName => throw new UnimplementedError();
- Symbol get qualifiedName => throw new UnimplementedError();
- bool get isPrivate => throw new UnimplementedError();
- bool get isTopLevel => throw new UnimplementedError();
- SourceLocation get location => throw new UnimplementedError();
- List<InstanceMirror> get metadata => throw new UnimplementedError();
-}
-
-class JsFunctionTypeMirror extends BrokenClassMirror
- implements FunctionTypeMirror {
- final _typeData;
- String _cachedToString;
- TypeMirror _cachedReturnType;
- UnmodifiableListView<ParameterMirror> _cachedParameters;
- Type _cachedReflectedType;
- DeclarationMirror owner;
-
- JsFunctionTypeMirror(this._typeData, this.owner);
-
- bool get _hasReturnType {
- return JS('bool', '# in #',
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG), _typeData);
- }
-
- get _returnType {
- return JS('', '#[#]', _typeData,
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG));
- }
-
- bool get _isVoid {
- return JS('bool', '!!#[#]', _typeData,
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG));
- }
-
- bool get _hasArguments {
- return JS(
- 'bool',
- '# in #',
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG),
- _typeData);
- }
-
- List get _arguments {
- return JS('JSExtendableArray', '#[#]', _typeData,
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG));
- }
-
- bool get _hasOptionalArguments {
- return JS(
- 'bool',
- '# in #',
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG),
- _typeData);
- }
-
- List get _optionalArguments {
- return JS('JSExtendableArray', '#[#]', _typeData,
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG));
- }
-
- bool get _hasNamedArguments {
- return JS('bool', '# in #',
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG), _typeData);
- }
-
- get _namedArguments {
- return JS('=Object', '#[#]', _typeData,
- JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG));
- }
-
- bool get isOriginalDeclaration => true;
-
- bool get isAbstract => false;
-
- bool get isEnum => false;
-
- TypeMirror get returnType {
- if (_cachedReturnType != null) return _cachedReturnType;
- if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType;
- if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType;
- return _cachedReturnType =
- typeMirrorFromRuntimeTypeRepresentation(owner, _returnType);
- }
-
- List<ParameterMirror> get parameters {
- if (_cachedParameters != null) return _cachedParameters;
- var result = <ParameterMirror>[];
- int parameterCount = 0;
- if (_hasArguments) {
- for (var type in _arguments) {
- result.add(
- new JsParameterMirror('argument${parameterCount++}', this, type));
- }
- }
- if (_hasOptionalArguments) {
- for (var type in _optionalArguments) {
- result.add(
- new JsParameterMirror('argument${parameterCount++}', this, type));
- }
- }
- if (_hasNamedArguments) {
- for (var name in extractKeys(_namedArguments)) {
- var type = JS('', '#[#]', _namedArguments, name);
- result.add(new JsParameterMirror(name, this, type));
- }
- }
- return _cachedParameters =
- new UnmodifiableListView<ParameterMirror>(result);
- }
-
- bool get hasReflectedType => true;
- Type get reflectedType => _cachedReflectedType ??=
- createRuntimeType(runtimeTypeToString(_typeData));
-
- String _unmangleIfPreserved(String mangled) {
- String result = unmangleGlobalNameIfPreservedAnyways(mangled);
- if (result != null) return result;
- return mangled;
- }
-
- String toString() {
- if (_cachedToString != null) return _cachedToString;
- var s = "FunctionTypeMirror on '(";
- var sep = '';
- if (_hasArguments) {
- for (var argument in _arguments) {
- s += sep;
- s += _unmangleIfPreserved(runtimeTypeToString(argument));
- sep = ', ';
- }
- }
- if (_hasOptionalArguments) {
- s += '$sep[';
- sep = '';
- for (var argument in _optionalArguments) {
- s += sep;
- s += _unmangleIfPreserved(runtimeTypeToString(argument));
- sep = ', ';
- }
- s += ']';
- }
- if (_hasNamedArguments) {
- s += '$sep{';
- sep = '';
- for (var name in extractKeys(_namedArguments)) {
- s += sep;
- s += '$name: ';
- s += _unmangleIfPreserved(
- runtimeTypeToString(JS('', '#[#]', _namedArguments, name)));
- sep = ', ';
- }
- s += '}';
- }
- s += ') -> ';
- if (_isVoid) {
- s += 'void';
- } else if (_hasReturnType) {
- s += _unmangleIfPreserved(runtimeTypeToString(_returnType));
- } else {
- s += 'dynamic';
- }
- return _cachedToString = "$s'";
- }
-
- bool isSubclassOf(ClassMirror other) => false;
-
- bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-
- bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-
- // TODO(ahe): Implement this method.
- MethodMirror get callMethod => throw new UnimplementedError();
-}
-
-int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) {
- for (int i = 0; i < typeVariables.length; i++) {
- if (typeVariables[i].simpleName == s(name)) {
- return i;
- }
- }
- throw new ArgumentError('Type variable not present in list.');
-}
-
-TypeMirror typeMirrorFromRuntimeTypeRepresentation(
- DeclarationMirror owner, var /*int|List|JsFunction|TypeImpl*/ type) {
- // TODO(ahe): This method might benefit from using convertRtiToRuntimeType
- // instead of working on strings.
- if (type == null) {
- return JsMirrorSystem._dynamicType;
- }
-
- ClassMirror ownerClass;
- DeclarationMirror context = owner;
- while (context != null) {
- if (context is ClassMirror) {
- ownerClass = context;
- break;
- }
- // TODO(ahe): Get type parameters and arguments from typedefs.
- if (context is TypedefMirror) break;
- context = context.owner;
- }
-
- String representation;
- if (type is TypeImpl) {
- return reflectType(type);
- } else if (ownerClass == null) {
- representation = runtimeTypeToString(type);
- } else if (ownerClass.isOriginalDeclaration) {
- if (type is num) {
- // [type] represents a type variable so in the context of an original
- // declaration the corresponding type variable should be returned.
- TypeVariable typeVariable = getMetadata(type);
- List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
- int index = findTypeVariableIndex(typeVariables, typeVariable.name);
- return typeVariables[index];
- } else {
- // Nested type variables will be retrieved lazily (the integer
- // representation is kept in the string) so they are not processed here.
- representation = runtimeTypeToString(type);
- }
- } else {
- TypeMirror getTypeArgument(int index) {
- TypeVariable typeVariable = getMetadata(index);
- int variableIndex =
- findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name);
- return ownerClass.typeArguments[variableIndex];
- }
-
- if (type is num) {
- // [type] represents a type variable used as type argument for example
- // the type argument of Bar: class Foo<T> extends Bar<T> {}
- TypeMirror typeArgument = getTypeArgument(type);
- if (typeArgument is JsTypeVariableMirror) return typeArgument;
- }
- String substituteTypeVariable(int index) {
- var typeArgument = getTypeArgument(index);
- if (typeArgument is JsTypeVariableMirror) {
- return '${typeArgument._metadataIndex}';
- }
- if (typeArgument is! JsClassMirror &&
- typeArgument is! JsTypeBoundClassMirror) {
- if (typeArgument == JsMirrorSystem._dynamicType) {
- return 'dynamic';
- } else if (typeArgument == JsMirrorSystem._voidType) {
- return 'void';
- } else {
- // TODO(ahe): This case shouldn't happen.
- return 'dynamic';
- }
- }
- return (typeArgument as dynamic)._mangledName;
- }
-
- representation =
- runtimeTypeToString(type, onTypeVariable: substituteTypeVariable);
- }
- if (representation != null) {
- return reflectClassByMangledName(
- getMangledTypeName(createRuntimeType(representation)));
- }
- String typedefPropertyName = JS_GET_NAME(JsGetName.TYPEDEF_TAG);
- if (JS('', '#[#]', type, typedefPropertyName) != null) {
- return typeMirrorFromRuntimeTypeRepresentation(
- owner, JS('', '#[#]', type, typedefPropertyName));
- } else if (isDartFunctionType(type)) {
- return new JsFunctionTypeMirror(type, owner);
- }
- return reflectClass(Function);
-}
-
-Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
- if (owner == null) return simpleName;
- String ownerName = n(owner.qualifiedName);
- return s('$ownerName.${n(simpleName)}');
-}
-
-List extractMetadata(victim) {
- preserveMetadata();
- var metadataFunction;
- if (JS('bool', 'Object.prototype.hasOwnProperty.call(#, "@")', victim)) {
- metadataFunction = JS('', '#["@"]', victim);
- }
- if (metadataFunction != null) return JS('', '#()', metadataFunction);
- if (JS('bool', 'typeof # != "function"', victim)) return const [];
- if (JS('bool', '# in #', r'$metadataIndex', victim)) {
- return JSArray
- .markFixedList(JS('JSExtendableArray',
- r'#.$reflectionInfo.splice(#.$metadataIndex)', victim, victim))
- .map((i) => getMetadata(i))
- .toList();
- }
- return const [];
-}
-
-void parseCompactFieldSpecification(JsDeclarationMirror owner,
- fieldSpecification, bool isStatic, List<Mirror> result) {
- List fieldsMetadata = null;
- List<String> fields;
- if (fieldSpecification is List) {
- fields = splitFields(fieldSpecification[0], ',');
- fieldsMetadata = fieldSpecification.sublist(1);
- } else if (fieldSpecification is String) {
- fields = splitFields(fieldSpecification, ',');
- } else {
- fields = [];
- }
- int fieldNumber = 0;
- for (String field in fields) {
- if (r'$ti' == field) continue; // Strip type info pseudofield.
- var metadata;
- if (fieldsMetadata != null) {
- metadata = fieldsMetadata[fieldNumber++];
- }
- var mirror = new JsVariableMirror.from(field, metadata, owner, isStatic);
- if (mirror != null) {
- result.add(mirror);
- }
- }
-}
-
-/// Similar to [String.split], but returns an empty list if [string] is empty.
-List<String> splitFields(String string, Pattern pattern) {
- if (string.isEmpty) return <String>[];
- return string.split(pattern);
-}
-
-bool isOperatorName(String name) {
- switch (name) {
- case '==':
- case '[]':
- case '*':
- case '/':
- case '%':
- case '~/':
- case '+':
- case '<<':
- case '>>':
- case '>=':
- case '>':
- case '<=':
- case '<':
- case '&':
- case '^':
- case '|':
- case '-':
- case 'unary-':
- case '[]=':
- case '~':
- return true;
- default:
- return false;
- }
-}
-
-/// Returns true if the key represent ancillary reflection data, that is, not a
-/// method.
-bool isReflectiveDataInPrototype(String key) {
- if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) ||
- key == METHODS_WITH_OPTIONAL_ARGUMENTS) {
- return true;
- }
- String firstChar = key[0];
- return firstChar == '*' || firstChar == '+';
-}
-
-/// Returns `true` if [jsFunction] is an ordinary reflectable method and
-/// not a (potentially reflectable) stub or otherwise non-reflectable method.
-bool isOrdinaryReflectableMethod(var jsFunction) {
- return JS('bool', r'#.$reflectable === 1', jsFunction);
-}
-
-/// Returns true if [key] is only an aliased entry for [function] in the
-/// prototype.
-bool isAliasedSuperMethod(var jsFunction, String key) {
- var stubName = JS('String|Null', r'#.$stubName', jsFunction);
- return stubName != null && key != stubName;
-}
-
-class NoSuchStaticMethodError extends Error implements NoSuchMethodError {
- static const int MISSING_CONSTRUCTOR = 0;
- static const int MISSING_METHOD = 1;
- final ClassMirror _cls;
- final Symbol _name;
- final List _positionalArguments;
- final Map<Symbol, dynamic> _namedArguments;
- final int _kind;
-
- NoSuchStaticMethodError.missingConstructor(
- this._cls, this._name, this._positionalArguments, this._namedArguments)
- : _kind = MISSING_CONSTRUCTOR;
-
- /// If the given class is `null` the static method/getter/setter is top-level.
- NoSuchStaticMethodError.method(
- this._cls, this._name, this._positionalArguments, this._namedArguments)
- : _kind = MISSING_METHOD;
-
- String toString() {
- // TODO(floitsch): show arguments.
- switch (_kind) {
- case MISSING_CONSTRUCTOR:
- return "NoSuchMethodError: No constructor named '${n(_name)}' in class"
- " '${n(_cls.qualifiedName)}'.";
- case MISSING_METHOD:
- if (_cls == null) {
- return "NoSuchMethodError: No top-level method named '${n(_name)}'.";
- }
- return "NoSuchMethodError: No static method named '${n(_name)}' in"
- " class '${n(_cls.qualifiedName)}'";
- default:
- return 'NoSuchMethodError';
- }
- }
-}
-
-Symbol getSymbol(String name, LibraryMirror library) {
- if (_isPublicSymbol(name)) {
- return new _symbol_dev.Symbol.validated(name);
- }
- if (library == null) {
- throw new ArgumentError('Library required for private symbol name: $name');
- }
- if (!_symbol_dev.Symbol.isValidSymbol(name)) {
- throw new ArgumentError('Not a valid symbol name: $name');
- }
- throw new UnimplementedError(
- 'MirrorSystem.getSymbol not implemented for private names');
-}
-
-bool _isPublicSymbol(String name) {
- // A symbol is public if it doesn't start with '_' and it doesn't
- // have a part (following a '.') that starts with '_'.
- const int UNDERSCORE = 0x5f;
- if (name.isEmpty) return true;
- int index = -1;
- do {
- if (name.codeUnitAt(index + 1) == UNDERSCORE) return false;
- index = name.indexOf('.', index + 1);
- } while (index >= 0 && index + 1 < name.length);
- return true;
-}
diff --git a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
index 341ce90..46f945b 100644
--- a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
+++ b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -98,12 +98,12 @@
var strings = _strings;
if (strings == null) return null;
LinkedHashMapCell cell = _getTableCell(strings, key);
- return (cell == null) ? null : cell.hashMapCellValue;
+ return JS('', '#', cell == null ? null : cell.hashMapCellValue);
} else if (_isNumericKey(key)) {
var nums = _nums;
if (nums == null) return null;
LinkedHashMapCell cell = _getTableCell(nums, key);
- return (cell == null) ? null : cell.hashMapCellValue;
+ return JS('', '#', cell == null ? null : cell.hashMapCellValue);
} else {
return internalGet(key);
}
@@ -116,7 +116,7 @@
int index = internalFindBucketIndex(bucket, key);
if (index < 0) return null;
LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
- return cell.hashMapCellValue;
+ return JS('', '#', cell.hashMapCellValue);
}
void operator []=(K key, V value) {
@@ -182,7 +182,7 @@
_unlinkCell(cell);
// TODO(kasperl): Consider getting rid of the bucket list when
// the length reaches zero.
- return cell.hashMapCellValue;
+ return JS('', '#', cell.hashMapCellValue);
}
void clear() {
@@ -197,7 +197,9 @@
LinkedHashMapCell cell = _first;
int modifications = _modifications;
while (cell != null) {
- action(cell.hashMapCellKey, cell.hashMapCellValue);
+ K key = JS('', '#', cell.hashMapCellKey);
+ V value = JS('', '#', cell.hashMapCellValue);
+ action(key, value);
if (modifications != _modifications) {
throw new ConcurrentModificationError(this);
}
@@ -220,7 +222,7 @@
if (cell == null) return null;
_unlinkCell(cell);
_deleteTableEntry(table, key);
- return cell.hashMapCellValue;
+ return JS('', '#', cell.hashMapCellValue);
}
void _modified() {
@@ -398,7 +400,7 @@
LinkedHashMapCell cell = _map._first;
int modifications = _map._modifications;
while (cell != null) {
- f(cell.hashMapCellKey);
+ f(JS('', '#', cell.hashMapCellKey));
if (modifications != _map._modifications) {
throw new ConcurrentModificationError(_map);
}
@@ -426,7 +428,7 @@
_current = null;
return false;
} else {
- _current = _cell.hashMapCellKey;
+ _current = JS('', '#', _cell.hashMapCellKey);
_cell = _cell._next;
return true;
}
diff --git a/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart b/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
deleted file mode 100644
index f23a07e..0000000
--- a/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Patch library for dart:mirrors.
-
-import 'dart:_js_helper' show patch;
-import 'dart:_js_mirrors' as js;
-
-@patch
-class MirrorSystem {
- @patch
- LibraryMirror findLibrary(Symbol libraryName) {
- return libraries.values
- .singleWhere((library) => library.simpleName == libraryName);
- }
-
- @patch
- static String getName(Symbol symbol) => js.getName(symbol);
-
- @patch
- static Symbol getSymbol(String name, [LibraryMirror library]) {
- return js.getSymbol(name, library);
- }
-}
-
-@patch
-MirrorSystem currentMirrorSystem() => js.currentJsMirrorSystem;
-
-@patch
-InstanceMirror reflect(Object reflectee) => js.reflect(reflectee);
-
-@patch
-ClassMirror reflectClass(Type key) {
- if (key is! Type || key == dynamic) {
- throw new ArgumentError('$key does not denote a class');
- }
- TypeMirror tm = reflectType(key);
- if (tm is! ClassMirror) {
- throw new ArgumentError("$key does not denote a class");
- }
- return (tm as ClassMirror).originalDeclaration;
-}
-
-@patch
-TypeMirror reflectType(Type key, [List<Type> typeArguments]) {
- if (key == dynamic) {
- return currentMirrorSystem().dynamicType;
- }
- return js.reflectType(key, typeArguments);
-}
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index c2ba34e..5e1c046 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -106,7 +106,7 @@
"mirrors": const LibraryInfo("mirrors/mirrors.dart",
categories: "Client,Server",
maturity: Maturity.UNSTABLE,
- dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch.dart"),
+ dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch_cfe.dart"),
"nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
categories: "Client",
implementation: true,
@@ -157,13 +157,6 @@
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
- "_isolate_helper": const LibraryInfo(
- "_internal/js_runtime/lib/isolate_helper.dart",
- categories: "",
- documented: false,
- platforms: DART2JS_PLATFORM),
- "_js_mirrors": const LibraryInfo("_internal/js_runtime/lib/js_mirrors.dart",
- categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_js_names": const LibraryInfo("_internal/js_runtime/lib/js_names.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_js_primitives": const LibraryInfo(
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index 210d6be..ba2321e 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -430,13 +430,6 @@
* Error thrown by the default implementation of [:noSuchMethod:] on [Object].
*/
class NoSuchMethodError extends Error {
- // Deprecated members to be removed.
- final Object _receiver;
- final Symbol _memberName;
- final List _arguments;
- final Map<Symbol, dynamic> _namedArguments;
- final List _existingArgumentNames;
-
/**
* Create a [NoSuchMethodError] corresponding to a failed method call.
*
@@ -446,7 +439,6 @@
* The [invocation] represents the method call that failed. It
* should not be `null`.
*/
- @Deprecated("Dart 2.0. Will be renamed to become default constructor")
external NoSuchMethodError.withInvocation(
Object receiver, Invocation invocation);
@@ -469,14 +461,14 @@
* The [namedArguments] is a map from [Symbol]s to the values of named
* arguments that the method was called with.
*
- * The optional [existingArgumentNames] is the expected parameters of a
- * method with the same name on the receiver, if available. This is
- * the signature of the method that would have been called if the parameters
- * had matched.
+ * This constructor does not handle type arguments.
+ * To include type variables, create an [Invocation] and use
+ * [NoSuchMethodError.withInvocation].
*/
+ @Deprecated("Use NoSuchMethod.withInvocation instead")
external NoSuchMethodError(Object receiver, Symbol memberName,
List positionalArguments, Map<Symbol, dynamic> namedArguments,
- [List existingArgumentNames = null]);
+ [@deprecated List existingArgumentNames = null]);
external String toString();
}
diff --git a/sdk/lib/dart_client.platform b/sdk/lib/dart_client.platform
index 0228d99..805ac5c 100644
--- a/sdk/lib/dart_client.platform
+++ b/sdk/lib/dart_client.platform
@@ -47,8 +47,6 @@
_js_helper: _internal/js_runtime/lib/js_helper.dart
_interceptors: _internal/js_runtime/lib/interceptors.dart
_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
-_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
-_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
_js_names: _internal/js_runtime/lib/js_names.dart
_js_primitives: _internal/js_runtime/lib/js_primitives.dart
_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/dart_server.platform b/sdk/lib/dart_server.platform
index f1f2d3b..290e1ef 100644
--- a/sdk/lib/dart_server.platform
+++ b/sdk/lib/dart_server.platform
@@ -44,8 +44,6 @@
_js_helper: _internal/js_runtime/lib/js_helper.dart
_interceptors: _internal/js_runtime/lib/interceptors.dart
_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
-_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
-_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
_js_names: _internal/js_runtime/lib/js_names.dart
_js_primitives: _internal/js_runtime/lib/js_primitives.dart
_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/dart_shared.platform b/sdk/lib/dart_shared.platform
index 922fb98..e8aa11c 100644
--- a/sdk/lib/dart_shared.platform
+++ b/sdk/lib/dart_shared.platform
@@ -41,8 +41,6 @@
_js_helper: _internal/js_runtime/lib/js_helper.dart
_interceptors: _internal/js_runtime/lib/interceptors.dart
_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
-_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
-_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
_js_names: _internal/js_runtime/lib/js_names.dart
_js_primitives: _internal/js_runtime/lib/js_primitives.dart
_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 9f2711b..52e41d5 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -342,6 +342,15 @@
abstract class X509Certificate {
external factory X509Certificate._();
+ /// The DER encoded bytes of the certificate.
+ Uint8List get der;
+
+ /// The PEM encoded String of the certificate.
+ String get pem;
+
+ /// The SHA1 hash of the certificate.
+ Uint8List get sha1;
+
String get subject;
String get issuer;
DateTime get startValidity;
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 496c820..7a677b0 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -271,10 +271,13 @@
* before those methods can complete.
*
* If the [checked] parameter is set to `true` or `false`,
- * the new isolate will run code in checked mode,
- * respectively in production mode, if possible.
- * If the parameter is omitted, the new isolate will inherit the
- * value from the current isolate.
+ * the new isolate will run code in checked mode (enabling asserts and type
+ * checks), respectively in production mode (disabling asserts and type
+ * checks), if possible. If the parameter is omitted, the new isolate will
+ * inherit the value from the current isolate.
+ *
+ * In Dart2 strong mode, the `checked` parameter only controls asserts, but
+ * not type checks.
*
* It may not always be possible to honor the `checked` parameter.
* If the isolate code was pre-compiled, it may not be possible to change
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index b1fe827..9f3f684 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -189,9 +189,6 @@
"_chrome": {
"uri": "_chrome/dart2js/chrome_dart2js.dart"
},
- "_js_mirrors": {
- "uri": "_internal/js_runtime/lib/js_mirrors.dart"
- },
"js": {
"uri": "js/dart2js/js_dart2js.dart"
},
@@ -248,9 +245,6 @@
"patches": "_internal/js_runtime/lib/convert_patch.dart",
"uri": "convert/convert.dart"
},
- "_isolate_helper": {
- "uri": "_internal/js_runtime/lib/isolate_helper.dart"
- },
"math": {
"patches": "_internal/js_runtime/lib/math_patch.dart",
"uri": "math/math.dart"
@@ -307,9 +301,6 @@
"js": {
"uri": "js/dart2js/js_dart2js.dart"
},
- "_js_mirrors": {
- "uri": "_internal/js_runtime/lib/js_mirrors.dart"
- },
"_native_typed_data": {
"uri": "_internal/js_runtime/lib/native_typed_data.dart"
},
@@ -348,9 +339,6 @@
"patches": "_internal/js_runtime/lib/convert_patch.dart",
"uri": "convert/convert.dart"
},
- "_isolate_helper": {
- "uri": "_internal/js_runtime/lib/isolate_helper.dart"
- },
"math": {
"patches": "_internal/js_runtime/lib/math_patch.dart",
"uri": "math/math.dart"
@@ -360,4 +348,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index eb7ae2e..92c2391 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -242,12 +242,6 @@
_foreign_helper:
uri: "_internal/js_runtime/lib/foreign_helper.dart"
- _isolate_helper:
- uri: "_internal/js_runtime/lib/isolate_helper.dart"
-
- _js_mirrors:
- uri: "_internal/js_runtime/lib/js_mirrors.dart"
-
_js_names:
uri: "_internal/js_runtime/lib/js_names.dart"
@@ -337,12 +331,6 @@
_foreign_helper:
uri: "_internal/js_runtime/lib/foreign_helper.dart"
- _isolate_helper:
- uri: "_internal/js_runtime/lib/isolate_helper.dart"
-
- _js_mirrors:
- uri: "_internal/js_runtime/lib/js_mirrors.dart"
-
_js_names:
uri: "_internal/js_runtime/lib/js_names.dart"
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 0811fdb..bbbb7b9 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -1241,6 +1241,7 @@
* will ensure that the target `Bar` from the current library and from library
* `foo` is available for reflection. See also [override].
*/
+@Deprecated("No longer has any effect. Will be removed in a later release.")
class MirrorsUsed {
// Note: the fields of this class are untyped. This is because the most
// convenient way to specify symbols today is using a single string. In
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index d802885..d758bc1 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -1466,6 +1466,7 @@
LibTest/typed_data/Uint8ClampedList/map_A02_t01: Pass, Slow # Please triage this failure.
[ $compiler == dart2js && $runtime == d8 ]
+Language/Statements/Continue/async_loops_t10: Skip # Issue 33150
LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: Fail # co19-roll r587: Please triage this failure
LibTest/typed_data/Int32x4/operator_OR_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
diff --git a/tests/compiler/dart2js/codegen/expect_annotations_test.dart b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
index bff2af5..e5d0770f 100644
--- a/tests/compiler/dart2js/codegen/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
@@ -7,6 +7,7 @@
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints;
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/types/types.dart';
import 'package:compiler/src/world.dart' show ClosedWorld;
import '../inference/type_mask_test_helper.dart';
diff --git a/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
index 4e8b777..615226b 100644
--- a/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
@@ -6,7 +6,7 @@
import "package:async_helper/async_helper.dart";
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart';
-import '../compiler_helper.dart';
+import 'package:compiler/src/types/masks.dart';
import '../memory_compiler.dart';
const String TEST = """
diff --git a/tests/compiler/dart2js/codegen/type_inference8_test.dart b/tests/compiler/dart2js/codegen/type_inference8_test.dart
index 502aa96..7940d5e 100644
--- a/tests/compiler/dart2js/codegen/type_inference8_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference8_test.dart
@@ -7,7 +7,7 @@
import "package:async_helper/async_helper.dart";
import "package:compiler/src/commandline_options.dart";
import "package:compiler/src/constants/values.dart";
-import "package:compiler/src/types/types.dart";
+import "package:compiler/src/types/masks.dart";
import "package:expect/expect.dart";
import '../memory_compiler.dart';
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index f1505be..50d9225 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -11,9 +11,7 @@
import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
-export 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/js_backend/js_backend.dart' as js;
@@ -23,8 +21,6 @@
export 'package:compiler/src/diagnostics/source_span.dart';
export 'package:compiler/src/diagnostics/spannable.dart';
-export 'package:compiler/src/types/types.dart' show TypeMask;
-
import 'package:compiler/src/util/util.dart';
export 'package:compiler/src/util/util.dart';
@@ -32,8 +28,6 @@
import 'package:compiler/src/compiler.dart' show Compiler;
-export 'package:compiler/src/tree/tree.dart';
-
import 'memory_compiler.dart';
import 'output_collector.dart';
@@ -129,17 +123,6 @@
return outputCollector.getOutput('', OutputType.js);
}
-Element findElement(compiler, String name, [Uri library]) {
- LibraryElement lib = compiler.frontendStrategy.elementEnvironment.mainLibrary;
- if (library != null) {
- lib = compiler.libraryLoader.lookupLibrary(library);
- Expect.isNotNull(lib, 'Could not locate library $library.');
- }
- var element = lib.find(name);
- Expect.isNotNull(element, 'Could not locate $name.');
- return element;
-}
-
String anyIdentifier = "[a-zA-Z][a-zA-Z0-9]*";
String getIntTypeCheck(String variable) {
diff --git a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
index b7d44ab..2c0951c 100644
--- a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
@@ -4,6 +4,6 @@
import '../libs/basic_deferred_lib.dart' deferred as lib;
/*element: main:OutputUnit(main, {})*/
-main() => lib.loadLibrary().then((_) {
+main() => lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
(lib.funky)();
});
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
index 0ded6cf..b688215 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
@@ -6,7 +6,7 @@
/*element: main:OutputUnit(main, {})*/
main() {
- lib.loadLibrary().then((_) {
+ lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
return new lib.MyClass().foo(87);
});
}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
index b3d820a..99f8444 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
@@ -9,7 +9,7 @@
main() async {
C1.value;
print(const C(4));
- () => print(const C(5));
+ /*OutputUnit(main, {})*/ () => print(const C(5));
await lib2.loadLibrary();
lib2.C2.value;
lib2.C3.value;
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
index 9f82270..f8821ae 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
@@ -8,7 +8,7 @@
/*element: main:OutputUnit(main, {})*/
main() {
- lib.loadLibrary().then((_) {
+ lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
Expect.equals(499, lib.C1.value);
});
}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
index 819032b..80b59bf 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
@@ -34,14 +34,14 @@
]);
asyncStart();
- lib.loadLibrary().then((_) {
+ lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
Expect.fail("Library should not have loaded");
- }, onError: (error) {
- lib.loadLibrary().then((_) {
+ }, onError: /*OutputUnit(main, {})*/ (error) {
+ lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
Expect.equals("loaded", lib.foo());
- }, onError: (error) {
+ }, onError: /*OutputUnit(main, {})*/ (error) {
Expect.fail("Library should have loaded this time");
- }).whenComplete(() {
+ }).whenComplete(/*OutputUnit(main, {})*/ () {
asyncEnd();
});
});
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
index d8895f7..6f809df 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
@@ -14,7 +14,7 @@
/*element: main:OutputUnit(main, {})*/
main() {
- lib.loadLibrary().then((_) {
+ lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
lib.foo('b');
readFoo();
});
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
index ea2354b..754ee48 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
@@ -8,9 +8,9 @@
// lib1.C1 and lib2.C2 has a shared base class. It will go in its own hunk.
/*element: main:OutputUnit(main, {})*/
void main() {
- lib1.loadLibrary().then((_) {
+ lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
new lib1.C1();
- lib2.loadLibrary().then((_) {
+ lib2.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
new lib2.C2();
});
});
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
index 58669a5..3e42dd2 100644
--- a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
@@ -6,7 +6,7 @@
/*element: main:OutputUnit(main, {})*/
void main() {
- lib.loadLibrary().then((_) {
+ lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
print(lib.finalVar);
print(lib.globalVar);
lib.globalVar = "foobar";
diff --git a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
new file mode 100644
index 0000000..ac5b27d
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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 class lib1.C is referenced via lib1
+// The static function lib1.C.foo is referenced via lib2
+// Dart2js will put them in separate hunks.
+// Similarly for C2, ..., C5.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "../libs/static_separate_lib1.dart" deferred as lib1;
+import "../libs/static_separate_lib2.dart" deferred as lib2;
+
+/*element: main:OutputUnit(main, {})*/
+void main() {
+ asyncStart();
+ Expect.throws(/*OutputUnit(main, {})*/ () => new lib1.C());
+ lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
+ lib2.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
+ print("HERE");
+ Expect.equals(1, new lib1.C().bar());
+ var x = new lib1.C2();
+ Expect.mapEquals({1: 2}, x.bar);
+ x.bar = {2: 3};
+ Expect.mapEquals({2: 3}, x.bar);
+
+ Expect.equals(lib1.x, new lib1.C3().bar);
+ Expect.mapEquals({lib1.x: lib1.x}, new lib1.C4().bar);
+ Expect.equals(1, new lib1.C5().bar());
+
+ lib2.foo();
+ asyncEnd();
+ });
+ });
+}
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index 8abed7c..cef5d1b 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -4,6 +4,7 @@
import 'dart:io' hide Link;
import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/closure.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/deferred_load.dart';
@@ -87,44 +88,73 @@
void computeKernelOutputUnitData(
Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
{bool verbose: false}) {
- OutputUnitData data = compiler.backend.outputUnitData;
- String value = outputUnitString(data.outputUnitForEntity(member));
-
KernelBackendStrategy backendStrategy = compiler.backendStrategy;
KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
MemberDefinition definition = elementMap.getMemberDefinition(member);
+ new TypeMaskIrComputer(
+ compiler.reporter,
+ actualMap,
+ elementMap,
+ member,
+ compiler.backend.outputUnitData,
+ backendStrategy.closureDataLookup as ClosureDataLookup<ir.Node>)
+ .run(definition.node);
+}
- _registerValue(
- computeEntityId(definition.node),
- value,
- member,
- computeSourceSpanFromTreeNode(definition.node),
- actualMap,
- compiler.reporter);
+/// IR visitor for computing inference data for a member.
+class TypeMaskIrComputer extends IrDataExtractor {
+ final KernelToElementMapForBuilding _elementMap;
+ final OutputUnitData _data;
+ final ClosureDataLookup<ir.Node> _closureDataLookup;
- ir.Member memberNode = definition.node;
- if (memberNode is ir.Field && memberNode.isConst) {
- ir.Expression node = memberNode.initializer;
- ConstantValue constant = elementMap.getConstantValue(node);
- if (constant.isPrimitive) return;
- SourceSpan span = computeSourceSpanFromTreeNode(node);
- if (node is ir.ConstructorInvocation ||
- node is ir.ListLiteral ||
- (node is ir.MapLiteral && node.keyType == null)) {
- // Adjust the source-span to match the AST-based location. The kernel FE
- // skips the "const" keyword for the expression offset and any prefix in
- // front of the constructor. The "-6" is an approximation assuming that
- // there is just a single space after "const" and no prefix.
- // TODO(sigmund): offsets should be fixed in the FE instead.
- span = new SourceSpan(span.uri, span.begin - 6, span.end - 6);
+ TypeMaskIrComputer(
+ DiagnosticReporter reporter,
+ Map<Id, ActualData> actualMap,
+ this._elementMap,
+ MemberEntity member,
+ this._data,
+ this._closureDataLookup)
+ : super(reporter, actualMap);
+
+ String getMemberValue(MemberEntity member) {
+ return outputUnitString(_data.outputUnitForEntity(member));
+ }
+
+ @override
+ String computeMemberValue(Id id, ir.Member node) {
+ if (node is ir.Field && node.isConst) {
+ ir.Expression initializer = node.initializer;
+ ConstantValue constant = _elementMap.getConstantValue(initializer);
+ if (!constant.isPrimitive) {
+ SourceSpan span = computeSourceSpanFromTreeNode(initializer);
+ if (initializer is ir.ConstructorInvocation) {
+ // Adjust the source-span to match the AST-based location. The kernel FE
+ // skips the "const" keyword for the expression offset and any prefix in
+ // front of the constructor. The "-6" is an approximation assuming that
+ // there is just a single space after "const" and no prefix.
+ // TODO(sigmund): offsets should be fixed in the FE instead.
+ span = new SourceSpan(span.uri, span.begin - 6, span.end - 6);
+ }
+ _registerValue(
+ new NodeId(span.begin, IdKind.node),
+ outputUnitString(_data.outputUnitForConstant(constant)),
+ node,
+ span,
+ actualMap,
+ reporter);
+ }
}
- _registerValue(
- new NodeId(span.begin, IdKind.node),
- outputUnitString(data.outputUnitForConstant(constant)),
- member,
- span,
- actualMap,
- compiler.reporter);
+
+ return getMemberValue(_elementMap.getMember(node));
+ }
+
+ @override
+ String computeNodeValue(Id id, ir.TreeNode node) {
+ if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
+ ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
+ return getMemberValue(info.callMethod);
+ }
+ return null;
}
}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
index 494a35d..a8f56bd 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
@@ -22,8 +22,8 @@
/*element: main:OutputUnit(main, {})*/
void main() {
- lib1.loadLibrary().then((_) {
- lib2.loadLibrary().then((_) {
+ lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
+ lib2.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
lib1.foo();
lib2.foo();
print(lib1.C1);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
new file mode 100644
index 0000000..d95536e
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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 lib1;
+
+/*class: ConstClass:OutputUnit(2, {lib1, lib2})*/
+class ConstClass {
+ /*element: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
+ final x;
+
+ /*element: ConstClass.:OutputUnit(2, {lib1, lib2})*/
+ const ConstClass(this.x);
+}
+
+/*element: x:OutputUnit(2, {lib1, lib2})*/
+var x = const ConstClass(const ConstClass(1));
+
+/*class: C:OutputUnit(1, {lib1})*/
+class C {
+ /*element: C.foo:OutputUnit(3, {lib2})*/
+ static foo() {
+ /*OutputUnit(3, {lib2})*/ () {}(); // Hack to avoid inlining.
+ return 1;
+ }
+
+ /*element: C.:OutputUnit(1, {lib1})*/
+ C();
+
+ /*element: C.bar:OutputUnit(1, {lib1})*/
+ bar() {
+ /*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
+ return 1;
+ }
+}
+
+/*class: C1:OutputUnit(main, {})*/
+class C1 {
+ /*element: C1.foo:OutputUnit(3, {lib2})*/
+ static var foo = const {};
+ var bar = const {};
+}
+
+/*class: C2:OutputUnit(1, {lib1})*/
+class C2 {
+ /*element: C2.foo:OutputUnit(3, {lib2})*/
+ static var foo = new Map<int, int>.from({1: 2});
+
+ /*element: C2.bar:OutputUnit(1, {lib1})*/
+ var bar = new Map<int, int>.from({1: 2});
+
+ /*element: C2.:OutputUnit(1, {lib1})*/
+ C2();
+}
+
+/*class: C3:OutputUnit(1, {lib1})*/
+class C3 {
+ /*element: C3.foo:OutputUnit(3, {lib2})*/
+ static final foo = const ConstClass(const ConstClass(1));
+
+ /*element: C3.bar:OutputUnit(1, {lib1})*/
+ final bar = const ConstClass(const ConstClass(1));
+
+ /*element: C3.:OutputUnit(1, {lib1})*/
+ C3();
+}
+
+/*class: C4:OutputUnit(1, {lib1})*/
+class C4 {
+ /*element: C4.foo:OutputUnit(3, {lib2})*/
+ static final foo = new Map<ConstClass, ConstClass>.from({x: x});
+
+ /*element: C4.bar:OutputUnit(1, {lib1})*/
+ final bar = new Map<ConstClass, ConstClass>.from({x: x});
+
+ /*element: C4.:OutputUnit(1, {lib1})*/
+ C4();
+}
+
+/*class: C5:OutputUnit(1, {lib1})*/
+class C5 {
+ /*element: C5.foo:OutputUnit(3, {lib2})*/
+ static const foo = /*OutputUnit(3, {lib2})*/ const [
+ const {1: 3}
+ ];
+
+ /*element: C5.:OutputUnit(1, {lib1})*/
+ C5();
+
+ /*element: C5.bar:OutputUnit(1, {lib1})*/
+ bar() {
+ /*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
+ return 1;
+ }
+}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
new file mode 100644
index 0000000..4358474
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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 lib2;
+
+import "package:expect/expect.dart";
+import "static_separate_lib1.dart";
+
+/*element: foo:OutputUnit(3, {lib2})*/
+foo() {
+ Expect.equals(1, C.foo());
+ Expect.mapEquals({}, C1.foo);
+
+ Expect.mapEquals({1: 2}, C2.foo);
+ C2.foo = {1: 2};
+ Expect.mapEquals({1: 2}, C2.foo);
+
+ Expect.equals(x, C3.foo);
+ Expect.mapEquals({x: x}, C4.foo);
+ Expect.listEquals([
+ const {1: 3}
+ ], C5.foo);
+}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
index 37095d3..d785ac6 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
@@ -5,4 +5,4 @@
import 'type_argument_dependency_lib2.dart';
/*element: doCast:OutputUnit(main, {})*/
-doCast(List<dynamic> l) => l.cast<B>().map((x) => 1);
+doCast(List<dynamic> l) => l.cast<B>().map(/*OutputUnit(main, {})*/ (x) => 1);
diff --git a/tests/compiler/dart2js/dill_loader_test.dart b/tests/compiler/dart2js/dill_loader_test.dart
index 4192756..e1fd6b1 100644
--- a/tests/compiler/dart2js/dill_loader_test.dart
+++ b/tests/compiler/dart2js/dill_loader_test.dart
@@ -2,16 +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.
-import 'dart:async';
import 'memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/diagnostics/spannable.dart' show Spannable;
import 'package:compiler/src/elements/entities.dart'
show LibraryEntity, ClassEntity;
-import 'package:compiler/src/io/source_file.dart' show Binary;
-import 'package:compiler/src/library_loader.dart' show ScriptLoader;
-import 'package:compiler/src/script.dart' show Script;
import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
import "package:expect/expect.dart";
import 'package:front_end/src/api_prototype/front_end.dart';
@@ -21,17 +16,6 @@
import 'package:front_end/src/compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
-class TestScriptLoader implements ScriptLoader {
- CompilerImpl compiler;
- TestScriptLoader(this.compiler);
-
- Future<Script> readScript(Uri uri, [Spannable spannable]) =>
- compiler.readScript(uri, spannable);
-
- Future<Binary> readBinary(Uri uri, [Spannable spannable]) =>
- compiler.readBinary(uri, spannable);
-}
-
/// Test that the compiler can successfully read in .dill kernel files rather
/// than just string source files.
main() {
diff --git a/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart b/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart
index 7a3c4c7..a04734f 100644
--- a/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart
+++ b/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart
@@ -10,7 +10,6 @@
import 'package:compiler/src/diagnostics/spannable.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/options.dart';
-import 'package:front_end/src/fasta/scanner.dart';
abstract class DiagnosticReporterWrapper extends DiagnosticReporter {
DiagnosticReporter get reporter;
@@ -64,9 +63,6 @@
}
@override
- SourceSpan spanFromToken(Token token) => reporter.spanFromToken(token);
-
- @override
withCurrentElement(Entity element, f()) {
return reporter.withCurrentElement(element, f);
}
diff --git a/tests/compiler/dart2js/equivalence/check_functions.dart b/tests/compiler/dart2js/equivalence/check_functions.dart
index 1a0222c..149894a 100644
--- a/tests/compiler/dart2js/equivalence/check_functions.dart
+++ b/tests/compiler/dart2js/equivalence/check_functions.dart
@@ -6,1248 +6,8 @@
library dart2js.equivalence.functions;
-import 'package:expect/expect.dart';
-import 'package:compiler/src/common/resolution.dart';
-import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/enqueue.dart';
import 'package:compiler/src/js/js_debug.dart' as js;
-import 'package:compiler/src/js_backend/backend.dart';
-import 'package:compiler/src/js_backend/backend_usage.dart';
-import 'package:compiler/src/js_backend/enqueuer.dart';
-import 'package:compiler/src/js_backend/native_data.dart';
-import 'package:compiler/src/js_backend/interceptor_data.dart';
-import 'package:compiler/src/js_emitter/code_emitter_task.dart';
-import 'package:compiler/src/js_emitter/model.dart';
-import 'package:compiler/src/universe/class_set.dart';
-import 'package:compiler/src/universe/world_builder.dart';
-import 'package:compiler/src/world.dart';
import 'package:js_ast/js_ast.dart' as js;
-import 'equivalence_helper.dart';
-import 'check_helpers.dart';
-
-void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
- {TestStrategy strategy: const TestStrategy(),
- bool allowExtra: false,
- bool verbose: false,
- bool allowMissingClosureClasses: false}) {
- if (verbose) {
- print(closedWorld1.dump());
- print(closedWorld2.dump());
- }
- checkClassHierarchyNodes(
- closedWorld1,
- closedWorld2,
- closedWorld1
- .getClassHierarchyNode(closedWorld1.commonElements.objectClass),
- closedWorld2
- .getClassHierarchyNode(closedWorld2.commonElements.objectClass),
- strategy.elementEquivalence,
- verbose: verbose,
- allowMissingClosureClasses: allowMissingClosureClasses);
-
- checkNativeData(closedWorld1.nativeData, closedWorld2.nativeData,
- strategy: strategy, allowExtra: allowExtra, verbose: verbose);
- checkInterceptorData(closedWorld1.interceptorData,
- closedWorld2.interceptorData, strategy.elementEquivalence,
- verbose: verbose);
-}
-
-void checkNativeData(NativeDataImpl data1, NativeDataImpl data2,
- {TestStrategy strategy: const TestStrategy(),
- bool allowExtra: false,
- bool verbose: false}) {
- checkMapEquivalence(data1, data2, 'nativeMemberName', data1.nativeMemberName,
- data2.nativeMemberName, strategy.elementEquivalence, equality,
- allowExtra: allowExtra);
-
- checkMapEquivalence(
- data1,
- data2,
- 'nativeMethodBehavior',
- data1.nativeMethodBehavior,
- data2.nativeMethodBehavior,
- strategy.elementEquivalence,
- (a, b) => testNativeBehavior(a, b, strategy: strategy),
- allowExtra: allowExtra);
-
- checkMapEquivalence(
- data1,
- data2,
- 'nativeFieldLoadBehavior',
- data1.nativeFieldLoadBehavior,
- data2.nativeFieldLoadBehavior,
- strategy.elementEquivalence,
- (a, b) => testNativeBehavior(a, b, strategy: strategy),
- allowExtra: allowExtra);
-
- checkMapEquivalence(
- data1,
- data2,
- 'nativeFieldStoreBehavior',
- data1.nativeFieldStoreBehavior,
- data2.nativeFieldStoreBehavior,
- strategy.elementEquivalence,
- (a, b) => testNativeBehavior(a, b, strategy: strategy),
- allowExtra: allowExtra);
-
- checkMapEquivalence(
- data1,
- data2,
- 'jsInteropLibraryNames',
- data1.jsInteropLibraries,
- data2.jsInteropLibraries,
- strategy.elementEquivalence,
- equality);
-
- checkSetEquivalence(
- data1,
- data2,
- 'anonymousJsInteropClasses',
- data1.anonymousJsInteropClasses,
- data2.anonymousJsInteropClasses,
- strategy.elementEquivalence);
-
- checkMapEquivalence(
- data1,
- data2,
- 'jsInteropClassNames',
- data1.jsInteropClasses,
- data2.jsInteropClasses,
- strategy.elementEquivalence,
- equality);
-
- checkMapEquivalence(
- data1,
- data2,
- 'jsInteropMemberNames',
- data1.jsInteropMembers,
- data2.jsInteropMembers,
- strategy.elementEquivalence,
- equality);
-}
-
-void checkInterceptorData(InterceptorDataImpl data1, InterceptorDataImpl data2,
- bool elementEquivalence(Entity a, Entity b),
- {bool verbose: false}) {
- checkMapEquivalence(
- data1,
- data2,
- 'interceptedElements',
- data1.interceptedMembers,
- data2.interceptedMembers,
- equality,
- (a, b) => areSetsEquivalent(a, b, elementEquivalence));
-
- checkSetEquivalence(data1, data2, 'interceptedClasses',
- data1.interceptedClasses, data2.interceptedClasses, elementEquivalence);
-
- checkSetEquivalence(
- data1,
- data2,
- 'classesMixedIntoInterceptedClasses',
- data1.classesMixedIntoInterceptedClasses,
- data2.classesMixedIntoInterceptedClasses,
- elementEquivalence);
-}
-
-void checkClassHierarchyNodes(
- ClosedWorld closedWorld1,
- ClosedWorld closedWorld2,
- ClassHierarchyNode node1,
- ClassHierarchyNode node2,
- bool elementEquivalence(Entity a, Entity b),
- {bool verbose: false,
- bool allowMissingClosureClasses: false}) {
- if (verbose) {
- print('Checking $node1 vs $node2');
- }
- ClassEntity cls1 = node1.cls;
- ClassEntity cls2 = node2.cls;
- Expect.isTrue(elementEquivalence(cls1, cls2),
- "Element identity mismatch for ${cls1} vs ${cls2}.");
- Expect.equals(
- node1.isDirectlyInstantiated,
- node2.isDirectlyInstantiated,
- "Value mismatch for 'isDirectlyInstantiated' "
- "for ${cls1} vs ${cls2}.");
- Expect.equals(
- node1.isIndirectlyInstantiated,
- node2.isIndirectlyInstantiated,
- "Value mismatch for 'isIndirectlyInstantiated' "
- "for ${node1.cls} vs ${node2.cls}.");
- // TODO(johnniwinther): Enforce a canonical and stable order on direct
- // subclasses.
- for (ClassHierarchyNode child in node1.directSubclasses) {
- bool found = false;
- for (ClassHierarchyNode other in node2.directSubclasses) {
- ClassEntity child1 = child.cls;
- ClassEntity child2 = other.cls;
- if (elementEquivalence(child1, child2)) {
- checkClassHierarchyNodes(
- closedWorld1, closedWorld2, child, other, elementEquivalence,
- verbose: verbose,
- allowMissingClosureClasses: allowMissingClosureClasses);
- found = true;
- break;
- }
- }
- if (!found && (!child.cls.isClosure || !allowMissingClosureClasses)) {
- if (child.isInstantiated) {
- print('Missing subclass ${child.cls} of ${node1.cls} '
- 'in ${node2.directSubclasses}');
- print(closedWorld1.dump(
- verbose ? closedWorld1.commonElements.objectClass : node1.cls));
- print(closedWorld2.dump(
- verbose ? closedWorld2.commonElements.objectClass : node2.cls));
- }
- Expect.isFalse(
- child.isInstantiated,
- 'Missing subclass ${child.cls} of ${node1.cls} in '
- '${node2.directSubclasses}');
- }
- }
- checkMixinUses(
- closedWorld1, closedWorld2, node1.cls, node2.cls, elementEquivalence,
- verbose: verbose);
- ClassSet classSet1 = closedWorld1.getClassSet(cls1);
- ClassSet classSet2 = closedWorld2.getClassSet(cls2);
- Expect.isNotNull(classSet1, "Missing ClassSet for $cls1");
- Expect.isNotNull(classSet2, "Missing ClassSet for $cls2");
- checkClassSets(
- closedWorld1, closedWorld2, classSet1, classSet2, elementEquivalence,
- verbose: verbose, allowMissingClosureClasses: allowMissingClosureClasses);
-}
-
-void checkClassSets(
- ClosedWorld closedWorld1,
- ClosedWorld closedWorld2,
- ClassSet classSet1,
- ClassSet classSet2,
- bool elementEquivalence(Entity a, Entity b),
- {bool verbose: false,
- bool allowMissingClosureClasses: false}) {
- for (ClassHierarchyNode child in classSet1.subtypeNodes) {
- bool found = false;
- for (ClassHierarchyNode other in classSet2.subtypeNodes) {
- ClassEntity child1 = child.cls;
- ClassEntity child2 = other.cls;
- if (elementEquivalence(child1, child2)) {
- found = true;
- break;
- }
- }
- if (!found && (!child.cls.isClosure || !allowMissingClosureClasses)) {
- if (child.isInstantiated) {
- print('Missing subtype ${child.cls} of ${classSet1.cls} '
- 'in ${classSet2.subtypeNodes}');
- print(closedWorld1.dump(
- verbose ? closedWorld1.commonElements.objectClass : classSet1.cls));
- print(closedWorld2.dump(
- verbose ? closedWorld2.commonElements.objectClass : classSet2.cls));
- }
- Expect.isFalse(
- child.isInstantiated,
- 'Missing subclass ${child.cls} of ${classSet1.cls} in '
- '${classSet2.subtypeNodes}');
- }
- }
-}
-
-void checkMixinUses(
- ClosedWorld closedWorld1,
- ClosedWorld closedWorld2,
- ClassEntity class1,
- ClassEntity class2,
- bool elementEquivalence(Entity a, Entity b),
- {bool verbose: false}) {
- checkSets(closedWorld1.mixinUsesOf(class1), closedWorld2.mixinUsesOf(class2),
- "Mixin uses of $class1 vs $class2", elementEquivalence,
- verbose: verbose);
-}
-
-/// Check member property equivalence between all members common to [compiler1]
-/// and [compiler2].
-void checkLoadedLibraryMembers(
- Compiler compiler1,
- Compiler compiler2,
- bool hasProperty(Element member1),
- void checkMemberProperties(Compiler compiler1, Element member1,
- Compiler compiler2, Element member2,
- {bool verbose}),
- {bool verbose: false}) {
- void checkMembers(Element member1, Element member2) {
- if (member1.isClass && member2.isClass) {
- ClassElement class1 = member1;
- ClassElement class2 = member2;
- if (!class1.isResolved) return;
-
- if (hasProperty(member1)) {
- if (areElementsEquivalent(member1, member2)) {
- checkMemberProperties(compiler1, member1, compiler2, member2,
- verbose: verbose);
- }
- }
-
- class1.forEachLocalMember((m1) {
- checkMembers(m1, class2.localLookup(m1.name));
- });
- ClassElement superclass1 = class1.superclass;
- ClassElement superclass2 = class2.superclass;
- while (superclass1 != null && superclass1.isUnnamedMixinApplication) {
- for (ConstructorElement c1 in superclass1.constructors) {
- checkMembers(c1, superclass2.lookupConstructor(c1.name));
- }
- superclass1 = superclass1.superclass;
- superclass2 = superclass2.superclass;
- }
- return;
- }
-
- if (!hasProperty(member1)) {
- return;
- }
-
- if (member2 == null) {
- throw 'Missing member for ${member1}';
- }
-
- if (areElementsEquivalent(member1, member2)) {
- checkMemberProperties(compiler1, member1, compiler2, member2,
- verbose: verbose);
- }
- }
-
- for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
- LibraryElement library2 =
- compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
- if (library2 != null) {
- library1.forEachLocalMember((Element member1) {
- checkMembers(member1, library2.localLookup(member1.name));
- });
- }
- }
-}
-
-/// Check equivalence of all resolution impacts.
-void checkAllImpacts(Compiler compiler1, Compiler compiler2,
- {bool verbose: false}) {
- checkLoadedLibraryMembers(compiler1, compiler2, (Element member1) {
- return compiler1.resolution.hasResolutionImpact(member1);
- }, checkImpacts, verbose: verbose);
-}
-
-/// Check equivalence of resolution impact for [member1] and [member2].
-void checkImpacts(
- Compiler compiler1, Element member1, Compiler compiler2, Element member2,
- {bool verbose: false}) {
- ResolutionImpact impact1 = compiler1.resolution.getResolutionImpact(member1);
- ResolutionImpact impact2 = compiler2.resolution.getResolutionImpact(member2);
-
- if (impact1 == null && impact2 == null) return;
-
- if (verbose) {
- print('Checking impacts for $member1 vs $member2');
- }
-
- if (impact1 == null) {
- throw 'Missing impact for $member1. $member2 has $impact2';
- }
- if (impact2 == null) {
- throw 'Missing impact for $member2. $member1 has $impact1';
- }
-
- testResolutionImpactEquivalence(impact1, impact2,
- strategy: const CheckStrategy());
-}
-
-void checkNativeClasses(
- Compiler compiler1, Compiler compiler2, TestStrategy strategy) {
- Iterable<ClassEntity> nativeClasses1 = compiler1
- .backend.nativeResolutionEnqueuerForTesting.nativeClassesForTesting;
- Iterable<ClassEntity> nativeClasses2 = compiler2
- .backend.nativeResolutionEnqueuerForTesting.nativeClassesForTesting;
-
- checkSetEquivalence(compiler1, compiler2, 'nativeClasses', nativeClasses1,
- nativeClasses2, strategy.elementEquivalence);
-
- Iterable<ClassEntity> liveNativeClasses1 =
- compiler1.backend.nativeResolutionEnqueuerForTesting.liveNativeClasses;
- Iterable<ClassEntity> liveNativeClasses2 =
- compiler2.backend.nativeResolutionEnqueuerForTesting.liveNativeClasses;
-
- checkSetEquivalence(compiler1, compiler2, 'liveNativeClasses',
- liveNativeClasses1, liveNativeClasses2, strategy.elementEquivalence);
-}
-
-void checkNativeBasicData(NativeBasicDataImpl data1, NativeBasicDataImpl data2,
- TestStrategy strategy) {
- checkMapEquivalence(
- data1,
- data2,
- 'nativeClassTagInfo',
- data1.nativeClassTagInfo,
- data2.nativeClassTagInfo,
- strategy.elementEquivalence,
- (a, b) => a == b);
- checkSetEquivalence(
- data1,
- data2,
- 'jsInteropLibraries',
- data1.jsInteropLibraries.keys,
- data2.jsInteropLibraries.keys,
- strategy.elementEquivalence);
- checkSetEquivalence(
- data1,
- data2,
- 'jsInteropClasses',
- data1.jsInteropClasses.keys,
- data2.jsInteropClasses.keys,
- strategy.elementEquivalence);
-}
-
-void checkBackendUsage(
- BackendUsageImpl usage1, BackendUsageImpl usage2, TestStrategy strategy) {
- checkSetEquivalence(
- usage1,
- usage2,
- 'globalClassDependencies',
- usage1.globalClassDependencies,
- usage2.globalClassDependencies,
- strategy.elementEquivalence);
- checkSetEquivalence(
- usage1,
- usage2,
- 'globalFunctionDependencies',
- usage1.globalFunctionDependencies,
- usage2.globalFunctionDependencies,
- strategy.elementEquivalence);
- checkSetEquivalence(
- usage1,
- usage2,
- 'helperClassesUsed',
- usage1.helperClassesUsed,
- usage2.helperClassesUsed,
- strategy.elementEquivalence);
- checkSetEquivalence(
- usage1,
- usage2,
- 'helperFunctionsUsed',
- usage1.helperFunctionsUsed,
- usage2.helperFunctionsUsed,
- strategy.elementEquivalence);
- check(
- usage1,
- usage2,
- 'needToInitializeIsolateAffinityTag',
- usage1.needToInitializeIsolateAffinityTag,
- usage2.needToInitializeIsolateAffinityTag);
- check(
- usage1,
- usage2,
- 'needToInitializeDispatchProperty',
- usage1.needToInitializeDispatchProperty,
- usage2.needToInitializeDispatchProperty);
- check(usage1, usage2, 'requiresPreamble', usage1.requiresPreamble,
- usage2.requiresPreamble);
- check(usage1, usage2, 'isInvokeOnUsed', usage1.isInvokeOnUsed,
- usage2.isInvokeOnUsed);
- check(usage1, usage2, 'isRuntimeTypeUsed', usage1.isRuntimeTypeUsed,
- usage2.isRuntimeTypeUsed);
- check(usage1, usage2, 'isFunctionApplyUsed', usage1.isFunctionApplyUsed,
- usage2.isFunctionApplyUsed);
- check(usage1, usage2, 'isNoSuchMethodUsed', usage1.isNoSuchMethodUsed,
- usage2.isNoSuchMethodUsed);
-}
-
-checkElementEnvironment(ElementEnvironment env1, ElementEnvironment env2,
- DartTypes types1, DartTypes types2, TestStrategy strategy,
- {bool checkConstructorBodies: false}) {
- strategy.testElements(
- env1, env2, 'mainLibrary', env1.mainLibrary, env2.mainLibrary);
- strategy.testElements(
- env1, env2, 'mainFunction', env1.mainFunction, env2.mainFunction);
-
- Iterable<ConstantValue> filterMetadata(Iterable<ConstantValue> constants) {
- const skippedMetadata = const [
- // Annotations on patches are not included in the patched sdk.
- 'ConstructedConstant(_Patch())',
- 'ConstructedConstant(NoInline())',
-
- // Inserted by TargetImplementation. Should only be in the VM target.
- 'ConstructedConstant(ExternalName(name=StringConstant("")))',
- ];
-
- return constants
- .where((c) => !skippedMetadata.contains(c.toStructuredText()));
- }
-
- Iterable<LibraryEntity> filterLibraries(Iterable<LibraryEntity> libraries) {
- List<Uri> skippedLibraries = [
- Uri.parse('dart:mirrors'),
- Uri.parse('dart:_js_mirrors'),
- Uri.parse('dart:js'),
- Uri.parse('dart:_js'),
- Uri.parse('dart:js_util'),
- Uri.parse('dart:_chrome'),
- Uri.parse('dart:io'),
- Uri.parse('dart:_http'),
- Uri.parse('dart:developer'),
- ];
- return libraries.where((l) => !skippedLibraries.contains(l.canonicalUri));
- }
-
- checkMembers(MemberEntity member1, MemberEntity member2) {
- Expect.equals(env1.isDeferredLoadLibraryGetter(member1),
- env2.isDeferredLoadLibraryGetter(member2));
-
- checkListEquivalence(
- member1,
- member2,
- 'metadata',
- filterMetadata(env1.getMemberMetadata(member1)),
- filterMetadata(env2.getMemberMetadata(member2)),
- strategy.testConstantValues);
-
- if (member1 is FunctionEntity && member2 is FunctionEntity) {
- if (member1 is ConstructorElement &&
- member1.definingConstructor != null) {
- // TODO(johnniwinther): Test these. Currently these are sometimes
- // correctly typed, sometimes using dynamic instead of parameter and
- // return types.
- return;
- }
- check(member1, member2, 'getFunctionType', env1.getFunctionType(member1),
- env2.getFunctionType(member2), strategy.typeEquivalence);
- }
-
- check(
- member1, member2, "isTopLevel", member1.isTopLevel, member2.isTopLevel);
- check(member1, member2, "isStatic", member1.isStatic, member2.isStatic);
- check(member1, member2, "isInstanceMember", member1.isInstanceMember,
- member2.isInstanceMember);
- check(member1, member2, "isConstructor", member1.isConstructor,
- member2.isConstructor);
- check(member1, member2, "isField", member1.isField, member2.isField);
- check(
- member1, member2, "isFunction", member1.isFunction, member2.isFunction);
- check(member1, member2, "isGetter", member1.isGetter, member2.isGetter);
- check(member1, member2, "isSetter", member1.isSetter, member2.isSetter);
- check(member1, member2, "isAssignable", member1.isAssignable,
- member2.isAssignable);
- check(member1, member2, "isConst", member1.isConst, member2.isConst);
- check(
- member1, member2, "isAbstract", member1.isAbstract, member2.isAbstract);
-
- if (member1 is FunctionEntity) {
- FunctionEntity function1 = member1;
- FunctionEntity function2 = member2;
- check(function1, function2, "isExternal", function1.isExternal,
- function2.isExternal);
- check(function1, function2, "parameterStructure",
- function1.parameterStructure, function2.parameterStructure);
- check(function1, function2, "asyncMarker", function1.asyncMarker,
- function2.asyncMarker);
- }
-
- if (member1 is ConstructorEntity) {
- ConstructorEntity constructor1 = member1;
- ConstructorEntity constructor2 = member2;
- check(
- constructor1,
- constructor2,
- "isGenerativeConstructor",
- constructor1.isGenerativeConstructor,
- constructor2.isGenerativeConstructor);
- check(constructor1, constructor2, "isFactoryConstructor",
- constructor1.isFactoryConstructor, constructor2.isFactoryConstructor);
- check(
- constructor1,
- constructor2,
- "isFromEnvironmentConstructor",
- constructor1.isFromEnvironmentConstructor,
- constructor2.isFromEnvironmentConstructor);
- }
- }
-
- checkSetEquivalence(env1, env2, 'libraries', filterLibraries(env1.libraries),
- filterLibraries(env2.libraries), strategy.elementEquivalence,
- onSameElement: (LibraryEntity lib1, LibraryEntity lib2) {
- Expect.identical(lib1, env1.lookupLibrary(lib1.canonicalUri));
- Expect.identical(lib2, env2.lookupLibrary(lib2.canonicalUri));
-
- // TODO(johnniwinther): Check libraryName.
-
- List<ClassEntity> classes2 = <ClassEntity>[];
- env1.forEachClass(lib1, (ClassEntity cls1) {
- Expect.identical(cls1, env1.lookupClass(lib1, cls1.name));
-
- String className = cls1.name;
- ClassEntity cls2 = env2.lookupClass(lib2, className);
- Expect.isNotNull(cls2, 'Missing class $className in $lib2');
- Expect.identical(cls2, env2.lookupClass(lib2, cls2.name));
-
- check(lib1, lib2, 'class:${className}', cls1, cls2,
- strategy.elementEquivalence);
-
- Expect.equals(env1.isGenericClass(cls1), env2.isGenericClass(cls2));
-
- check(
- cls1,
- cls2,
- 'superclass',
- env1.getSuperClass(cls1, skipUnnamedMixinApplications: false),
- env2.getSuperClass(cls2, skipUnnamedMixinApplications: false),
- strategy.elementEquivalence);
- check(
- cls1,
- cls2,
- 'superclass',
- env1.getSuperClass(cls1, skipUnnamedMixinApplications: true),
- env2.getSuperClass(cls2, skipUnnamedMixinApplications: true),
- strategy.elementEquivalence);
-
- InterfaceType thisType1 = env1.getThisType(cls1);
- InterfaceType thisType2 = env2.getThisType(cls2);
- check(cls1, cls2, 'thisType', thisType1, thisType2,
- strategy.typeEquivalence);
- check(cls1, cls2, 'rawType', env1.getRawType(cls1), env2.getRawType(cls2),
- strategy.typeEquivalence);
- check(
- cls1,
- cls2,
- 'createInterfaceType',
- env1.createInterfaceType(cls1, thisType1.typeArguments),
- env2.createInterfaceType(cls2, thisType2.typeArguments),
- strategy.typeEquivalence);
-
- check(cls1, cls2, 'isGenericClass', env1.isGenericClass(cls1),
- env2.isGenericClass(cls2));
- check(cls1, cls2, 'isMixinApplication', env1.isMixinApplication(cls1),
- env2.isMixinApplication(cls2));
- check(
- cls1,
- cls2,
- 'isUnnamedMixinApplication',
- env1.isUnnamedMixinApplication(cls1),
- env2.isUnnamedMixinApplication(cls2));
- check(
- cls1,
- cls2,
- 'getEffectiveMixinClass',
- env1.getEffectiveMixinClass(cls1),
- env2.getEffectiveMixinClass(cls2),
- strategy.elementEquivalence);
-
- // TODO(johnniwinther): Check type variable bounds.
-
- check(cls1, cls2, 'callType', types1.getCallType(thisType1),
- types2.getCallType(thisType2), strategy.typeEquivalence);
-
- List<InterfaceType> supertypes1 = <InterfaceType>[];
- env1.forEachSupertype(cls1, supertypes1.add);
- List<InterfaceType> supertypes2 = <InterfaceType>[];
- env2.forEachSupertype(cls2, supertypes2.add);
- checkLists(supertypes1, supertypes2, 'supertypes on $cls1, $cls2',
- strategy.typeEquivalence);
-
- List<ClassEntity> mixins1 = <ClassEntity>[];
- env1.forEachMixin(cls1, mixins1.add);
- List<ClassEntity> mixins2 = <ClassEntity>[];
- env2.forEachMixin(cls2, mixins2.add);
- checkLists(mixins1, mixins2, 'mixins on $cls1, $cls2',
- strategy.elementEquivalence);
-
- Map<MemberEntity, ClassEntity> members1 = <MemberEntity, ClassEntity>{};
- Set<String> memberNames1 = new Set<String>();
- Map<MemberEntity, ClassEntity> members2 = <MemberEntity, ClassEntity>{};
- Set<String> memberNames2 = new Set<String>();
- env1.forEachClassMember(cls1,
- (ClassEntity declarer1, MemberEntity member1) {
- if (cls1 == declarer1) {
- Expect.identical(
- member1,
- env1.lookupLocalClassMember(cls1, member1.name,
- setter: member1.isSetter));
- }
- if (!memberNames1.contains(member1.name)) {
- Expect.identical(
- member1,
- env1.lookupClassMember(cls1, member1.name,
- setter: member1.isSetter));
- }
- memberNames1.add(member1.name);
- members1[member1] = declarer1;
- });
- env2.forEachClassMember(cls2,
- (ClassEntity declarer2, MemberEntity member2) {
- if (cls2 == declarer2) {
- Expect.identical(
- member2,
- env2.lookupLocalClassMember(cls2, member2.name,
- setter: member2.isSetter));
- }
- if (!memberNames2.contains(member2.name)) {
- Expect.identical(
- member2,
- env2.lookupClassMember(cls2, member2.name,
- setter: member2.isSetter));
- }
- memberNames2.add(member2.name);
- members2[member2] = declarer2;
- });
- checkMapEquivalence(cls1, cls2, 'members', members1, members2, (a, b) {
- bool result = strategy.elementEquivalence(a, b);
- if (result) checkMembers(a, b);
- return result;
- }, strategy.elementEquivalence);
-
- Set<ConstructorEntity> constructors2 = new Set<ConstructorEntity>();
- env1.forEachConstructor(cls1, (ConstructorEntity constructor1) {
- Expect.identical(
- constructor1, env1.lookupConstructor(cls1, constructor1.name));
-
- String constructorName = constructor1.name;
- ConstructorEntity constructor2 =
- env2.lookupConstructor(cls2, constructorName);
- Expect.isNotNull(
- constructor2, "Missing constructor for $constructor1 in $cls2 ");
- Expect.identical(
- constructor2, env2.lookupConstructor(cls2, constructor2.name));
-
- constructors2.add(constructor2);
-
- check(cls1, cls2, 'constructor:${constructorName}', constructor1,
- constructor2, strategy.elementEquivalence);
-
- checkMembers(constructor1, constructor2);
- });
- env2.forEachConstructor(cls2, (ConstructorEntity constructor2) {
- Expect.isTrue(constructors2.contains(constructor2),
- "Extra constructor $constructor2 in $cls2");
- });
-
- if (checkConstructorBodies) {
- Set<ConstructorBodyEntity> constructorBodies1 =
- new Set<ConstructorBodyEntity>();
- Set<ConstructorBodyEntity> constructorBodies2 =
- new Set<ConstructorBodyEntity>();
- env1.forEachConstructorBody(cls1,
- (ConstructorBodyEntity constructorBody1) {
- constructorBodies1.add(constructorBody1);
- });
- env2.forEachConstructorBody(cls2,
- (ConstructorBodyEntity constructorBody2) {
- constructorBodies2.add(constructorBody2);
- });
- checkSetEquivalence(cls1, cls2, 'constructor-bodies',
- constructorBodies1, constructorBodies2, strategy.elementEquivalence,
- onSameElement: (ConstructorBodyEntity constructorBody1,
- ConstructorBodyEntity constructorBody2) {
- check(constructorBody1, constructorBody2, 'name',
- constructorBody1.name, constructorBody2.name);
-
- checkMembers(constructorBody1, constructorBody2);
- });
- }
- classes2.add(cls2);
- });
- env2.forEachClass(lib2, (ClassEntity cls2) {
- Expect.isTrue(classes2.contains(cls2), "Extra class $cls2 in $lib2");
- });
-
- Set<MemberEntity> members2 = new Set<MemberEntity>();
- env1.forEachLibraryMember(lib1, (MemberEntity member1) {
- Expect.identical(
- member1,
- env1.lookupLibraryMember(lib1, member1.name,
- setter: member1.isSetter));
-
- String memberName = member1.name;
- MemberEntity member2 =
- env2.lookupLibraryMember(lib2, memberName, setter: member1.isSetter);
- Expect.isNotNull(member2, 'Missing member for $member1 in $lib2');
- Expect.identical(
- member2,
- env2.lookupLibraryMember(lib2, member2.name,
- setter: member2.isSetter));
-
- members2.add(member2);
-
- check(lib1, lib2, 'member:${memberName}', member1, member2,
- strategy.elementEquivalence);
-
- checkMembers(member1, member2);
- });
- env2.forEachLibraryMember(lib2, (MemberEntity member2) {
- Expect.isTrue(
- members2.contains(member2), "Extra member $member2 in $lib2");
- });
- });
- // TODO(johnniwinther): Check getLocalFunctionType and getUnaliasedType ?
-}
-
-bool areInstantiationInfosEquivalent(
- InstantiationInfo info1,
- InstantiationInfo info2,
- bool elementEquivalence(Entity a, Entity b),
- bool typeEquivalence(DartType a, DartType b)) {
- checkMaps(
- info1.instantiationMap,
- info2.instantiationMap,
- 'instantiationMap of\n '
- '${info1.instantiationMap}\nvs ${info2.instantiationMap}',
- elementEquivalence,
- (a, b) => areSetsEquivalent(
- a, b, (a, b) => areInstancesEquivalent(a, b, typeEquivalence)));
- return true;
-}
-
-bool areInstancesEquivalent(Instance instance1, Instance instance2,
- bool typeEquivalence(DartType a, DartType b)) {
- InterfaceType type1 = instance1.type;
- InterfaceType type2 = instance2.type;
- return typeEquivalence(type1, type2) &&
- instance1.kind == instance2.kind &&
- instance1.isRedirection == instance2.isRedirection;
-}
-
-bool areAbstractUsagesEquivalent(AbstractUsage usage1, AbstractUsage usage2) {
- return usage1.hasSameUsage(usage2);
-}
-
-bool _areEntitiesEquivalent(a, b) => areElementsEquivalent(a, b);
-
-void checkResolutionEnqueuers(
- BackendUsage backendUsage1,
- BackendUsage backendUsage2,
- ResolutionEnqueuer enqueuer1,
- ResolutionEnqueuer enqueuer2,
- {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
- bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
- bool elementFilter(Entity element),
- bool verbose: false,
- List<String> skipClassUsageTesting: const <String>[]}) {
- elementFilter ??= (_) => true;
-
- ResolutionWorldBuilderBase worldBuilder1 = enqueuer1.worldBuilder;
- ResolutionWorldBuilderBase worldBuilder2 = enqueuer2.worldBuilder;
-
- checkSets(worldBuilder1.instantiatedTypes, worldBuilder2.instantiatedTypes,
- "Instantiated types mismatch", typeEquivalence,
- verbose: verbose);
-
- checkSets(
- worldBuilder1.directlyInstantiatedClasses,
- worldBuilder2.directlyInstantiatedClasses,
- "Directly instantiated classes mismatch",
- elementEquivalence,
- verbose: verbose);
-
- checkMaps(
- worldBuilder1.getInstantiationMap(),
- worldBuilder2.getInstantiationMap(),
- "Instantiated classes mismatch",
- elementEquivalence,
- (a, b) => areInstantiationInfosEquivalent(
- a, b, elementEquivalence, typeEquivalence),
- verbose: verbose);
-
- checkSets(enqueuer1.processedEntities, enqueuer2.processedEntities,
- "Processed element mismatch", elementEquivalence,
- elementFilter: elementFilter, verbose: verbose);
-
- checkSets(worldBuilder1.isChecks, worldBuilder2.isChecks, "Is-check mismatch",
- typeEquivalence,
- verbose: verbose);
-
- checkSets(worldBuilder1.closurizedMembers, worldBuilder2.closurizedMembers,
- "closurizedMembers", elementEquivalence,
- verbose: verbose);
- checkSets(worldBuilder1.fieldSetters, worldBuilder2.fieldSetters,
- "fieldSetters", elementEquivalence,
- verbose: verbose);
- checkSets(
- worldBuilder1.methodsNeedingSuperGetter,
- worldBuilder2.methodsNeedingSuperGetter,
- "methodsNeedingSuperGetter",
- elementEquivalence,
- verbose: verbose);
-
- checkMaps(
- worldBuilder1.classUsageForTesting,
- worldBuilder2.classUsageForTesting,
- 'classUsageForTesting',
- elementEquivalence,
- areAbstractUsagesEquivalent,
- keyFilter: (c) => !skipClassUsageTesting.contains(c.name),
- verbose: verbose);
-
- checkMaps(
- worldBuilder1.staticMemberUsageForTesting,
- worldBuilder2.staticMemberUsageForTesting,
- 'staticMemberUsageForTesting',
- elementEquivalence,
- areAbstractUsagesEquivalent,
- keyFilter: elementFilter,
- verbose: verbose);
- checkMaps(
- worldBuilder1.instanceMemberUsageForTesting,
- worldBuilder2.instanceMemberUsageForTesting,
- 'instanceMemberUsageForTesting',
- elementEquivalence,
- areAbstractUsagesEquivalent,
- verbose: verbose);
-
- Expect.equals(backendUsage1.isInvokeOnUsed, backendUsage2.isInvokeOnUsed,
- "JavaScriptBackend.hasInvokeOnSupport mismatch");
- Expect.equals(
- backendUsage1.isFunctionApplyUsed,
- backendUsage1.isFunctionApplyUsed,
- "JavaScriptBackend.hasFunctionApplySupport mismatch");
- Expect.equals(
- backendUsage1.isRuntimeTypeUsed,
- backendUsage2.isRuntimeTypeUsed,
- "JavaScriptBackend.hasRuntimeTypeSupport mismatch");
-}
-
-void checkCodegenEnqueuers(CodegenEnqueuer enqueuer1, CodegenEnqueuer enqueuer2,
- {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
- bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
- bool elementFilter(Element element),
- bool verbose: false}) {
- CodegenWorldBuilderImpl worldBuilder1 = enqueuer1.worldBuilder;
- CodegenWorldBuilderImpl worldBuilder2 = enqueuer2.worldBuilder;
-
- checkSets(worldBuilder1.instantiatedTypes, worldBuilder2.instantiatedTypes,
- "Instantiated types mismatch", typeEquivalence,
- verbose: verbose);
-
- checkSets(
- worldBuilder1.directlyInstantiatedClasses,
- worldBuilder2.directlyInstantiatedClasses,
- "Directly instantiated classes mismatch",
- elementEquivalence,
- verbose: verbose);
-
- checkSets(enqueuer1.processedEntities, enqueuer2.processedEntities,
- "Processed element mismatch", elementEquivalence, elementFilter: (e) {
- return elementFilter != null ? elementFilter(e) : true;
- }, verbose: verbose);
-
- checkSets(worldBuilder1.isChecks, worldBuilder2.isChecks, "Is-check mismatch",
- typeEquivalence,
- verbose: verbose);
-
- checkSets(
- worldBuilder1.allReferencedStaticFields,
- worldBuilder2.allReferencedStaticFields,
- "Directly instantiated classes mismatch",
- elementEquivalence,
- verbose: verbose);
- checkSets(worldBuilder1.closurizedMembers, worldBuilder2.closurizedMembers,
- "closurizedMembers", elementEquivalence,
- verbose: verbose);
- checkSets(worldBuilder1.processedClasses, worldBuilder2.processedClasses,
- "processedClasses", elementEquivalence,
- verbose: verbose);
- checkSets(
- worldBuilder1.methodsNeedingSuperGetter,
- worldBuilder2.methodsNeedingSuperGetter,
- "methodsNeedingSuperGetter",
- elementEquivalence,
- verbose: verbose);
- checkSets(
- worldBuilder1.staticFunctionsNeedingGetter,
- worldBuilder2.staticFunctionsNeedingGetter,
- "staticFunctionsNeedingGetter",
- elementEquivalence,
- verbose: verbose);
-
- checkMaps(
- worldBuilder1.classUsageForTesting,
- worldBuilder2.classUsageForTesting,
- 'classUsageForTesting',
- elementEquivalence,
- areAbstractUsagesEquivalent,
- verbose: verbose);
- checkMaps(
- worldBuilder1.staticMemberUsageForTesting,
- worldBuilder2.staticMemberUsageForTesting,
- 'staticMemberUsageForTesting',
- elementEquivalence,
- areAbstractUsagesEquivalent,
- verbose: verbose);
- checkMaps(
- worldBuilder1.instanceMemberUsageForTesting,
- worldBuilder2.instanceMemberUsageForTesting,
- 'instanceMemberUsageForTesting',
- elementEquivalence,
- areAbstractUsagesEquivalent,
- verbose: verbose);
-}
-
-// TODO(johnniwinther): Check all emitter properties.
-void checkEmitters(
- CodeEmitterTask emitter1, CodeEmitterTask emitter2, TestStrategy strategy,
- {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
- bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
- bool elementFilter(Element element),
- bool verbose: false}) {
- checkEmitterPrograms(emitter1.emitter.programForTesting,
- emitter2.emitter.programForTesting, strategy);
-
- checkSets(
- emitter1.typeTestRegistry.rtiNeededClasses,
- emitter2.typeTestRegistry.rtiNeededClasses,
- "TypeTestRegistry rti needed classes mismatch",
- strategy.elementEquivalence,
- verbose: verbose);
-}
-
-void checkEmitterPrograms(
- Program program1, Program program2, TestStrategy strategy) {
- checkLists(program1.fragments, program2.fragments, 'fragments',
- (a, b) => a.outputFileName == b.outputFileName,
- onSameElement: (a, b) =>
- checkEmitterFragments(program1, program2, a, b, strategy));
- checkLists(
- program1.holders, program2.holders, 'holders', (a, b) => a.name == b.name,
- onSameElement: checkEmitterHolders);
- check(program1, program2, 'outputContainsConstantList',
- program1.outputContainsConstantList, program2.outputContainsConstantList);
- check(program1, program2, 'needsNativeSupport', program1.needsNativeSupport,
- program2.needsNativeSupport);
- check(program1, program2, 'hasSoftDeferredClasses',
- program1.hasSoftDeferredClasses, program2.hasSoftDeferredClasses);
- checkMaps(
- program1.loadMap,
- program2.loadMap,
- 'loadMap',
- equality,
- (a, b) => areSetsEquivalent(
- a, b, (a, b) => a.outputFileName == b.outputFileName));
- checkMaps(program1.symbolsMap, program2.symbolsMap, 'symbolsMap',
- (a, b) => a.key == b.key, equality);
-
- check(
- program1,
- program2,
- 'typeToInterceptorMap',
- program1.typeToInterceptorMap,
- program2.typeToInterceptorMap,
- areJsNodesEquivalent,
- js.nodeToString);
-}
-
-void checkEmitterFragments(Program program1, Program program2,
- Fragment fragment1, Fragment fragment2, TestStrategy strategy) {
- // TODO(johnniwinther): Check outputUnit.
- checkLists(fragment1.libraries, fragment2.libraries, 'libraries',
- (a, b) => a.element.canonicalUri == b.element.canonicalUri,
- onSameElement: (a, b) => checkEmitterLibraries(a, b, strategy));
- checkLists(fragment1.constants, fragment2.constants, 'constants',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterConstants(a, b, strategy));
- checkLists(fragment1.staticNonFinalFields, fragment2.staticNonFinalFields,
- 'staticNonFinalFields', (a, b) => a.name.key == b.name.key,
- onSameElement: checkEmitterStaticFields);
- checkLists(
- fragment1.staticLazilyInitializedFields,
- fragment2.staticLazilyInitializedFields,
- 'staticLazilyInitializedFields',
- (a, b) => a.name.key == b.name.key,
- onSameElement: checkEmitterStaticFields);
- check(fragment1, fragment2, 'isMainFragment', fragment1.isMainFragment,
- fragment2.isMainFragment);
- if (fragment1 is MainFragment && fragment2 is MainFragment) {
- check(fragment1, fragment2, 'invokeMain', fragment1.invokeMain,
- fragment2.invokeMain, areJsNodesEquivalent, js.nodeToString);
- } else if (fragment1 is DeferredFragment && fragment2 is DeferredFragment) {
- check(fragment1, fragment2, 'name', fragment1.name, fragment2.name);
- }
-
- check(
- program1,
- program2,
- 'metadataForOutputUnit',
- program1.metadataForOutputUnit(fragment1.outputUnit),
- program2.metadataForOutputUnit(fragment2.outputUnit),
- areJsNodesEquivalent,
- js.nodeToString);
-
- check(
- program1,
- program2,
- 'metadataTypesForOutputUnit',
- program1.metadataTypesForOutputUnit(fragment1.outputUnit),
- program2.metadataTypesForOutputUnit(fragment2.outputUnit),
- areJsNodesEquivalent,
- js.nodeToString);
-}
-
-void checkEmitterLibraries(
- Library library1, Library library2, TestStrategy strategy) {
- check(library1, library2, 'uri', library1.uri, library2.uri);
- checkLists(library1.classes, library2.classes, 'classes',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterClasses(a, b, strategy));
- checkLists(library1.statics, library2.statics, 'statics',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
- checkLists(
- library1.staticFieldsForReflection,
- library2.staticFieldsForReflection,
- 'staticFieldsForReflection on $library1/$library2',
- (a, b) => a.name.key == b.name.key,
- onSameElement: checkEmitterFields);
-}
-
-void checkEmitterClasses(Class class1, Class class2, TestStrategy strategy) {
- checkLists(class1.methods, class2.methods, 'methods',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
- checkLists(class1.fields, class2.fields, 'fields',
- (a, b) => a.name.key == b.name.key,
- onSameElement: checkEmitterFields);
- checkLists(class1.isChecks, class2.isChecks, 'isChecks',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
- checkLists(class1.checkedSetters, class2.checkedSetters, 'checkedSetters',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
- checkLists(class1.callStubs, class2.callStubs, 'callStubs',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
- checkLists(class1.noSuchMethodStubs, class2.noSuchMethodStubs,
- 'noSuchMethodStubs', (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
- checkLists(
- class1.staticFieldsForReflection,
- class2.staticFieldsForReflection,
- 'staticFieldsForReflection on $class1/$class2',
- (a, b) => a.name.key == b.name.key,
- onSameElement: checkEmitterFields);
-
- check(class1, class2, 'superclassName', class1.superclassName?.key,
- class2.superclassName?.key);
- check(class1, class2, 'isMixinApplication', class1.isMixinApplication,
- class2.isMixinApplication);
- check(class1, class2, 'hasRtiField', class1.hasRtiField, class2.hasRtiField);
- check(class1, class2, 'onlyForRti', class1.onlyForRti, class2.onlyForRti);
- check(class1, class2, 'isDirectlyInstantiated', class1.isDirectlyInstantiated,
- class2.isDirectlyInstantiated);
- check(class1, class2, 'isNative', class1.isNative, class2.isNative);
- check(class1, class2, 'isClosureBaseClass', class1.isClosureBaseClass,
- class2.isClosureBaseClass);
- check(class1, class2, 'isSoftDeferred', class1.isSoftDeferred,
- class2.isSoftDeferred);
- check(class1, class2, 'isEager', class1.isEager, class2.isEager);
- checkEmitterHolders(class1.holder, class2.holder);
-}
-
-void checkEmitterMethods(
- Method method1, Method method2, TestStrategy strategy) {
- check(method1, method2, 'code', method1.code, method2.code,
- areJsNodesEquivalent, js.nodeToString);
- check(method1, method2, 'is ParameterStubMethod',
- method1 is ParameterStubMethod, method2 is ParameterStubMethod);
- if (method1 is ParameterStubMethod && method2 is ParameterStubMethod) {
- check(method1, method2, 'callName', method1.callName?.key,
- method2.callName?.key);
- }
- check(method1, method2, 'is DartMethod', method1 is DartMethod,
- method2 is DartMethod);
- if (method1 is DartMethod && method2 is DartMethod) {
- check(method1, method2, 'callName', method1.callName?.key,
- method2.callName?.key);
- check(method1, method2, 'needsTearOff', method1.needsTearOff,
- method2.needsTearOff);
- check(method1, method2, 'tearOffName', method1.tearOffName?.key,
- method2.tearOffName?.key);
- checkLists(method1.parameterStubs, method2.parameterStubs, 'parameterStubs',
- (a, b) => a.name.key == b.name.key,
- onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
- check(method1, method2, 'canBeApplied', method1.canBeApplied,
- method2.canBeApplied);
- check(method1, method2, 'canBeReflected', method1.canBeReflected,
- method2.canBeReflected);
- check(method1, method2, 'functionType', method1.functionType,
- method2.functionType, areJsNodesEquivalent, js.nodeToString);
- check(method1, method2, 'requiredParameterCount',
- method1.requiredParameterCount, method2.requiredParameterCount);
- if (method1.optionalParameterDefaultValues == null &&
- method2.optionalParameterDefaultValues == null) {
- // Nothing to test.
- } else if (method1.optionalParameterDefaultValues is List &&
- method2.optionalParameterDefaultValues is List) {
- checkLists(
- method1.optionalParameterDefaultValues,
- method2.optionalParameterDefaultValues,
- 'optionalParameterDefaultValues',
- strategy.constantValueEquivalence);
- } else if (method1.optionalParameterDefaultValues is Map &&
- method2.optionalParameterDefaultValues is Map) {
- checkMaps(
- method1.optionalParameterDefaultValues,
- method2.optionalParameterDefaultValues,
- 'optionalParameterDefaultValues',
- equality,
- strategy.constantValueEquivalence);
- } else {
- check(
- method1,
- method2,
- 'optionalParameterDefaultValues',
- method1.optionalParameterDefaultValues,
- method2.optionalParameterDefaultValues);
- }
- }
-}
-
-void checkEmitterFields(Field field1, Field field2) {
- check(field1, field2, 'accessorName', field1.accessorName?.key,
- field2.accessorName?.key);
- check(field1, field2, 'getterFlags', field1.getterFlags, field2.getterFlags);
- check(field1, field2, 'setterFlags', field1.setterFlags, field2.setterFlags);
- check(field1, field2, 'needsCheckedSetter', field1.needsCheckedSetter,
- field2.needsCheckedSetter);
-}
-
-void checkEmitterConstants(
- Constant constant1, Constant constant2, TestStrategy strategy) {
- checkEmitterHolders(constant1.holder, constant2.holder);
- check(constant1, constant2, 'value', constant1.value, constant2.value,
- strategy.constantValueEquivalence);
-}
-
-void checkEmitterStaticFields(StaticField field1, StaticField field2) {
- check(field1, field2, 'code', field1.code, field2.code, areJsNodesEquivalent,
- js.nodeToString);
- check(field1, field2, 'isFinal', field1.isFinal, field2.isFinal);
- check(field1, field2, 'isLazy', field1.isLazy, field2.isLazy);
- checkEmitterHolders(field1.holder, field2.holder);
-}
-
-void checkEmitterHolders(Holder holder1, Holder holder2) {
- check(holder1, holder2, 'name', holder1.name, holder2.name);
- check(holder1, holder2, 'index', holder1.index, holder2.index);
- check(holder1, holder2, 'isStaticStateHolder', holder1.isStaticStateHolder,
- holder2.isStaticStateHolder);
- check(holder1, holder2, 'isConstantsHolder', holder1.isConstantsHolder,
- holder2.isConstantsHolder);
-}
-
-void checkGeneratedCode(JavaScriptBackend backend1, JavaScriptBackend backend2,
- {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent}) {
- checkMaps(backend1.generatedCode, backend2.generatedCode, 'generatedCode',
- elementEquivalence, areJsNodesEquivalent,
- valueToString: js.nodeToString);
-}
bool areJsNodesEquivalent(js.Node node1, js.Node node2) {
return new JsEquivalenceVisitor().testNodes(node1, node2);
diff --git a/tests/compiler/dart2js/equivalence/check_helpers.dart b/tests/compiler/dart2js/equivalence/check_helpers.dart
index 4a52acc..cef161e 100644
--- a/tests/compiler/dart2js/equivalence/check_helpers.dart
+++ b/tests/compiler/dart2js/equivalence/check_helpers.dart
@@ -6,15 +6,9 @@
library dart2js.equivalence.helpers;
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:expect/expect.dart';
-import 'equivalence_helper.dart';
-
Check currentCheck;
class Check {
@@ -66,66 +60,8 @@
}
}
-/// Strategy for checking equivalence.
-///
-/// Use this strategy to fail early with contextual information in the event of
-/// inequivalence.
-class CheckStrategy extends TestStrategy {
- const CheckStrategy(
- {Equivalence<Entity> elementEquivalence: areEntitiesEquivalent,
- Equivalence<DartType> typeEquivalence: areTypesEquivalent,
- Equivalence<ConstantExpression> constantEquivalence:
- areConstantsEquivalent,
- Equivalence<ConstantValue> constantValueEquivalence:
- areConstantValuesEquivalent})
- : super(
- elementEquivalence: elementEquivalence,
- typeEquivalence: typeEquivalence,
- constantEquivalence: constantEquivalence,
- constantValueEquivalence: constantValueEquivalence);
-
- TestStrategy get testOnly => new TestStrategy(
- elementEquivalence: elementEquivalence,
- typeEquivalence: typeEquivalence,
- constantEquivalence: constantEquivalence,
- constantValueEquivalence: constantValueEquivalence);
-
- @override
- bool test<T>(var object1, var object2, String property, T value1, T value2,
- [bool equivalence(T a, T b) = equality]) {
- return check(object1, object2, property, value1, value2, equivalence);
- }
-
- @override
- bool testLists(
- Object object1, Object object2, String property, List list1, List list2,
- [bool elementEquivalence(a, b) = equality]) {
- return checkListEquivalence(object1, object2, property, list1, list2,
- (o1, o2, p, v1, v2) {
- if (!elementEquivalence(v1, v2)) {
- throw "$o1.$p = '${v1}' <> "
- "$o2.$p = '${v2}'";
- }
- });
- }
-
- @override
- bool testSets<E>(var object1, var object2, String property, Iterable<E> set1,
- Iterable<E> set2,
- [bool elementEquivalence(E a, E b) = equality]) {
- return checkSetEquivalence(
- object1, object2, property, set1, set2, elementEquivalence);
- }
-
- @override
- bool testMaps<K, V>(
- var object1, var object2, String property, Map<K, V> map1, Map<K, V> map2,
- [bool keyEquivalence(K a, K b) = equality,
- bool valueEquivalence(V a, V b) = equality]) {
- return checkMapEquivalence(object1, object2, property, map1, map2,
- keyEquivalence, valueEquivalence);
- }
-}
+/// Equality based equivalence function.
+bool equality(a, b) => a == b;
/// Check that the values [property] of [object1] and [object2], [value1] and
/// [value2] respectively, are equal and throw otherwise.
@@ -266,110 +202,6 @@
return true;
}
-/// Checks the equivalence of the identity (but not properties) of [element1]
-/// and [element2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkElementIdentities(Object object1, Object object2, String property,
- Entity element1, Entity element2) {
- if (identical(element1, element2)) return true;
- return check(
- object1, object2, property, element1, element2, areEntitiesEquivalent);
-}
-
-/// Checks the pair-wise equivalence of the identity (but not properties) of the
-/// elements in [list] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkElementListIdentities(Object object1, Object object2, String property,
- Iterable<Entity> list1, Iterable<Entity> list2) {
- return checkListEquivalence(
- object1, object2, property, list1, list2, checkElementIdentities);
-}
-
-/// Checks the equivalence of [DartType]s [type1] and [type2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkDartTypes(Object object1, Object object2, String property,
- DartType type1, DartType type2) =>
- checkTypes(object1, object2, property, type1, type2);
-
-/// Checks the equivalence of [type1] and [type2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkTypes(Object object1, Object object2, String property,
- ResolutionDartType type1, ResolutionDartType type2) {
- if (identical(type1, type2)) return true;
- if (type1 == null || type2 == null) {
- return check(object1, object2, property, type1, type2);
- } else {
- return check(object1, object2, property, type1, type2,
- (a, b) => const TypeEquivalence(const CheckStrategy()).visit(a, b));
- }
-}
-
-/// Checks the pair-wise equivalence of the types in [list1] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkTypeLists(Object object1, Object object2, String property,
- List<DartType> list1, List<DartType> list2) {
- return checkListEquivalence(
- object1, object2, property, list1, list2, checkDartTypes);
-}
-
-/// Checks the equivalence of [exp1] and [exp2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstants(Object object1, Object object2, String property,
- ConstantExpression exp1, ConstantExpression exp2) {
- if (identical(exp1, exp2)) return true;
- if (exp1 == null || exp2 == null) {
- return check(object1, object2, property, exp1, exp2);
- } else {
- return check(object1, object2, property, exp1, exp2,
- (a, b) => const ConstantEquivalence(const CheckStrategy()).visit(a, b));
- }
-}
-
-/// Checks the equivalence of [value1] and [value2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstantValues(Object object1, Object object2, String property,
- ConstantValue value1, ConstantValue value2) {
- if (identical(value1, value2)) return true;
- if (value1 == null || value2 == null) {
- return check(object1, object2, property, value1, value2);
- } else {
- return check(
- object1,
- object2,
- property,
- value1,
- value2,
- (a, b) =>
- const ConstantValueEquivalence(const CheckStrategy()).visit(a, b));
- }
-}
-
-/// Checks the pair-wise equivalence of the constants in [list1] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstantLists(Object object1, Object object2, String property,
- List<ConstantExpression> list1, List<ConstantExpression> list2) {
- return checkListEquivalence(
- object1, object2, property, list1, list2, checkConstants);
-}
-
-/// Checks the pair-wise equivalence of the constants values in [list1] and
-/// [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstantValueLists(Object object1, Object object2, String property,
- List<ConstantValue> list1, List<ConstantValue> list2) {
- return checkListEquivalence(
- object1, object2, property, list1, list2, checkConstantValues);
-}
-
void checkLists<T>(List<T> list1, List<T> list2, String messagePrefix,
bool sameElement(T a, T b),
{bool verbose: false,
diff --git a/tests/compiler/dart2js/equivalence/equivalence_helper.dart b/tests/compiler/dart2js/equivalence/equivalence_helper.dart
deleted file mode 100644
index 45437a9..0000000
--- a/tests/compiler/dart2js/equivalence/equivalence_helper.dart
+++ /dev/null
@@ -1,2310 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Functions for asserting equivalence across different compiler
-/// implementations.
-
-library dart2js.test.equivalence;
-
-import 'package:compiler/src/closure.dart';
-import 'package:compiler/src/common/resolution.dart';
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/jumps.dart';
-import 'package:compiler/src/elements/modelx.dart';
-import 'package:compiler/src/elements/names.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
-import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/elements/visitor.dart';
-import 'package:compiler/src/native/native.dart'
- show NativeBehavior, SpecialType;
-import 'package:compiler/src/resolution/access_semantics.dart';
-import 'package:compiler/src/resolution/send_structure.dart';
-import 'package:compiler/src/resolution/tree_elements.dart';
-import 'package:compiler/src/tree/nodes.dart';
-import 'package:compiler/src/universe/feature.dart';
-import 'package:compiler/src/universe/selector.dart';
-import 'package:compiler/src/universe/use.dart';
-import 'package:compiler/src/util/util.dart';
-
-import 'package:front_end/src/fasta/scanner.dart';
-
-typedef bool Equivalence<E>(E a, E b, {TestStrategy strategy});
-
-/// Equality based equivalence function.
-bool equality(a, b) => a == b;
-
-/// Returns `true` if the elements in [a] and [b] are pair-wise equivalent
-/// according to [elementEquivalence].
-bool areListsEquivalent<T>(List<T> a, List<T> b,
- [bool elementEquivalence(T a, T b) = equality]) {
- if (a.length != b.length) return false;
- for (int i = 0; i < a.length && i < b.length; i++) {
- if (!elementEquivalence(a[i], b[i])) {
- return false;
- }
- }
- return true;
-}
-
-/// Returns `true` if the elements in [a] and [b] are equivalent as sets using
-/// [elementEquivalence] to determine element equivalence.
-bool areSetsEquivalent<E>(Iterable<E> set1, Iterable<E> set2,
- [bool elementEquivalence(E a, E b) = equality]) {
- Set<E> remaining = set2.toSet();
- for (dynamic element1 in set1) {
- bool found = false;
- for (dynamic element2 in set2) {
- if (elementEquivalence(element1, element2)) {
- found = true;
- remaining.remove(element2);
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
- return remaining.isEmpty;
-}
-
-/// Returns `true` if the content of [map1] and [map2] is equivalent using
-/// [keyEquivalence] and [valueEquivalence] to determine key/value equivalence.
-bool areMapsEquivalent<K, V>(Map<K, V> map1, Map<K, V> map2,
- [bool keyEquivalence(K a, K b) = equality,
- bool valueEquivalence(V a, V b) = equality]) {
- Set remaining = map2.keys.toSet();
- for (dynamic key1 in map1.keys) {
- bool found = false;
- for (dynamic key2 in map2.keys) {
- if (keyEquivalence(key1, key2)) {
- found = true;
- remaining.remove(key2);
- if (!valueEquivalence(map1[key1], map2[key2])) {
- return false;
- }
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
- return remaining.isEmpty;
-}
-
-/// Returns `true` if elements [a] and [b] are equivalent.
-bool areElementsEquivalent(Element a, Element b, {TestStrategy strategy}) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- return new ElementIdentityEquivalence(strategy ?? const TestStrategy())
- .visit(a, b);
-}
-
-bool areEntitiesEquivalent(Entity a, Entity b, {TestStrategy strategy}) {
- return areElementsEquivalent(a, b, strategy: strategy);
-}
-
-/// Returns `true` if types [a] and [b] are equivalent.
-bool areTypesEquivalent(DartType a, DartType b, {TestStrategy strategy}) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- return new TypeEquivalence(strategy ?? const TestStrategy()).visit(a, b);
-}
-
-/// Returns `true` if constants [exp1] and [exp2] are equivalent.
-bool areConstantsEquivalent(ConstantExpression exp1, ConstantExpression exp2,
- {TestStrategy strategy}) {
- if (identical(exp1, exp2)) return true;
- if (exp1 == null || exp2 == null) return false;
- return new ConstantEquivalence(strategy ?? const TestStrategy())
- .visit(exp1, exp2);
-}
-
-/// Returns `true` if constant values [value1] and [value2] are equivalent.
-bool areConstantValuesEquivalent(ConstantValue value1, ConstantValue value2,
- {TestStrategy strategy}) {
- if (identical(value1, value2)) return true;
- if (value1 == null || value2 == null) return false;
- return new ConstantValueEquivalence(strategy ?? const TestStrategy())
- .visit(value1, value2);
-}
-
-/// Returns `true` if the lists of elements, [a] and [b], are equivalent.
-bool areElementListsEquivalent(List<Element> a, List<Element> b) {
- return areListsEquivalent(a, b, areElementsEquivalent);
-}
-
-/// Returns `true` if the lists of types, [a] and [b], are equivalent.
-bool areTypeListsEquivalent(
- List<ResolutionDartType> a, List<ResolutionDartType> b) {
- return areListsEquivalent(a, b, areTypesEquivalent);
-}
-
-/// Returns `true` if the lists of constants, [a] and [b], are equivalent.
-bool areConstantListsEquivalent(
- List<ConstantExpression> a, List<ConstantExpression> b) {
- return areListsEquivalent(a, b, areConstantsEquivalent);
-}
-
-/// Returns `true` if the lists of constant values, [a] and [b], are equivalent.
-bool areConstantValueListsEquivalent(
- List<ConstantValue> a, List<ConstantValue> b) {
- return areListsEquivalent(a, b, areConstantValuesEquivalent);
-}
-
-/// Returns `true` if the selectors [a] and [b] are equivalent.
-bool areSelectorsEquivalent(Selector a, Selector b,
- {TestStrategy strategy: const TestStrategy()}) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- return a.kind == b.kind &&
- a.callStructure == b.callStructure &&
- areNamesEquivalent(a.memberName, b.memberName, strategy: strategy);
-}
-
-/// Returns `true` if the names [a] and [b] are equivalent.
-bool areNamesEquivalent(Name a, Name b,
- {TestStrategy strategy: const TestStrategy()}) {
- return a.text == b.text &&
- a.isSetter == b.isSetter &&
- strategy.testElements(a, b, 'library', a.library, b.library);
-}
-
-/// Returns `true` if the dynamic uses [a] and [b] are equivalent.
-bool areDynamicUsesEquivalent(DynamicUse a, DynamicUse b,
- {TestStrategy strategy: const TestStrategy()}) {
- return areSelectorsEquivalent(a.selector, b.selector, strategy: strategy);
-}
-
-/// Returns `true` if the static uses [a] and [b] are equivalent.
-bool areStaticUsesEquivalent(StaticUse a, StaticUse b,
- {TestStrategy strategy: const TestStrategy()}) {
- return a.kind == b.kind &&
- strategy.testElements(a, b, 'element', a.element, b.element);
-}
-
-/// Returns `true` if the type uses [a] and [b] are equivalent.
-bool areTypeUsesEquivalent(TypeUse a, TypeUse b,
- {TestStrategy strategy: const TestStrategy()}) {
- return a.kind == b.kind && strategy.testTypes(a, b, 'type', a.type, b.type);
-}
-
-/// Returns `true` if the list literal uses [a] and [b] are equivalent.
-bool areListLiteralUsesEquivalent(ListLiteralUse a, ListLiteralUse b,
- {TestStrategy strategy: const TestStrategy()}) {
- return strategy.testTypes(a, b, 'type', a.type, b.type) &&
- a.isConstant == b.isConstant &&
- a.isEmpty == b.isEmpty;
-}
-
-/// Returns `true` if the map literal uses [a] and [b] are equivalent.
-bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b,
- {TestStrategy strategy: const TestStrategy()}) {
- return strategy.testTypes(a, b, 'type', a.type, b.type) &&
- a.isConstant == b.isConstant &&
- a.isEmpty == b.isEmpty;
-}
-
-/// Returns `true` if the access semantics [a] and [b] are equivalent.
-bool areAccessSemanticsEquivalent(AccessSemantics a, AccessSemantics b) {
- if (a.kind != b.kind) return false;
- switch (a.kind) {
- case AccessKind.EXPRESSION:
- case AccessKind.THIS:
- // No additional properties.
- return true;
- case AccessKind.THIS_PROPERTY:
- case AccessKind.DYNAMIC_PROPERTY:
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return areNamesEquivalent(a.name, b.name);
- case AccessKind.CLASS_TYPE_LITERAL:
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return areConstantsEquivalent(a.constant, b.constant);
- case AccessKind.LOCAL_FUNCTION:
- case AccessKind.LOCAL_VARIABLE:
- case AccessKind.FINAL_LOCAL_VARIABLE:
- case AccessKind.PARAMETER:
- case AccessKind.FINAL_PARAMETER:
- case AccessKind.STATIC_FIELD:
- case AccessKind.FINAL_STATIC_FIELD:
- case AccessKind.STATIC_METHOD:
- case AccessKind.STATIC_GETTER:
- case AccessKind.STATIC_SETTER:
- case AccessKind.TOPLEVEL_FIELD:
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- case AccessKind.TOPLEVEL_METHOD:
- case AccessKind.TOPLEVEL_GETTER:
- case AccessKind.TOPLEVEL_SETTER:
- case AccessKind.SUPER_FIELD:
- case AccessKind.SUPER_FINAL_FIELD:
- case AccessKind.SUPER_METHOD:
- case AccessKind.SUPER_GETTER:
- case AccessKind.SUPER_SETTER:
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- case AccessKind.UNRESOLVED:
- case AccessKind.UNRESOLVED_SUPER:
- case AccessKind.INVALID:
- return areElementsEquivalent(a.element, b.element);
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundAccess1 = a;
- CompoundAccessSemantics compoundAccess2 = b;
- return compoundAccess1.compoundAccessKind ==
- compoundAccess2.compoundAccessKind &&
- areElementsEquivalent(
- compoundAccess1.getter, compoundAccess2.getter) &&
- areElementsEquivalent(compoundAccess1.setter, compoundAccess2.setter);
- case AccessKind.CONSTANT:
- default:
- throw new UnsupportedError('Unsupported access kind: ${a.kind}');
- }
-}
-
-/// Returns `true` if the send structures [a] and [b] are equivalent.
-bool areSendStructuresEquivalent(SendStructure a, SendStructure b) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- if (a.kind != b.kind) return false;
-
- dynamic ad = a;
- dynamic bd = b;
- switch (a.kind) {
- case SendStructureKind.IF_NULL:
- case SendStructureKind.LOGICAL_AND:
- case SendStructureKind.LOGICAL_OR:
- case SendStructureKind.NOT:
- case SendStructureKind.INVALID_UNARY:
- case SendStructureKind.INVALID_BINARY:
- // No additional properties.
- return true;
-
- case SendStructureKind.IS:
- case SendStructureKind.IS_NOT:
- case SendStructureKind.AS:
- return areTypesEquivalent(ad.type, bd.type);
-
- case SendStructureKind.INVOKE:
- case SendStructureKind.INCOMPATIBLE_INVOKE:
- if (!areSelectorsEquivalent(ad.selector, bd.selector)) return false;
- continue semantics;
-
- case SendStructureKind.UNARY:
- case SendStructureKind.BINARY:
- case SendStructureKind.PREFIX:
- case SendStructureKind.POSTFIX:
- case SendStructureKind.INDEX_PREFIX:
- case SendStructureKind.INDEX_POSTFIX:
- case SendStructureKind.COMPOUND:
- case SendStructureKind.COMPOUND_INDEX_SET:
- if (ad.operator != bd.operator) return false;
- continue semantics;
-
- case SendStructureKind.DEFERRED_PREFIX:
- return areElementsEquivalent(ad.prefix, bd.prefix) &&
- areSendStructuresEquivalent(ad.sendStructure, bd.sendStructure);
-
- semantics:
- case SendStructureKind.GET:
- case SendStructureKind.SET:
- case SendStructureKind.INDEX:
- case SendStructureKind.INDEX_SET:
- case SendStructureKind.EQUALS:
- case SendStructureKind.NOT_EQUALS:
- case SendStructureKind.SET_IF_NULL:
- case SendStructureKind.INDEX_SET_IF_NULL:
- return areAccessSemanticsEquivalent(ad.semantics, bd.semantics);
- }
- throw new UnsupportedError('Unexpected send structures $a vs $b');
-}
-
-/// Returns `true` if the new structures [a] and [b] are equivalent.
-bool areNewStructuresEquivalent(NewStructure a, NewStructure b) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- if (a.kind != b.kind) return false;
-
- dynamic ad = a;
- dynamic bd = b;
- switch (a.kind) {
- case NewStructureKind.NEW_INVOKE:
- return ad.semantics.kind == bd.semantics.kind &&
- areElementsEquivalent(ad.semantics.element, bd.semantics.element) &&
- areTypesEquivalent(ad.semantics.type, bd.semantics.type) &&
- areSelectorsEquivalent(ad.selector, bd.selector);
- case NewStructureKind.CONST_INVOKE:
- return ad.constantInvokeKind == bd.constantInvokeKind &&
- areConstantsEquivalent(ad.constant, bd.constant);
- case NewStructureKind.LATE_CONST:
- default:
- throw new UnsupportedError('Unsupported NewStructure kind ${a.kind}.');
- }
-}
-
-/// Returns `true` if nodes [a] and [b] are equivalent.
-bool areNodesEquivalent(Node node1, Node node2) {
- if (identical(node1, node2)) return true;
- if (node1 == null || node2 == null) return false;
- return node1.accept1(const NodeEquivalenceVisitor(), node2);
-}
-
-/// Strategy for testing equivalence.
-///
-/// Use this strategy to determine equivalence without failing on inequivalence.
-class TestStrategy {
- final Equivalence<Entity> elementEquivalence;
- final Equivalence<DartType> typeEquivalence;
- final Equivalence<ConstantExpression> constantEquivalence;
- final Equivalence<ConstantValue> constantValueEquivalence;
-
- const TestStrategy(
- {this.elementEquivalence: areEntitiesEquivalent,
- this.typeEquivalence: areTypesEquivalent,
- this.constantEquivalence: areConstantsEquivalent,
- this.constantValueEquivalence: areConstantValuesEquivalent});
-
- /// An equivalence [TestStrategy] that doesn't throw on inequivalence.
- TestStrategy get testOnly => this;
-
- bool test<T>(
- dynamic object1, dynamic object2, String property, T value1, T value2,
- [bool equivalence(T a, T b) = equality]) {
- return equivalence(value1, value2);
- }
-
- bool testLists(
- Object object1, Object object2, String property, List list1, List list2,
- [bool elementEquivalence(a, b) = equality]) {
- return areListsEquivalent(list1, list2, elementEquivalence);
- }
-
- bool testSets<E>(dynamic object1, dynamic object2, String property,
- Iterable<E> set1, Iterable<E> set2,
- [bool elementEquivalence(E a, E b) = equality]) {
- return areSetsEquivalent(set1, set2, elementEquivalence);
- }
-
- bool testMaps<K, V>(dynamic object1, dynamic object2, String property,
- Map<K, V> map1, Map<K, V> map2,
- [bool keyEquivalence(K a, K b) = equality,
- bool valueEquivalence(V a, V b) = equality]) {
- return areMapsEquivalent(map1, map2, keyEquivalence, valueEquivalence);
- }
-
- bool testElements(Object object1, Object object2, String property,
- Entity element1, Entity element2) {
- return test(object1, object2, property, element1, element2,
- (a, b) => elementEquivalence(a, b, strategy: this));
- }
-
- bool testTypes(Object object1, Object object2, String property,
- DartType type1, DartType type2) {
- return test(object1, object2, property, type1, type2,
- (a, b) => typeEquivalence(a, b, strategy: this));
- }
-
- bool testConstants(Object object1, Object object2, String property,
- ConstantExpression exp1, ConstantExpression exp2) {
- return test(object1, object2, property, exp1, exp2,
- (a, b) => constantEquivalence(a, b, strategy: this));
- }
-
- bool testConstantValues(Object object1, Object object2, String property,
- ConstantValue value1, ConstantValue value2) {
- return test(object1, object2, property, value1, value2,
- (a, b) => constantValueEquivalence(a, b, strategy: this));
- }
-
- bool testTypeLists(Object object1, Object object2, String property,
- List<DartType> list1, List<DartType> list2) {
- return testLists(object1, object2, property, list1, list2,
- (a, b) => typeEquivalence(a, b, strategy: this));
- }
-
- bool testConstantLists(Object object1, Object object2, String property,
- List<ConstantExpression> list1, List<ConstantExpression> list2) {
- return testLists(object1, object2, property, list1, list2,
- (a, b) => constantEquivalence(a, b, strategy: this));
- }
-
- bool testConstantValueLists(Object object1, Object object2, String property,
- List<ConstantValue> list1, List<ConstantValue> list2) {
- return testLists(object1, object2, property, list1, list2,
- (a, b) => constantValueEquivalence(a, b, strategy: this));
- }
-
- bool testNodes(
- Object object1, Object object2, String property, Node node1, Node node2) {
- return areNodesEquivalent(node1, node2);
- }
-}
-
-/// Visitor that checks for equivalence of [Element]s.
-class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> {
- final TestStrategy strategy;
-
- const ElementIdentityEquivalence([this.strategy = const TestStrategy()]);
-
- bool visit(Element element1, Element element2) {
- if (element1 == null && element2 == null) {
- return true;
- } else if (element1 == null || element2 == null) {
- return false;
- }
- element1 = element1.declaration;
- element2 = element2.declaration;
- if (element1 == element2) {
- return true;
- }
- return strategy.test(
- element1, element2, 'kind', element1.kind, element2.kind) &&
- element1.accept(this, element2);
- }
-
- @override
- bool visitElement(Element e, Element arg) {
- throw new UnsupportedError("Unsupported element $e");
- }
-
- @override
- bool visitLibraryElement(
- LibraryElement element1, covariant LibraryElement element2) {
- return strategy.test(element1, element2, 'canonicalUri',
- element1.canonicalUri, element2.canonicalUri);
- }
-
- @override
- bool visitCompilationUnitElement(CompilationUnitElement element1,
- covariant CompilationUnitElement element2) {
- return strategy.test(element1, element2, 'script.resourceUri',
- element1.script.resourceUri, element2.script.resourceUri) &&
- visit(element1.library, element2.library);
- }
-
- @override
- bool visitClassElement(
- ClassElement element1, covariant ClassElement element2) {
- if (!strategy.test(
- element1,
- element2,
- 'isUnnamedMixinApplication',
- element1.isUnnamedMixinApplication,
- element2.isUnnamedMixinApplication)) {
- return false;
- }
- if (element1.isUnnamedMixinApplication) {
- MixinApplicationElement mixin1 = element1;
- MixinApplicationElement mixin2 = element2;
- return strategy.testElements(
- mixin1, mixin2, 'subclass', mixin1.subclass, mixin2.subclass) &&
- // Using the [mixinType] is more precise but requires the test to
- // handle self references: The identity of a type variable is based on
- // its type declaration and if [mixin1] is generic the [mixinType]
- // will contain the type variables declared by [mixin1], i.e.
- // `abstract class Mixin<T> implements MixinType<T> {}`
- strategy.testElements(
- mixin1, mixin2, 'mixin', mixin1.mixin, mixin2.mixin);
- } else {
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- visit(element1.library, element2.library);
- }
- }
-
- bool checkMembers(Element element1, covariant Element element2) {
- if (!strategy.test(
- element1, element2, 'name', element1.name, element2.name)) {
- return false;
- }
- if (element1.enclosingClass != null || element2.enclosingClass != null) {
- return visit(element1.enclosingClass, element2.enclosingClass);
- } else {
- return visit(element1.library, element2.library);
- }
- }
-
- @override
- bool visitFieldElement(
- FieldElement element1, covariant FieldElement element2) {
- return checkMembers(element1, element2);
- }
-
- @override
- bool visitBoxFieldElement(
- BoxFieldElement element1, covariant BoxFieldElement element2) {
- return element1.box.name == element2.box.name &&
- visit(element1.box.executableContext, element2.box.executableContext) &&
- visit(element1.variableElement, element2.variableElement);
- }
-
- @override
- bool visitConstructorElement(
- ConstructorElement element1, covariant ConstructorElement element2) {
- return checkMembers(element1, element2);
- }
-
- @override
- bool visitMethodElement(
- covariant MethodElement element1, covariant MethodElement element2) {
- return checkMembers(element1, element2);
- }
-
- @override
- bool visitGetterElement(
- GetterElement element1, covariant GetterElement element2) {
- return checkMembers(element1, element2);
- }
-
- @override
- bool visitSetterElement(
- SetterElement element1, covariant SetterElement element2) {
- return checkMembers(element1, element2);
- }
-
- @override
- bool visitLocalFunctionElement(
- LocalFunctionElement element1, covariant LocalFunctionElement element2) {
- // TODO(johnniwinther): Define an equivalence on locals.
- MemberElement member1 = element1.memberContext;
- MemberElement member2 = element2.memberContext;
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- checkMembers(member1, member2);
- }
-
- @override
- bool visitLocalVariableElement(
- LocalVariableElement element1, covariant LocalVariableElement element2) {
- // TODO(johnniwinther): Define an equivalence on locals.
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- checkMembers(element1.memberContext, element2.memberContext);
- }
-
- bool visitAbstractFieldElement(
- AbstractFieldElement element1, covariant AbstractFieldElement element2) {
- return checkMembers(element1, element2);
- }
-
- @override
- bool visitTypeVariableElement(
- TypeVariableElement element1, covariant TypeVariableElement element2) {
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- visit(element1.typeDeclaration, element2.typeDeclaration);
- }
-
- @override
- bool visitTypedefElement(
- TypedefElement element1, covariant TypedefElement element2) {
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- visit(element1.library, element2.library);
- }
-
- @override
- bool visitParameterElement(
- ParameterElement element1, covariant ParameterElement element2) {
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- visit(element1.functionDeclaration, element2.functionDeclaration);
- }
-
- @override
- bool visitImportElement(
- ImportElement element1, covariant ImportElement element2) {
- return visit(element1.importedLibrary, element2.importedLibrary) &&
- visit(element1.library, element2.library);
- }
-
- @override
- bool visitExportElement(
- ExportElement element1, covariant ExportElement element2) {
- return visit(element1.exportedLibrary, element2.exportedLibrary) &&
- visit(element1.library, element2.library);
- }
-
- @override
- bool visitPrefixElement(
- PrefixElement element1, covariant PrefixElement element2) {
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- visit(element1.library, element2.library);
- }
-
- @override
- bool visitErroneousElement(
- ErroneousElement element1, covariant ErroneousElement element2) {
- return strategy.test(element1, element2, 'messageKind',
- element1.messageKind, element2.messageKind);
- }
-
- @override
- bool visitWarnOnUseElement(
- WarnOnUseElement element1, covariant WarnOnUseElement element2) {
- return strategy.testElements(element1, element2, 'wrappedElement',
- element1.wrappedElement, element2.wrappedElement);
- }
-}
-
-/// Visitor that checks for equivalence of [ResolutionDartType]s.
-class TypeEquivalence
- implements ResolutionDartTypeVisitor<bool, ResolutionDartType> {
- final TestStrategy strategy;
-
- const TypeEquivalence([this.strategy = const TestStrategy()]);
-
- bool visit(
- covariant ResolutionDartType type1, covariant ResolutionDartType type2) {
- return strategy.test(type1, type2, 'kind', type1.kind, type2.kind) &&
- type1.accept(this, type2);
- }
-
- @override
- bool visitDynamicType(covariant ResolutionDynamicType type,
- covariant ResolutionDynamicType other) =>
- true;
-
- @override
- bool visitFunctionType(covariant ResolutionFunctionType type,
- covariant ResolutionFunctionType other) {
- return strategy.testTypeLists(type, other, 'parameterTypes',
- type.parameterTypes, other.parameterTypes) &&
- strategy.testTypeLists(type, other, 'optionalParameterTypes',
- type.optionalParameterTypes, other.optionalParameterTypes) &&
- strategy.testTypeLists(type, other, 'namedParameterTypes',
- type.namedParameterTypes, other.namedParameterTypes) &&
- strategy.testLists(type, other, 'namedParameters', type.namedParameters,
- other.namedParameters);
- }
-
- bool visitGenericType(GenericType type, GenericType other) {
- return strategy.testElements(
- type, other, 'element', type.element, other.element) &&
- strategy.testTypeLists(type, other, 'typeArguments', type.typeArguments,
- other.typeArguments);
- }
-
- @override
- bool visitMalformedType(MalformedType type, covariant MalformedType other) =>
- true;
-
- @override
- bool visitTypeVariableType(covariant ResolutionTypeVariableType type,
- covariant ResolutionTypeVariableType other) {
- return strategy.testElements(
- type, other, 'element', type.element, other.element) &&
- strategy.test(type, other, 'is MethodTypeVariableType',
- type is MethodTypeVariableType, other is MethodTypeVariableType);
- }
-
- @override
- bool visitVoidType(covariant ResolutionVoidType type,
- covariant ResolutionVoidType argument) =>
- true;
-
- @override
- bool visitInterfaceType(covariant ResolutionInterfaceType type,
- covariant ResolutionInterfaceType other) {
- return visitGenericType(type, other);
- }
-
- @override
- bool visitTypedefType(covariant ResolutionTypedefType type,
- covariant ResolutionTypedefType other) {
- return visitGenericType(type, other);
- }
-
- @override
- bool visitFunctionTypeVariable(
- FunctionTypeVariable type, ResolutionDartType other) {
- throw new UnsupportedError("Function type variables are not supported.");
- }
-
- @override
- bool visitFutureOrType(
- covariant FutureOrType type, covariant ResolutionDartType other) {
- throw new UnsupportedError("FutureOr is not supported.");
- }
-}
-
-/// Visitor that checks for structural equivalence of [ConstantExpression]s.
-class ConstantEquivalence
- implements ConstantExpressionVisitor<bool, ConstantExpression> {
- final TestStrategy strategy;
-
- const ConstantEquivalence([this.strategy = const TestStrategy()]);
-
- @override
- bool visit(ConstantExpression exp1, covariant ConstantExpression exp2) {
- if (identical(exp1, exp2)) return true;
- return strategy.test(exp1, exp2, 'kind', exp1.kind, exp2.kind) &&
- exp1.accept(this, exp2);
- }
-
- @override
- bool visitAs(AsConstantExpression exp1, covariant AsConstantExpression exp2) {
- return strategy.test(
- exp1, exp2, 'expression', exp1.expression, exp2.expression) &&
- strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type);
- }
-
- @override
- bool visitBinary(
- BinaryConstantExpression exp1, covariant BinaryConstantExpression exp2) {
- return strategy.test(
- exp1, exp2, 'operator', exp1.operator, exp2.operator) &&
- strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) &&
- strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right);
- }
-
- @override
- bool visitConcatenate(ConcatenateConstantExpression exp1,
- covariant ConcatenateConstantExpression exp2) {
- return strategy.testConstantLists(
- exp1, exp2, 'expressions', exp1.expressions, exp2.expressions);
- }
-
- @override
- bool visitConditional(ConditionalConstantExpression exp1,
- covariant ConditionalConstantExpression exp2) {
- return strategy.testConstants(
- exp1, exp2, 'condition', exp1.condition, exp2.condition) &&
- strategy.testConstants(
- exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp) &&
- strategy.testConstants(
- exp1, exp2, 'falseExp', exp1.falseExp, exp2.falseExp);
- }
-
- @override
- bool visitConstructed(ConstructedConstantExpression exp1,
- covariant ConstructedConstantExpression exp2) {
- return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) &&
- strategy.testElements(exp1, exp2, 'target', exp1.target, exp2.target) &&
- strategy.testConstantLists(
- exp1, exp2, 'arguments', exp1.arguments, exp2.arguments) &&
- strategy.test(exp1, exp2, 'callStructure', exp1.callStructure,
- exp2.callStructure);
- }
-
- @override
- bool visitFunction(FunctionConstantExpression exp1,
- covariant FunctionConstantExpression exp2) {
- return strategy.testElements(
- exp1, exp2, 'element', exp1.element, exp2.element);
- }
-
- @override
- bool visitIdentical(IdenticalConstantExpression exp1,
- covariant IdenticalConstantExpression exp2) {
- return strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) &&
- strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right);
- }
-
- @override
- bool visitList(
- ListConstantExpression exp1, covariant ListConstantExpression exp2) {
- return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) &&
- strategy.testConstantLists(
- exp1, exp2, 'values', exp1.values, exp2.values);
- }
-
- @override
- bool visitMap(
- MapConstantExpression exp1, covariant MapConstantExpression exp2) {
- return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) &&
- strategy.testConstantLists(exp1, exp2, 'keys', exp1.keys, exp2.keys) &&
- strategy.testConstantLists(
- exp1, exp2, 'values', exp1.values, exp2.values);
- }
-
- @override
- bool visitNamed(
- NamedArgumentReference exp1, covariant NamedArgumentReference exp2) {
- return strategy.test(exp1, exp2, 'name', exp1.name, exp2.name);
- }
-
- @override
- bool visitPositional(PositionalArgumentReference exp1,
- covariant PositionalArgumentReference exp2) {
- return strategy.test(exp1, exp2, 'index', exp1.index, exp2.index);
- }
-
- @override
- bool visitSymbol(
- SymbolConstantExpression exp1, covariant SymbolConstantExpression exp2) {
- // TODO(johnniwinther): Handle private names. Currently not even supported
- // in resolution.
- return strategy.test(exp1, exp2, 'name', exp1.name, exp2.name);
- }
-
- @override
- bool visitType(
- TypeConstantExpression exp1, covariant TypeConstantExpression exp2) {
- return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type);
- }
-
- @override
- bool visitUnary(
- UnaryConstantExpression exp1, covariant UnaryConstantExpression exp2) {
- return strategy.test(
- exp1, exp2, 'operator', exp1.operator, exp2.operator) &&
- strategy.testConstants(
- exp1, exp2, 'expression', exp1.expression, exp2.expression);
- }
-
- @override
- bool visitField(
- FieldConstantExpression exp1, covariant FieldConstantExpression exp2) {
- return strategy.testElements(
- exp1, exp2, 'element', exp1.element, exp2.element);
- }
-
- @override
- bool visitLocalVariable(LocalVariableConstantExpression exp1,
- covariant LocalVariableConstantExpression exp2) {
- return strategy.testElements(
- exp1, exp2, 'element', exp1.element, exp2.element);
- }
-
- @override
- bool visitBool(
- BoolConstantExpression exp1, covariant BoolConstantExpression exp2) {
- return strategy.test(
- exp1, exp2, 'boolValue', exp1.boolValue, exp2.boolValue);
- }
-
- @override
- bool visitDouble(
- DoubleConstantExpression exp1, covariant DoubleConstantExpression exp2) {
- return strategy.test(
- exp1, exp2, 'doubleValue', exp1.doubleValue, exp2.doubleValue);
- }
-
- @override
- bool visitInt(
- IntConstantExpression exp1, covariant IntConstantExpression exp2) {
- return strategy.test(exp1, exp2, 'intValue', exp1.intValue, exp2.intValue);
- }
-
- @override
- bool visitNull(
- NullConstantExpression exp1, covariant NullConstantExpression exp2) {
- return true;
- }
-
- @override
- bool visitString(
- StringConstantExpression exp1, covariant StringConstantExpression exp2) {
- return strategy.test(
- exp1, exp2, 'stringValue', exp1.stringValue, exp2.stringValue);
- }
-
- @override
- bool visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1,
- covariant BoolFromEnvironmentConstantExpression exp2) {
- return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
- strategy.testConstants(
- exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue);
- }
-
- @override
- bool visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1,
- covariant IntFromEnvironmentConstantExpression exp2) {
- return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
- strategy.testConstants(
- exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue);
- }
-
- @override
- bool visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp1,
- covariant StringFromEnvironmentConstantExpression exp2) {
- return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
- strategy.testConstants(
- exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue);
- }
-
- @override
- bool visitStringLength(StringLengthConstantExpression exp1,
- covariant StringLengthConstantExpression exp2) {
- return strategy.testConstants(
- exp1, exp2, 'expression', exp1.expression, exp2.expression);
- }
-
- @override
- bool visitDeferred(DeferredConstantExpression exp1,
- covariant DeferredConstantExpression exp2) {
- return strategy.testElements(
- exp1, exp2, 'import', exp1.import, exp2.import) &&
- strategy.testConstants(
- exp1, exp2, 'expression', exp1.expression, exp2.expression);
- }
-
- @override
- bool visitAssert(
- AssertConstantExpression exp1, covariant AssertConstantExpression exp2) {
- return strategy.testConstants(
- exp1, exp2, 'condition', exp1.condition, exp2.condition) &&
- strategy.testConstants(
- exp1, exp2, 'message', exp1.message, exp2.message);
- }
-
- @override
- bool visitInstantiation(InstantiationConstantExpression exp1,
- covariant InstantiationConstantExpression exp2) {
- return strategy.testTypeLists(exp1, exp2, 'typeArguments',
- exp1.typeArguments, exp2.typeArguments) &&
- strategy.testConstants(
- exp1, exp2, 'expression', exp1.expression, exp2.expression);
- }
-}
-
-/// Visitor that checks for structural equivalence of [ConstantValue]s.
-class ConstantValueEquivalence
- implements ConstantValueVisitor<bool, ConstantValue> {
- final TestStrategy strategy;
-
- const ConstantValueEquivalence([this.strategy = const TestStrategy()]);
-
- bool visit(ConstantValue value1, covariant ConstantValue value2) {
- if (identical(value1, value2)) return true;
- return strategy.test(value1, value2, 'kind', value1.kind, value2.kind) &&
- value1.accept(this, value2);
- }
-
- @override
- bool visitConstructed(ConstructedConstantValue value1,
- covariant ConstructedConstantValue value2) {
- return strategy.testTypes(
- value1, value2, 'type', value1.type, value2.type) &&
- strategy.testMaps(
- value1,
- value2,
- 'fields',
- value1.fields,
- value2.fields,
- strategy.elementEquivalence,
- (a, b) => strategy.testConstantValues(
- value1, value2, 'fields.values', a, b));
- }
-
- @override
- bool visitFunction(
- FunctionConstantValue value1, covariant FunctionConstantValue value2) {
- return strategy.testElements(
- value1, value2, 'element', value1.element, value2.element);
- }
-
- @override
- bool visitList(ListConstantValue value1, covariant ListConstantValue value2) {
- return strategy.testTypes(
- value1, value2, 'type', value1.type, value2.type) &&
- strategy.testConstantValueLists(
- value1, value2, 'entries', value1.entries, value2.entries);
- }
-
- @override
- bool visitMap(MapConstantValue value1, covariant MapConstantValue value2) {
- return strategy.testTypes(
- value1, value2, 'type', value1.type, value2.type) &&
- strategy.testConstantValueLists(
- value1, value2, 'keys', value1.keys, value2.keys) &&
- strategy.testConstantValueLists(
- value1, value2, 'values', value1.values, value2.values);
- }
-
- @override
- bool visitType(TypeConstantValue value1, covariant TypeConstantValue value2) {
- return strategy.testTypes(value1, value2, 'type', value1.type, value2.type);
- }
-
- @override
- bool visitBool(BoolConstantValue value1, covariant BoolConstantValue value2) {
- return strategy.test(
- value1, value2, 'boolValue', value1.boolValue, value2.boolValue);
- }
-
- @override
- bool visitDouble(
- DoubleConstantValue value1, covariant DoubleConstantValue value2) {
- return strategy.test(
- value1, value2, 'doubleValue', value1.doubleValue, value2.doubleValue);
- }
-
- @override
- bool visitInt(IntConstantValue value1, covariant IntConstantValue value2) {
- return strategy.test(
- value1, value2, 'intValue', value1.intValue, value2.intValue);
- }
-
- @override
- bool visitNull(NullConstantValue value1, covariant NullConstantValue value2) {
- return true;
- }
-
- @override
- bool visitString(
- StringConstantValue value1, covariant StringConstantValue value2) {
- return strategy.test(
- value1, value2, 'stringValue', value1.stringValue, value2.stringValue);
- }
-
- @override
- bool visitDeferred(
- DeferredConstantValue value1, covariant DeferredConstantValue value2) {
- return strategy.testElements(
- value1, value2, 'prefix', value1.import, value2.import) &&
- strategy.testConstantValues(
- value1, value2, 'referenced', value1.referenced, value2.referenced);
- }
-
- @override
- bool visitDeferredGlobal(DeferredGlobalConstantValue value1,
- covariant DeferredGlobalConstantValue value2) {
- return strategy.testSets(
- value1,
- value2,
- 'imports',
- value1.unit.importsForTesting,
- value2.unit.importsForTesting,
- strategy.elementEquivalence) &&
- strategy.testConstantValues(
- value1, value2, 'referenced', value1.referenced, value2.referenced);
- }
-
- @override
- bool visitNonConstant(
- NonConstantValue value1, covariant NonConstantValue value2) {
- return true;
- }
-
- @override
- bool visitSynthetic(
- SyntheticConstantValue value1, covariant SyntheticConstantValue value2) {
- return strategy.test(
- value1, value2, 'payload', value1.payload, value2.payload) &&
- strategy.test(
- value1, value2, 'valueKind', value1.valueKind, value2.valueKind);
- }
-
- @override
- bool visitInterceptor(InterceptorConstantValue value1,
- covariant InterceptorConstantValue value2) {
- return strategy.testElements(value1, value2, 'cls', value1.cls, value2.cls);
- }
-
- @override
- bool visitInstantiation(InstantiationConstantValue value1,
- covariant InstantiationConstantValue value2) {
- return strategy.testTypeLists(value1, value2, 'typeArguments',
- value1.typeArguments, value2.typeArguments) &&
- strategy.testConstantValues(
- value1, value2, 'function', value1.function, value2.function);
- }
-}
-
-/// Tests the equivalence of [impact1] and [impact2] using [strategy].
-bool testResolutionImpactEquivalence(
- ResolutionImpact impact1, ResolutionImpact impact2,
- {TestStrategy strategy = const TestStrategy(),
- Iterable<ConstantExpression> filterConstantLiterals(
- Iterable<ConstantExpression> constants,
- {bool fromFirstImpact})}) {
- return strategy.testSets(impact1, impact2, 'constSymbolNames',
- impact1.constSymbolNames, impact2.constSymbolNames) &&
- strategy.testSets(
- impact1,
- impact2,
- 'constantLiterals',
- filterConstantLiterals != null
- ? filterConstantLiterals(impact1.constantLiterals,
- fromFirstImpact: true)
- : impact1.constantLiterals,
- filterConstantLiterals != null
- ? filterConstantLiterals(impact2.constantLiterals,
- fromFirstImpact: false)
- : impact2.constantLiterals,
- areConstantsEquivalent) &&
- strategy.testSets(
- impact1,
- impact2,
- 'dynamicUses',
- impact1.dynamicUses,
- impact2.dynamicUses,
- (a, b) =>
- areDynamicUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
- strategy.testSets(
- impact1, impact2, 'features', impact1.features, impact2.features) &&
- strategy.testSets(
- impact1,
- impact2,
- 'listLiterals',
- impact1.listLiterals,
- impact2.listLiterals,
- (a, b) => areListLiteralUsesEquivalent(a, b,
- strategy: strategy.testOnly)) &&
- strategy.testSets(
- impact1,
- impact2,
- 'mapLiterals',
- impact1.mapLiterals,
- impact2.mapLiterals,
- (a, b) =>
- areMapLiteralUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
- strategy.testSets(
- impact1,
- impact2,
- 'staticUses',
- impact1.staticUses,
- impact2.staticUses,
- (a, b) =>
- areStaticUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
- strategy.testSets(
- impact1,
- impact2,
- 'typeUses',
- impact1.typeUses,
- impact2.typeUses,
- (a, b) => areTypeUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
- strategy.testSets(
- impact1,
- impact2,
- 'nativeData',
- impact1.nativeData,
- impact2.nativeData,
- (a, b) => testNativeBehavior(a, b, strategy: strategy));
-}
-
-/// Tests the equivalence of [resolvedAst1] and [resolvedAst2] using [strategy].
-bool testResolvedAstEquivalence(
- ResolvedAst resolvedAst1, ResolvedAst resolvedAst2,
- [TestStrategy strategy = const TestStrategy()]) {
- if (!strategy.test(resolvedAst1, resolvedAst1, 'kind', resolvedAst1.kind,
- resolvedAst2.kind)) {
- return false;
- }
- if (resolvedAst1.kind != ResolvedAstKind.PARSED) {
- // Nothing more to check.
- return true;
- }
- bool result = strategy.testElements(resolvedAst1, resolvedAst2, 'element',
- resolvedAst1.element, resolvedAst2.element) &&
- strategy.testNodes(resolvedAst1, resolvedAst2, 'node', resolvedAst1.node,
- resolvedAst2.node) &&
- strategy.testNodes(resolvedAst1, resolvedAst2, 'body', resolvedAst1.body,
- resolvedAst2.body) &&
- testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy) &&
- strategy.test(resolvedAst1, resolvedAst2, 'sourceUri',
- resolvedAst1.sourceUri, resolvedAst2.sourceUri);
- if (resolvedAst1.element is FunctionElement) {
- FunctionElement element1 = resolvedAst1.element;
- FunctionElement element2 = resolvedAst2.element;
- for (int index = 0; index < element1.parameters.length; index++) {
- dynamic parameter1 = element1.parameters[index];
- dynamic parameter2 = element2.parameters[index];
- result = result &&
- strategy.testNodes(parameter1, parameter2, 'node',
- parameter1.implementation.node, parameter2.implementation.node) &&
- strategy.testNodes(
- parameter1,
- parameter2,
- 'initializer',
- parameter1.implementation.initializer,
- parameter2.implementation.initializer);
- }
- }
- return result;
-}
-
-/// Tests the equivalence of the data stored in the [TreeElements] of
-/// [resolvedAst1] and [resolvedAst2] using [strategy].
-bool testTreeElementsEquivalence(
- ResolvedAst resolvedAst1, ResolvedAst resolvedAst2,
- [TestStrategy strategy = const TestStrategy()]) {
- AstIndexComputer indices1 = new AstIndexComputer();
- resolvedAst1.node.accept(indices1);
- AstIndexComputer indices2 = new AstIndexComputer();
- resolvedAst2.node.accept(indices2);
-
- TreeElements elements1 = resolvedAst1.elements;
- TreeElements elements2 = resolvedAst2.elements;
-
- TreeElementsEquivalenceVisitor visitor = new TreeElementsEquivalenceVisitor(
- indices1, indices2, elements1, elements2, strategy);
- resolvedAst1.node.accept(visitor);
- if (visitor.success) {
- return strategy.test(elements1, elements2, 'containsTryStatement',
- elements1.containsTryStatement, elements2.containsTryStatement);
- }
- return false;
-}
-
-bool testNativeBehavior(NativeBehavior a, NativeBehavior b,
- {TestStrategy strategy = const TestStrategy()}) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- return strategy.test(
- a, b, 'codeTemplateText', a.codeTemplateText, b.codeTemplateText) &&
- strategy.test(a, b, 'isAllocation', a.isAllocation, b.isAllocation) &&
- strategy.test(a, b, 'sideEffects', a.sideEffects, b.sideEffects) &&
- strategy.test(a, b, 'throwBehavior', a.throwBehavior, b.throwBehavior) &&
- strategy.testTypeLists(
- a,
- b,
- 'dartTypesReturned',
- NativeBehaviorFilters.filterDartTypes(a.typesReturned),
- NativeBehaviorFilters.filterDartTypes(b.typesReturned)) &&
- strategy.testLists(
- a,
- b,
- 'specialTypesReturned',
- NativeBehaviorFilters.filterSpecialTypes(a.typesReturned),
- NativeBehaviorFilters.filterSpecialTypes(b.typesReturned)) &&
- strategy.testTypeLists(
- a,
- b,
- 'dartTypesInstantiated',
- NativeBehaviorFilters.filterDartTypes(a.typesInstantiated),
- NativeBehaviorFilters.filterDartTypes(b.typesInstantiated)) &&
- strategy.testLists(
- a,
- b,
- 'specialTypesInstantiated',
- NativeBehaviorFilters.filterSpecialTypes(a.typesInstantiated),
- NativeBehaviorFilters.filterSpecialTypes(b.typesInstantiated)) &&
- strategy.test(a, b, 'useGvn', a.useGvn, b.useGvn);
-}
-
-/// Visitor that checks the equivalence of [TreeElements] data.
-class TreeElementsEquivalenceVisitor extends Visitor {
- final TestStrategy strategy;
- final AstIndexComputer indices1;
- final AstIndexComputer indices2;
- final TreeElements elements1;
- final TreeElements elements2;
- bool success = true;
-
- TreeElementsEquivalenceVisitor(
- this.indices1, this.indices2, this.elements1, this.elements2,
- [this.strategy = const TestStrategy()]);
-
- bool testJumpTargets(
- Node node1, Node node2, String property, JumpTarget a, JumpTarget b) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- return strategy.test(
- a, b, 'nestingLevel', a.nestingLevel, b.nestingLevel) &&
- strategy.test(a, b, 'statement', indices1.nodeIndices[a.statement],
- indices2.nodeIndices[b.statement]) &&
- strategy.test(
- a, b, 'isBreakTarget', a.isBreakTarget, b.isBreakTarget) &&
- strategy.test(
- a, b, 'isContinueTarget', a.isContinueTarget, b.isContinueTarget) &&
- strategy.testLists(a, b, 'labels', a.labels.toList(), b.labels.toList(),
- (a, b) {
- return indices1.nodeIndices[a.label] == indices2.nodeIndices[b.label];
- });
- }
-
- bool testLabelDefinitions(Node node1, Node node2, String property,
- LabelDefinitionX a, LabelDefinitionX b) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- return strategy.test(a, b, 'label', indices1.nodeIndices[a.label],
- indices2.nodeIndices[b.label]) &&
- strategy.test(a, b, 'labelName', a.labelName, b.labelName) &&
- strategy.test(a, b, 'target', indices1.nodeIndices[a.target.statement],
- indices2.nodeIndices[b.target.statement]) &&
- strategy.test(
- a, b, 'isBreakTarget', a.isBreakTarget, b.isBreakTarget) &&
- strategy.test(
- a, b, 'isContinueTarget', a.isContinueTarget, b.isContinueTarget);
- }
-
- bool testNativeData(Node node1, Node node2, String property, a, b) {
- if (identical(a, b)) return true;
- if (a == null || b == null) return false;
- if (a is NativeBehavior && b is NativeBehavior) {
- return testNativeBehavior(a, b, strategy: strategy);
- }
- return true;
- }
-
- visitNode(Node node1) {
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- Node node2 = indices2.nodeList[index];
- success = strategy.testElements(
- node1, node2, '[$index]', elements1[node1], elements2[node2]) &&
- strategy.testTypes(node1, node2, 'getType($index)',
- elements1.getType(node1), elements2.getType(node2)) &&
- strategy.test(
- node1,
- node2,
- 'getSelector($index)',
- elements1.getSelector(node1),
- elements2.getSelector(node2),
- areSelectorsEquivalent) &&
- strategy.testConstants(node1, node2, 'getConstant($index)',
- elements1.getConstant(node1), elements2.getConstant(node2)) &&
- strategy.testTypes(node1, node2, 'typesCache[$index]',
- elements1.typesCache[node1], elements2.typesCache[node2]) &&
- testJumpTargets(
- node1,
- node2,
- 'getTargetDefinition($index)',
- elements1.getTargetDefinition(node1),
- elements2.getTargetDefinition(node2)) &&
- testNativeData(node1, node2, 'getNativeData($index)',
- elements1.getNativeData(node1), elements2.getNativeData(node2));
-
- node1.visitChildren(this);
- }
-
- @override
- visitSend(Send node1) {
- visitExpression(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- Send node2 = indices2.nodeList[index];
- success = strategy.test(node1, node2, 'isTypeLiteral($index)',
- elements1.isTypeLiteral(node1), elements2.isTypeLiteral(node2)) &&
- strategy.testTypes(
- node1,
- node2,
- 'getTypeLiteralType($index)',
- elements1.getTypeLiteralType(node1),
- elements2.getTypeLiteralType(node2)) &&
- strategy.test(
- node1,
- node2,
- 'getSendStructure($index)',
- elements1.getSendStructure(node1),
- elements2.getSendStructure(node2),
- areSendStructuresEquivalent);
- }
-
- @override
- visitNewExpression(NewExpression node1) {
- visitExpression(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- NewExpression node2 = indices2.nodeList[index];
- success = strategy.test(
- node1,
- node2,
- 'getNewStructure($index)',
- elements1.getNewStructure(node1),
- elements2.getNewStructure(node2),
- areNewStructuresEquivalent);
- }
-
- @override
- visitSendSet(SendSet node1) {
- visitSend(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- SendSet node2 = indices2.nodeList[index];
- success = strategy.test(
- node1,
- node2,
- 'getGetterSelectorInComplexSendSet($index)',
- elements1.getGetterSelectorInComplexSendSet(node1),
- elements2.getGetterSelectorInComplexSendSet(node2),
- areSelectorsEquivalent) &&
- strategy.test(
- node1,
- node2,
- 'getOperatorSelectorInComplexSendSet($index)',
- elements1.getOperatorSelectorInComplexSendSet(node1),
- elements2.getOperatorSelectorInComplexSendSet(node2),
- areSelectorsEquivalent);
- }
-
- @override
- visitFunctionExpression(FunctionExpression node1) {
- visitNode(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- FunctionExpression node2 = indices2.nodeList[index];
- if (elements1[node1] is! FunctionElement) {
- // [getFunctionDefinition] is currently stored in [] which doesn't always
- // contain a [FunctionElement].
- return;
- }
- success = strategy.testElements(
- node1,
- node2,
- 'getFunctionDefinition($index)',
- elements1.getFunctionDefinition(node1),
- elements2.getFunctionDefinition(node2));
- }
-
- @override
- visitForIn(ForIn node1) {
- visitLoop(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- ForIn node2 = indices2.nodeList[index];
- success = strategy.testElements(node1, node2, 'getForInVariable($index)',
- elements1.getForInVariable(node1), elements2.getForInVariable(node2));
- }
-
- @override
- visitRedirectingFactoryBody(RedirectingFactoryBody node1) {
- visitStatement(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- RedirectingFactoryBody node2 = indices2.nodeList[index];
- success = strategy.testElements(
- node1,
- node2,
- 'getRedirectingTargetConstructor($index)',
- elements1.getRedirectingTargetConstructor(node1),
- elements2.getRedirectingTargetConstructor(node2));
- }
-
- @override
- visitGotoStatement(GotoStatement node1) {
- visitStatement(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- GotoStatement node2 = indices2.nodeList[index];
- success = testJumpTargets(node1, node2, 'getTargetOf($index)',
- elements1.getTargetOf(node1), elements2.getTargetOf(node2));
- if (!success) return;
- if (node1.target == null && node2.target == null) {
- return;
- }
- success = testLabelDefinitions(node1, node2, 'getTarget($index)',
- elements1.getTargetLabel(node1), elements2.getTargetLabel(node2));
- }
-
- @override
- visitLabel(Label node1) {
- visitNode(node1);
- if (!success) return;
- int index = indices1.nodeIndices[node1];
- Label node2 = indices2.nodeList[index];
- success = testLabelDefinitions(
- node1,
- node2,
- 'getLabelDefinition($index)',
- elements1.getLabelDefinition(node1),
- elements2.getLabelDefinition(node2));
- }
-}
-
-class NodeEquivalenceVisitor implements Visitor1<bool, Node> {
- final TestStrategy strategy;
-
- const NodeEquivalenceVisitor([this.strategy = const TestStrategy()]);
-
- bool testNodes(dynamic object1, dynamic object2, String property, Node node1,
- Node node2) {
- return strategy.test(object1, object2, property, node1, node2,
- (Node n1, Node n2) {
- if (n1 == n2) return true;
- if (n1 == null || n2 == null) return false;
- return n1.accept1(this, n2);
- });
- }
-
- bool testNodeLists(dynamic object1, dynamic object2, String property,
- Link<Node> list1, Link<Node> list2) {
- return strategy.test(object1, object2, property, list1, list2,
- (Link<Node> l1, Link<Node> l2) {
- if (l1 == l2) return true;
- if (l1 == null || l2 == null) return false;
- while (l1.isNotEmpty && l2.isNotEmpty) {
- if (!l1.head.accept1(this, l2.head)) {
- return false;
- }
- l1 = l1.tail;
- l2 = l2.tail;
- }
- return l1.isEmpty && l2.isEmpty;
- });
- }
-
- bool testTokens(dynamic object1, dynamic object2, String property,
- Token token1, Token token2) {
- return strategy.test(object1, object2, property, token1, token2,
- (Token t1, Token t2) {
- if (t1 == t2) return true;
- if (t1 == null || t2 == null) return false;
- return strategy.test(
- t1, t2, 'charOffset', t1.charOffset, t2.charOffset) &&
- strategy.test(t1, t2, 'info', t1.type, t2.type) &&
- strategy.test(t1, t2, 'value', t1.lexeme, t2.lexeme);
- });
- }
-
- @override
- bool visitAssert(Assert node1, covariant Assert node2) {
- return testTokens(node1, node2, 'assertToken', node1.assertToken,
- node2.assertToken) &&
- testNodes(
- node1, node2, 'condition', node1.condition, node2.condition) &&
- testNodes(node1, node2, 'message', node1.message, node2.message);
- }
-
- @override
- bool visitAsyncForIn(AsyncForIn node1, covariant AsyncForIn node2) {
- return visitForIn(node1, node2) &&
- testTokens(
- node1, node2, 'awaitToken', node1.awaitToken, node2.awaitToken);
- }
-
- @override
- bool visitAsyncModifier(AsyncModifier node1, covariant AsyncModifier node2) {
- return testTokens(
- node1, node2, 'asyncToken', node1.asyncToken, node2.asyncToken) &&
- testTokens(node1, node2, 'starToken', node1.starToken, node2.starToken);
- }
-
- @override
- bool visitAwait(Await node1, covariant Await node2) {
- return testTokens(
- node1, node2, 'awaitToken', node1.awaitToken, node2.awaitToken) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitBlock(Block node1, covariant Block node2) {
- return testNodes(
- node1, node2, 'statements', node1.statements, node2.statements);
- }
-
- @override
- bool visitBreakStatement(
- BreakStatement node1, covariant BreakStatement node2) {
- return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
- node2.keywordToken) &&
- testNodes(node1, node2, 'target', node1.target, node2.target);
- }
-
- @override
- bool visitCascade(Cascade node1, covariant Cascade node2) {
- return testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitCascadeReceiver(
- CascadeReceiver node1, covariant CascadeReceiver node2) {
- return testTokens(node1, node2, 'cascadeOperator', node1.cascadeOperator,
- node2.cascadeOperator) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitCaseMatch(CaseMatch node1, covariant CaseMatch node2) {
- return testTokens(node1, node2, 'caseKeyword', node1.caseKeyword,
- node2.caseKeyword) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitCatchBlock(CatchBlock node1, covariant CatchBlock node2) {
- return testTokens(node1, node2, 'catchKeyword', node1.catchKeyword,
- node2.catchKeyword) &&
- testTokens(
- node1, node2, 'onKeyword', node1.onKeyword, node2.onKeyword) &&
- testNodes(node1, node2, 'type', node1.type, node2.type) &&
- testNodes(node1, node2, 'formals', node1.formals, node2.formals) &&
- testNodes(node1, node2, 'block', node1.block, node2.block);
- }
-
- @override
- bool visitClassNode(ClassNode node1, covariant ClassNode node2) {
- return testTokens(
- node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
- testTokens(node1, node2, 'extendsKeyword', node1.extendsKeyword,
- node2.extendsKeyword) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(
- node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
- testNodes(node1, node2, 'name', node1.name, node2.name) &&
- testNodes(
- node1, node2, 'superclass', node1.superclass, node2.superclass) &&
- testNodes(
- node1, node2, 'interfaces', node1.interfaces, node2.interfaces) &&
- testNodes(node1, node2, 'typeParameters', node1.typeParameters,
- node2.typeParameters) &&
- testNodes(node1, node2, 'body', node1.body, node2.body);
- }
-
- @override
- bool visitCombinator(Combinator node1, covariant Combinator node2) {
- return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
- node2.keywordToken) &&
- testNodes(
- node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
- }
-
- @override
- bool visitConditional(Conditional node1, covariant Conditional node2) {
- return testTokens(node1, node2, 'questionToken', node1.questionToken,
- node2.questionToken) &&
- testTokens(
- node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
- testNodes(
- node1, node2, 'condition', node1.condition, node2.condition) &&
- testNodes(node1, node2, 'thenExpression', node1.thenExpression,
- node2.thenExpression) &&
- testNodes(node1, node2, 'elseExpression', node1.elseExpression,
- node2.elseExpression);
- }
-
- @override
- bool visitConditionalUri(
- ConditionalUri node1, covariant ConditionalUri node2) {
- return testTokens(node1, node2, 'ifToken', node1.ifToken, node2.ifToken) &&
- testNodes(node1, node2, 'key', node1.key, node2.key) &&
- testNodes(node1, node2, 'value', node1.value, node2.value) &&
- testNodes(node1, node2, 'uri', node1.uri, node2.uri);
- }
-
- @override
- bool visitContinueStatement(
- ContinueStatement node1, covariant ContinueStatement node2) {
- return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
- node2.keywordToken) &&
- testNodes(node1, node2, 'target', node1.target, node2.target);
- }
-
- @override
- bool visitDoWhile(DoWhile node1, covariant DoWhile node2) {
- return testTokens(
- node1, node2, 'doKeyword', node1.doKeyword, node2.doKeyword) &&
- testTokens(node1, node2, 'whileKeyword', node1.whileKeyword,
- node2.whileKeyword) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(
- node1, node2, 'condition', node1.condition, node2.condition) &&
- testNodes(node1, node2, 'body', node1.body, node2.body);
- }
-
- @override
- bool visitDottedName(DottedName node1, covariant DottedName node2) {
- return testTokens(node1, node2, 'token', node1.token, node2.token) &&
- testNodes(
- node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
- }
-
- @override
- bool visitEmptyStatement(
- EmptyStatement node1, covariant EmptyStatement node2) {
- return testTokens(node1, node2, 'semicolonToken', node1.semicolonToken,
- node2.semicolonToken);
- }
-
- @override
- bool visitEnum(Enum node1, covariant Enum node2) {
- return testTokens(
- node1, node2, 'enumToken', node1.enumToken, node2.enumToken) &&
- testNodes(node1, node2, 'name', node1.name, node2.name) &&
- testNodes(node1, node2, 'names', node1.names, node2.names);
- }
-
- @override
- bool visitExport(Export node1, covariant Export node2) {
- return visitLibraryDependency(node1, node2) &&
- testTokens(node1, node2, 'exportKeyword', node1.exportKeyword,
- node2.exportKeyword);
- }
-
- @override
- bool visitExpressionStatement(
- ExpressionStatement node1, covariant ExpressionStatement node2) {
- return testTokens(
- node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitFor(For node1, covariant For node2) {
- return testTokens(
- node1, node2, 'forToken', node1.forToken, node2.forToken) &&
- testNodes(node1, node2, 'initializer', node1.initializer,
- node2.initializer) &&
- testNodes(node1, node2, 'conditionStatement', node1.conditionStatement,
- node2.conditionStatement) &&
- testNodes(node1, node2, 'update', node1.update, node2.update) &&
- testNodes(node1, node2, 'body', node1.body, node2.body);
- }
-
- @override
- bool visitForIn(ForIn node1, covariant ForIn node2) {
- return testNodes(
- node1, node2, 'condition', node1.condition, node2.condition) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression) &&
- testNodes(node1, node2, 'body', node1.body, node2.body) &&
- testNodes(node1, node2, 'declaredIdentifier', node1.declaredIdentifier,
- node2.declaredIdentifier);
- }
-
- @override
- bool visitFunctionDeclaration(
- FunctionDeclaration node1, covariant FunctionDeclaration node2) {
- return testNodes(node1, node2, 'function', node1.function, node2.function);
- }
-
- @override
- bool visitFunctionExpression(
- FunctionExpression node1, covariant FunctionExpression node2) {
- return testTokens(
- node1, node2, 'getOrSet', node1.getOrSet, node2.getOrSet) &&
- testNodes(node1, node2, 'name', node1.name, node2.name) &&
- testNodes(
- node1, node2, 'parameters', node1.parameters, node2.parameters) &&
- testNodes(node1, node2, 'body', node1.body, node2.body) &&
- testNodes(
- node1, node2, 'returnType', node1.returnType, node2.returnType) &&
- testNodes(
- node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
- testNodes(node1, node2, 'initializers', node1.initializers,
- node2.initializers) &&
- testNodes(node1, node2, 'asyncModifier', node1.asyncModifier,
- node2.asyncModifier);
- }
-
- @override
- bool visitGotoStatement(GotoStatement node1, covariant GotoStatement node2) {
- return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
- node2.keywordToken) &&
- testTokens(node1, node2, 'semicolonToken', node1.semicolonToken,
- node2.semicolonToken) &&
- testNodes(node1, node2, 'target', node1.target, node2.target);
- }
-
- @override
- bool visitIdentifier(Identifier node1, covariant Identifier node2) {
- return testTokens(node1, node2, 'token', node1.token, node2.token);
- }
-
- @override
- bool visitIf(If node1, covariant If node2) {
- return testTokens(node1, node2, 'ifToken', node1.ifToken, node2.ifToken) &&
- testTokens(
- node1, node2, 'elseToken', node1.elseToken, node2.elseToken) &&
- testNodes(
- node1, node2, 'condition', node1.condition, node2.condition) &&
- testNodes(node1, node2, 'thenPart', node1.thenPart, node2.thenPart) &&
- testNodes(node1, node2, 'elsePart', node1.elsePart, node2.elsePart);
- }
-
- @override
- bool visitImport(Import node1, covariant Import node2) {
- return visitLibraryDependency(node1, node2) &&
- testTokens(node1, node2, 'importKeyword', node1.importKeyword,
- node2.importKeyword) &&
- testNodes(node1, node2, 'prefix', node1.prefix, node2.prefix) &&
- strategy.test(
- node1, node2, 'isDeferred', node1.isDeferred, node2.isDeferred);
- }
-
- @override
- bool visitLabel(Label node1, covariant Label node2) {
- return testTokens(
- node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
- testNodes(
- node1, node2, 'identifier', node1.identifier, node2.identifier);
- }
-
- @override
- bool visitLabeledStatement(
- LabeledStatement node1, covariant LabeledStatement node2) {
- return testNodes(node1, node2, 'labels', node1.labels, node2.labels) &&
- testNodes(node1, node2, 'statement', node1.statement, node2.statement);
- }
-
- @override
- bool visitLibraryDependency(
- LibraryDependency node1, covariant LibraryDependency node2) {
- return visitLibraryTag(node1, node2) &&
- testNodes(node1, node2, 'uri', node1.uri, node2.uri) &&
- testNodes(node1, node2, 'conditionalUris', node1.conditionalUris,
- node2.conditionalUris) &&
- testNodes(
- node1, node2, 'combinators', node1.combinators, node2.combinators);
- }
-
- @override
- bool visitLibraryName(LibraryName node1, covariant LibraryName node2) {
- return visitLibraryTag(node1, node2) &&
- testTokens(node1, node2, 'libraryKeyword', node1.libraryKeyword,
- node2.libraryKeyword) &&
- testNodes(node1, node2, 'name', node1.name, node2.name);
- }
-
- @override
- bool visitLibraryTag(LibraryTag node1, covariant LibraryTag node2) {
- // TODO(johnniwinther): Check metadata?
- return true;
- }
-
- @override
- bool visitLiteral(Literal node1, covariant Literal node2) {
- return testTokens(node1, node2, 'token', node1.token, node2.token);
- }
-
- @override
- bool visitLiteralBool(LiteralBool node1, covariant LiteralBool node2) {
- return visitLiteral(node1, node2);
- }
-
- @override
- bool visitLiteralDouble(LiteralDouble node1, covariant LiteralDouble node2) {
- return visitLiteral(node1, node2);
- }
-
- @override
- bool visitLiteralInt(LiteralInt node1, covariant LiteralInt node2) {
- return visitLiteral(node1, node2);
- }
-
- @override
- bool visitLiteralList(LiteralList node1, covariant LiteralList node2) {
- return testTokens(node1, node2, 'constKeyword', node1.constKeyword,
- node2.constKeyword) &&
- testNodes(node1, node2, 'typeArguments', node1.typeArguments,
- node2.typeArguments) &&
- testNodes(node1, node2, 'elements', node1.elements, node2.elements);
- }
-
- @override
- bool visitLiteralMap(LiteralMap node1, covariant LiteralMap node2) {
- return testTokens(node1, node2, 'constKeyword', node1.constKeyword,
- node2.constKeyword) &&
- testNodes(node1, node2, 'typeArguments', node1.typeArguments,
- node2.typeArguments) &&
- testNodes(node1, node2, 'entries', node1.entries, node2.entries);
- }
-
- @override
- bool visitLiteralMapEntry(
- LiteralMapEntry node1, covariant LiteralMapEntry node2) {
- return testTokens(
- node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
- testNodes(node1, node2, 'key', node1.key, node2.key) &&
- testNodes(node1, node2, 'value', node1.value, node2.value);
- }
-
- @override
- bool visitLiteralNull(LiteralNull node1, covariant LiteralNull node2) {
- return visitLiteral(node1, node2);
- }
-
- @override
- bool visitLiteralString(LiteralString node1, covariant LiteralString node2) {
- return testTokens(node1, node2, 'token', node1.token, node2.token) &&
- strategy.test(
- node1, node2, 'dartString', node1.dartString, node2.dartString);
- }
-
- @override
- bool visitLiteralSymbol(LiteralSymbol node1, covariant LiteralSymbol node2) {
- return testTokens(
- node1, node2, 'hashToken', node1.hashToken, node2.hashToken) &&
- testNodes(
- node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
- }
-
- @override
- bool visitLoop(Loop node1, covariant Loop node2) {
- return testNodes(
- node1, node2, 'condition', node1.condition, node2.condition) &&
- testNodes(node1, node2, 'body', node1.body, node2.body);
- }
-
- @override
- bool visitMetadata(Metadata node1, covariant Metadata node2) {
- return testTokens(node1, node2, 'token', node1.token, node2.token) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitMixinApplication(
- MixinApplication node1, covariant MixinApplication node2) {
- return testNodes(
- node1, node2, 'superclass', node1.superclass, node2.superclass) &&
- testNodes(node1, node2, 'mixins', node1.mixins, node2.mixins);
- }
-
- @override
- bool visitModifiers(Modifiers node1, covariant Modifiers node2) {
- return strategy.test(node1, node2, 'flags', node1.flags, node2.flags) &&
- testNodes(node1, node2, 'nodes', node1.nodes, node2.nodes);
- }
-
- @override
- bool visitNamedArgument(NamedArgument node1, covariant NamedArgument node2) {
- return testTokens(
- node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
- testNodes(node1, node2, 'name', node1.name, node2.name) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitNamedMixinApplication(
- NamedMixinApplication node1, covariant NamedMixinApplication node2) {
- return testTokens(node1, node2, 'classKeyword', node1.classKeyword,
- node2.classKeyword) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(node1, node2, 'name', node1.name, node2.name) &&
- testNodes(node1, node2, 'typeParameters', node1.typeParameters,
- node2.typeParameters) &&
- testNodes(
- node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
- testNodes(node1, node2, 'mixinApplication', node1.mixinApplication,
- node2.mixinApplication) &&
- testNodes(
- node1, node2, 'interfaces', node1.interfaces, node2.interfaces);
- }
-
- @override
- bool visitNewExpression(NewExpression node1, covariant NewExpression node2) {
- return testTokens(
- node1, node2, 'newToken', node1.newToken, node2.newToken) &&
- testNodes(node1, node2, 'send', node1.send, node2.send);
- }
-
- @override
- bool visitNodeList(NodeList node1, covariant NodeList node2) {
- return testTokens(
- node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- strategy.test(
- node1, node2, 'delimiter', node1.delimiter, node2.delimiter) &&
- testNodeLists(node1, node2, 'nodes', node1.nodes, node2.nodes);
- }
-
- @override
- bool visitOperator(Operator node1, covariant Operator node2) {
- return visitIdentifier(node1, node2);
- }
-
- @override
- bool visitParenthesizedExpression(
- ParenthesizedExpression node1, covariant ParenthesizedExpression node2) {
- return testTokens(
- node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitPart(Part node1, covariant Part node2) {
- return visitLibraryTag(node1, node2) &&
- testTokens(node1, node2, 'partKeyword', node1.partKeyword,
- node2.partKeyword) &&
- testNodes(node1, node2, 'uri', node1.uri, node2.uri);
- }
-
- @override
- bool visitPartOf(PartOf node1, covariant PartOf node2) {
- // TODO(johnniwinther): Check metadata?
- return testTokens(node1, node2, 'partKeyword', node1.partKeyword,
- node2.partKeyword) &&
- testNodes(node1, node2, 'name', node1.name, node2.name);
- }
-
- @override
- bool visitPostfix(Postfix node1, covariant Postfix node2) {
- return visitNodeList(node1, node2);
- }
-
- @override
- bool visitPrefix(Prefix node1, covariant Prefix node2) {
- return visitNodeList(node1, node2);
- }
-
- @override
- bool visitRedirectingFactoryBody(
- RedirectingFactoryBody node1, covariant RedirectingFactoryBody node2) {
- return testTokens(
- node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(node1, node2, 'constructorReference',
- node1.constructorReference, node2.constructorReference);
- }
-
- @override
- bool visitRethrow(Rethrow node1, covariant Rethrow node2) {
- return testTokens(
- node1, node2, 'throwToken', node1.throwToken, node2.throwToken) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken);
- }
-
- @override
- bool visitReturn(Return node1, covariant Return node2) {
- return testTokens(
- node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitSend(Send node1, covariant Send node2) {
- return strategy.test(node1, node2, 'isConditional', node1.isConditional,
- node2.isConditional) &&
- testNodes(node1, node2, 'receiver', node1.receiver, node2.receiver) &&
- testNodes(node1, node2, 'selector', node1.selector, node2.selector) &&
- testNodes(node1, node2, 'argumentsNode', node1.argumentsNode,
- node2.argumentsNode);
- }
-
- @override
- bool visitSendSet(SendSet node1, covariant SendSet node2) {
- return visitSend(node1, node2) &&
- testNodes(node1, node2, 'assignmentOperator', node1.assignmentOperator,
- node2.assignmentOperator);
- }
-
- @override
- bool visitStringInterpolation(
- StringInterpolation node1, covariant StringInterpolation node2) {
- return testNodes(node1, node2, 'string', node1.string, node2.string) &&
- testNodes(node1, node2, 'parts', node1.parts, node2.parts);
- }
-
- @override
- bool visitStringInterpolationPart(
- StringInterpolationPart node1, covariant StringInterpolationPart node2) {
- return testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitStringJuxtaposition(
- StringJuxtaposition node1, covariant StringJuxtaposition node2) {
- return testNodes(node1, node2, 'first', node1.first, node2.first) &&
- testNodes(node1, node2, 'second', node1.second, node2.second);
- }
-
- @override
- bool visitSwitchCase(SwitchCase node1, covariant SwitchCase node2) {
- return testTokens(node1, node2, 'defaultKeyword', node1.defaultKeyword,
- node2.defaultKeyword) &&
- testTokens(
- node1, node2, 'startToken', node1.startToken, node2.startToken) &&
- testNodes(node1, node2, 'labelsAndCases', node1.labelsAndCases,
- node2.labelsAndCases) &&
- testNodes(
- node1, node2, 'statements', node1.statements, node2.statements);
- }
-
- @override
- bool visitSwitchStatement(
- SwitchStatement node1, covariant SwitchStatement node2) {
- return testTokens(node1, node2, 'switchKeyword', node1.switchKeyword,
- node2.switchKeyword) &&
- testNodes(node1, node2, 'parenthesizedExpression',
- node1.parenthesizedExpression, node2.parenthesizedExpression) &&
- testNodes(node1, node2, 'cases', node1.cases, node2.cases);
- }
-
- @override
- bool visitSyncForIn(SyncForIn node1, covariant SyncForIn node2) {
- return visitForIn(node1, node2);
- }
-
- @override
- bool visitThrow(Throw node1, covariant Throw node2) {
- return testTokens(
- node1, node2, 'throwToken', node1.throwToken, node2.throwToken) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitTryStatement(TryStatement node1, covariant TryStatement node2) {
- return testTokens(
- node1, node2, 'tryKeyword', node1.tryKeyword, node2.tryKeyword) &&
- testTokens(node1, node2, 'finallyKeyword', node1.finallyKeyword,
- node2.finallyKeyword) &&
- testNodes(node1, node2, 'tryBlock', node1.tryBlock, node2.tryBlock) &&
- testNodes(node1, node2, 'catchBlocks', node1.catchBlocks,
- node2.catchBlocks) &&
- testNodes(node1, node2, 'finallyBlock', node1.finallyBlock,
- node2.finallyBlock);
- }
-
- @override
- bool visitNominalTypeAnnotation(
- NominalTypeAnnotation node1, covariant NominalTypeAnnotation node2) {
- return testNodes(
- node1, node2, 'typeName', node1.typeName, node2.typeName) &&
- testNodes(node1, node2, 'typeArguments', node1.typeArguments,
- node2.typeArguments);
- }
-
- @override
- bool visitFunctionTypeAnnotation(
- FunctionTypeAnnotation node1, covariant FunctionTypeAnnotation node2) {
- return testNodes(
- node1, node2, 'returnType', node1.returnType, node2.returnType) &&
- testNodes(node1, node2, 'formals', node1.formals, node2.formals) &&
- testNodes(node1, node2, 'typeParameters', node1.typeParameters,
- node2.typeParameters);
- }
-
- @override
- bool visitTypeVariable(TypeVariable node1, covariant TypeVariable node2) {
- return testNodes(node1, node2, 'name', node1.name, node2.name) &&
- testNodes(node1, node2, 'bound', node1.bound, node2.bound);
- }
-
- @override
- bool visitTypedef(Typedef node1, covariant Typedef node2) {
- return testTokens(node1, node2, 'typedefKeyword', node1.typedefKeyword,
- node2.typedefKeyword) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(
- node1, node2, 'returnType', node1.returnType, node2.returnType) &&
- testNodes(node1, node2, 'name', node1.name, node2.name) &&
- testNodes(node1, node2, 'typeParameters', node1.templateParameters,
- node2.templateParameters) &&
- testNodes(node1, node2, 'formals', node1.formals, node2.formals);
- }
-
- @override
- bool visitVariableDefinitions(
- VariableDefinitions node1, covariant VariableDefinitions node2) {
- return testNodes(
- node1, node2, 'metadata', node1.metadata, node2.metadata) &&
- testNodes(node1, node2, 'type', node1.type, node2.type) &&
- testNodes(
- node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
- testNodes(
- node1, node2, 'definitions', node1.definitions, node2.definitions);
- }
-
- @override
- bool visitWhile(While node1, covariant While node2) {
- return testTokens(node1, node2, 'whileKeyword', node1.whileKeyword,
- node2.whileKeyword) &&
- testNodes(
- node1, node2, 'condition', node1.condition, node2.condition) &&
- testNodes(node1, node2, 'body', node1.body, node2.body);
- }
-
- @override
- bool visitYield(Yield node1, covariant Yield node2) {
- return testTokens(
- node1, node2, 'yieldToken', node1.yieldToken, node2.yieldToken) &&
- testTokens(
- node1, node2, 'starToken', node1.starToken, node2.starToken) &&
- testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
- testNodes(
- node1, node2, 'expression', node1.expression, node2.expression);
- }
-
- @override
- bool visitNode(Node node1, covariant Node node2) {
- throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
- }
-
- @override
- bool visitExpression(Expression node1, covariant Expression node2) {
- throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
- }
-
- @override
- bool visitStatement(Statement node1, covariant Statement node2) {
- throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
- }
-
- @override
- bool visitStringNode(StringNode node1, covariant StringNode node2) {
- throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
- }
-
- @override
- bool visitTypeAnnotation(
- TypeAnnotation node1, covariant TypeAnnotation node2) {
- throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
- }
-}
-
-bool areMetadataAnnotationsEquivalent(
- MetadataAnnotation metadata1, MetadataAnnotation metadata2) {
- if (metadata1 == metadata2) return true;
- if (metadata1 == null || metadata2 == null) return false;
- return areElementsEquivalent(
- metadata1.annotatedElement, metadata2.annotatedElement) &&
- areConstantsEquivalent(metadata1.constant, metadata2.constant);
-}
-
-class NativeBehaviorFilters {
- static const int NORMAL_TYPE = 0;
- static const int THIS_TYPE = 1;
- static const int SPECIAL_TYPE = 2;
-
- static int getTypeKind(var type) {
- if (type is DartType) {
- // TODO(johnniwinther): Remove this when annotation are no longer resolved
- // to this-types.
- if (type is InterfaceType &&
- type.typeArguments.isNotEmpty &&
- type.typeArguments.first is TypeVariableType) {
- return THIS_TYPE;
- }
- return NORMAL_TYPE;
- }
- return SPECIAL_TYPE;
- }
-
- /// Returns a list of the non-this-type [ResolutionDartType]s in [types].
- static List<ResolutionDartType> filterDartTypes(List types) {
- return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
- }
-
- // TODO(johnniwinther): Remove this when annotation are no longer resolved
- // to this-types.
- /// Returns a list of the classes of this-types in [types].
- static List<Element> filterThisTypes(List types) {
- return types
- .where((type) => getTypeKind(type) == THIS_TYPE)
- .map((type) => type.element)
- .toList();
- }
-
- /// Returns a list of the names of the [SpecialType]s in [types].
- static List<String> filterSpecialTypes(List types) {
- return types.where((type) => getTypeKind(type) == SPECIAL_TYPE).map((t) {
- SpecialType type = t;
- return type.name;
- }).toList();
- }
-}
-
-/// Visitor that computes a node-index mapping.
-class AstIndexComputer extends Visitor {
- final Map<Node, int> nodeIndices = <Node, int>{};
- final List<Node> nodeList = <Node>[];
-
- @override
- visitNode(Node node) {
- nodeIndices.putIfAbsent(node, () {
- // Some nodes (like Modifier and empty NodeList) can be reused.
- nodeList.add(node);
- return nodeIndices.length;
- });
- node.visitChildren(this);
- }
-}
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence.dart b/tests/compiler/dart2js/equivalence/id_equivalence.dart
index c2828f6..6564b65 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence.dart
@@ -119,6 +119,8 @@
id = new NodeId(offset, IdKind.node);
expected = text;
}
+ // Remove newlines.
+ expected = expected.replaceAll(new RegExp(r'\s*(\n\s*)+\s*'), '');
return new IdValue(id, expected);
}
}
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 6c824ed..58f7e1d 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -95,6 +95,26 @@
Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
{bool verbose});
+abstract class DataComputer {
+ void setup();
+
+ /// Function that computes a data mapping for [member].
+ ///
+ /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
+ /// for the data origin.
+ void computeMemberData(
+ Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
+ {bool verbose});
+
+ /// Function that computes a data mapping for [cls].
+ ///
+ /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
+ /// for the data origin.
+ void computeClassData(
+ Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
+ {bool verbose});
+}
+
const String stopAfterTypeInference = 'stopAfterTypeInference';
/// Reports [message] as an error using [spannable] as error location.
@@ -124,6 +144,7 @@
ComputeMemberDataFunction computeMemberData,
{List<String> options: const <String>[],
bool verbose: false,
+ bool testFrontend: false,
bool forUserLibrariesOnly: true,
bool skipUnprocessedMembers: false,
bool skipFailedCompilations: false,
@@ -142,7 +163,9 @@
Expect.isTrue(result.isSuccess, "Unexpected compilation error.");
}
Compiler compiler = result.compiler;
- ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+ ClosedWorld closedWorld = testFrontend
+ ? compiler.resolutionWorldBuilder.closedWorldForTesting
+ : compiler.backendClosedWorldForTesting;
ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
CommonElements commonElements = closedWorld.commonElements;
@@ -456,6 +479,7 @@
List<String> options: const <String>[],
List<String> args: const <String>[],
Directory libDirectory: null,
+ bool testFrontend: false,
bool forUserLibrariesOnly: true,
Callback setUpFunction,
ComputeClassDataFunction computeClassDataFromKernel,
@@ -560,6 +584,7 @@
computeClassData: computeClassDataFromKernel,
options: options,
verbose: verbose,
+ testFrontend: testFrontend,
forUserLibrariesOnly: forUserLibrariesOnly,
globalIds: annotations.globalData.keys);
if (await checkCode(
@@ -584,6 +609,7 @@
computeClassData: computeClassDataFromKernel,
options: options,
verbose: verbose,
+ testFrontend: testFrontend,
forUserLibrariesOnly: forUserLibrariesOnly,
globalIds: annotations.globalData.keys);
if (await checkCode(
@@ -607,6 +633,7 @@
computeClassData: computeClassDataFromKernel,
options: options,
verbose: verbose,
+ testFrontend: testFrontend,
forUserLibrariesOnly: forUserLibrariesOnly,
globalIds: annotations.globalData.keys);
if (await checkCode(
diff --git a/tests/compiler/dart2js/equivalence/show_helper.dart b/tests/compiler/dart2js/equivalence/show_helper.dart
index fa2eb40..0cdad7d 100644
--- a/tests/compiler/dart2js/equivalence/show_helper.dart
+++ b/tests/compiler/dart2js/equivalence/show_helper.dart
@@ -27,6 +27,7 @@
show(ArgResults argResults, ComputeMemberDataFunction computeKernelData,
{ComputeClassDataFunction computeKernelClassData,
+ bool testFrontend: false,
List<String> options: const <String>[]}) async {
if (argResults.wasParsed('colors')) {
useColors = argResults['colors'];
@@ -60,6 +61,7 @@
CompiledData data = await computeData(entryPoint, const {}, computeKernelData,
computeClassData: computeKernelClassData,
options: options,
+ testFrontend: testFrontend,
forUserLibrariesOnly: false,
skipUnprocessedMembers: true,
skipFailedCompilations: true,
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
new file mode 100644
index 0000000..8f67a76
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -0,0 +1,371 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[
+ testAnonymousAsync(0),
+ testAnonymousAsyncStar(0),
+ testAnonymousSyncStar(0),
+ testAsync(0),
+ testAsyncForIn(1),
+ testAsyncForInTyped(1),
+ testAsyncStar(0),
+ testLocalAsync(0),
+ testLocalAsyncStar(0),
+ testLocalSyncStar(0),
+ testSyncStar(0)],
+ type=[inst:JSNull]
+*/
+main() {
+ testSyncStar();
+ testAsync();
+ testAsyncStar();
+ testLocalSyncStar();
+ testLocalAsync();
+ testLocalAsyncStar();
+ testAnonymousSyncStar();
+ testAnonymousAsync();
+ testAnonymousAsyncStar();
+ testAsyncForIn(null);
+ testAsyncForInTyped(null);
+}
+
+/*element: testSyncStar:
+ static=[
+ _IterationMarker.endOfIteration,
+ _IterationMarker.uncaughtError,
+ _IterationMarker.yieldStar,
+ _makeSyncStarIterable<dynamic>(1)]
+*/
+testSyncStar() sync* {}
+
+/*element: testAsync:
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<dynamic>(0),
+ _wrapJsFunctionForAsync]
+*/
+testAsync() async {}
+
+/*element: testAsyncStar:static=[StreamIterator.,
+ _IterationMarker.yieldSingle,
+ _IterationMarker.yieldStar,
+ _asyncStarHelper,
+ _makeAsyncStarStreamController<dynamic>(1),
+ _streamOfController,
+ _wrapJsFunctionForAsync]*/
+testAsyncStar() async* {}
+
+/*kernel.element: testLocalSyncStar:
+ static=[
+ _IterationMarker.endOfIteration,
+ _IterationMarker.uncaughtError,
+ _IterationMarker.yieldStar,
+ _makeSyncStarIterable<dynamic>(1),
+ def:local],
+ type=[inst:Function]
+*/
+/*strong.element: testLocalSyncStar:
+ static=[
+ _IterationMarker.endOfIteration,
+ _IterationMarker.uncaughtError,
+ _IterationMarker.yieldStar,
+ _makeSyncStarIterable<Null>(1),
+ computeSignature,
+ def:local,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[
+ inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalSyncStar() {
+ local() sync* {}
+ return local;
+}
+
+/*kernel.element: testLocalAsync:
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<dynamic>(0),
+ _wrapJsFunctionForAsync,
+ def:local],
+ type=[inst:Function]
+*/
+/*strong.element: testLocalAsync:
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<Null>(0),
+ _wrapJsFunctionForAsync,
+ computeSignature,
+ def:local,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[
+ inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalAsync() {
+ local() async {}
+ return local;
+}
+
+/*kernel.element: testLocalAsyncStar:
+ static=[
+ StreamIterator.,
+ _IterationMarker.yieldSingle,
+ _IterationMarker.yieldStar,
+ _asyncStarHelper,
+ _makeAsyncStarStreamController<dynamic>(1),
+ _streamOfController,
+ _wrapJsFunctionForAsync,
+ def:local],
+ type=[inst:Function]
+*/
+/*strong.element: testLocalAsyncStar:
+ static=[
+ StreamIterator.,
+ _IterationMarker.yieldSingle,
+ _IterationMarker.yieldStar,
+ _asyncStarHelper,
+ _makeAsyncStarStreamController<Null>(1),
+ _streamOfController,
+ _wrapJsFunctionForAsync,
+ computeSignature,
+ def:local,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[
+ inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalAsyncStar() {
+ local() async* {}
+ return local;
+}
+
+/*kernel.element: testAnonymousSyncStar:
+ static=[
+ _IterationMarker.endOfIteration,
+ _IterationMarker.uncaughtError,
+ _IterationMarker.yieldStar,
+ _makeSyncStarIterable<dynamic>(1),
+ def:<anonymous>],
+ type=[
+ check:Iterable<dynamic>,
+ inst:Function]
+*/
+/*strong.element: testAnonymousSyncStar:
+ static=[
+ _IterationMarker.endOfIteration,
+ _IterationMarker.uncaughtError,
+ _IterationMarker.yieldStar,
+ _makeSyncStarIterable<Null>(1),
+ computeSignature,
+ def:<anonymous>,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[
+ inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]
+*/
+testAnonymousSyncStar() {
+ return () sync* {};
+}
+
+/*kernel.element: testAnonymousAsync:
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<dynamic>(0),
+ _wrapJsFunctionForAsync,
+ def:<anonymous>],
+ type=[
+ check:Future<dynamic>,
+ inst:Function]
+*/
+/*strong.element: testAnonymousAsync:
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<Null>(0),
+ _wrapJsFunctionForAsync,
+ computeSignature,
+ def:<anonymous>,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[
+ inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]
+*/
+testAnonymousAsync() {
+ return () async {};
+}
+
+/*kernel.element: testAnonymousAsyncStar:
+ static=[
+ StreamIterator.,
+ _IterationMarker.yieldSingle,
+ _IterationMarker.yieldStar,
+ _asyncStarHelper,
+ _makeAsyncStarStreamController<dynamic>(1),
+ _streamOfController,
+ _wrapJsFunctionForAsync,
+ def:<anonymous>],
+ type=[
+ check:Stream<dynamic>,
+ inst:Function]
+*/
+/*strong.element: testAnonymousAsyncStar:
+ static=[
+ StreamIterator.,
+ _IterationMarker.yieldSingle,
+ _IterationMarker.yieldStar,
+ _asyncStarHelper,
+ _makeAsyncStarStreamController<Null>(1),
+ _streamOfController,
+ _wrapJsFunctionForAsync,
+ computeSignature,
+ def:<anonymous>,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[
+ inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]
+*/
+testAnonymousAsyncStar() {
+ return () async* {};
+}
+
+/*kernel.element: testAsyncForIn:
+ dynamic=[
+ cancel(0),
+ current,
+ moveNext(0)],
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<dynamic>(0),
+ _wrapJsFunctionForAsync],
+ type=[
+ inst:JSNull,
+ inst:Null]
+*/
+/*strong.element: testAsyncForIn:
+ dynamic=[
+ cancel(0),
+ current,
+ moveNext(0)],
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<dynamic>(0),
+ _wrapJsFunctionForAsync],
+ type=[
+ impl:Stream<dynamic>,
+ inst:JSBool,
+ inst:JSNull,
+ inst:Null]
+*/
+testAsyncForIn(o) async {
+ // ignore: UNUSED_LOCAL_VARIABLE
+ await for (var e in o) {}
+}
+
+/*kernel.element: testAsyncForInTyped:
+ dynamic=[
+ cancel(0),
+ current,
+ moveNext(0)],
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<dynamic>(0),
+ _wrapJsFunctionForAsync],
+ type=[
+ check:int,
+ inst:JSNull,
+ inst:Null]
+*/
+/*strong.element: testAsyncForInTyped:
+ dynamic=[
+ cancel(0),
+ current,
+ moveNext(0)],
+ static=[
+ StreamIterator.,
+ _asyncAwait,
+ _asyncRethrow,
+ _asyncReturn,
+ _asyncStartSync,
+ _makeAsyncAwaitCompleter<dynamic>(0),
+ _wrapJsFunctionForAsync],
+ type=[
+ impl:Stream<dynamic>,
+ impl:int,
+ inst:JSBool,
+ inst:JSNull,
+ inst:Null]
+*/
+testAsyncForInTyped(o) async {
+ // ignore: UNUSED_LOCAL_VARIABLE
+ await for (int e in o) {}
+}
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
new file mode 100644
index 0000000..6b3c008
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -0,0 +1,390 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[
+ testAbstractClassWithField(0),
+ testEnum(0),
+ testForwardingConstructor(0),
+ testForwardingConstructorGeneric(0),
+ testForwardingConstructorTyped(0),
+ testGenericMixinInstantiation(0),
+ testGenericNamedMixinInstantiation(0),
+ testInstanceGenericMethod(0),
+ testMixinInstantiation(0),
+ testNamedMixinInstantiation(0),
+ testStaticGenericMethod(0),
+ testSuperCall(0),
+ testSuperClosurization(0),
+ testSuperFieldSet(0),
+ testSuperGet(0),
+ testSuperSetterSet(0)]
+*/
+main() {
+ testSuperCall();
+ testSuperGet();
+ testSuperFieldSet();
+ testSuperSetterSet();
+ testSuperClosurization();
+ testForwardingConstructor();
+ testForwardingConstructorTyped();
+ testForwardingConstructorGeneric();
+ testEnum();
+ testStaticGenericMethod();
+ testInstanceGenericMethod();
+ testAbstractClassWithField();
+ testMixinInstantiation();
+ testNamedMixinInstantiation();
+ testGenericMixinInstantiation();
+ testGenericNamedMixinInstantiation();
+}
+
+/*element: Super1.:static=[Object.(0)]*/
+class Super1 {
+ /*element: Super1.foo:*/
+ foo() {}
+}
+
+class Sub1 extends Super1 {
+ /*element: Sub1.:static=[Super1.(0),Super1.foo(0)]*/
+ Sub1() {
+ super.foo();
+ }
+}
+
+/*element: testSuperCall:static=[Sub1.(0)]*/
+testSuperCall() => new Sub1();
+
+/*element: Super2.:static=[Object.(0)]*/
+class Super2 {
+ /*element: Super2.foo:type=[inst:JSNull]*/
+ var foo;
+}
+
+class Sub2 extends Super2 {
+ /*element: Sub2.:static=[Super2.(0),Super2.foo]*/
+ Sub2() {
+ super.foo;
+ }
+}
+
+/*element: testSuperGet:static=[Sub2.(0)]*/
+testSuperGet() => new Sub2();
+
+/*element: Super3.:static=[Object.(0)]*/
+class Super3 {
+ /*element: Super3.foo:type=[inst:JSNull]*/
+ var foo;
+}
+
+class Sub3 extends Super3 {
+ /*element: Sub3.:static=[Super3.(0),set:Super3.foo],type=[inst:JSBool]*/
+ Sub3() {
+ super.foo = true;
+ }
+}
+
+/*element: testSuperFieldSet:static=[Sub3.(0)]*/
+testSuperFieldSet() => new Sub3();
+
+/*element: Super4.:static=[Object.(0)]*/
+class Super4 {
+ /*element: Super4.foo=:*/
+ set foo(_) {}
+}
+
+class Sub4 extends Super4 {
+ /*element: Sub4.:static=[Super4.(0),set:Super4.foo],type=[inst:JSBool]*/
+ Sub4() {
+ super.foo = true;
+ }
+}
+
+/*element: testSuperSetterSet:static=[Sub4.(0)]*/
+testSuperSetterSet() => new Sub4();
+
+/*element: Super5.:static=[Object.(0)]*/
+class Super5 {
+ /*element: Super5.foo:*/
+ foo() {}
+}
+
+/*element: Sub5.:static=[Super5.(0),Super5.foo]*/
+class Sub5 extends Super5 {
+ Sub5() {
+ super.foo;
+ }
+}
+
+/*element: testSuperClosurization:static=[Sub5.(0)]*/
+testSuperClosurization() => new Sub5();
+
+class EmptyMixin {}
+
+class ForwardingConstructorSuperClass {
+ /*element: ForwardingConstructorSuperClass.:static=[Object.(0)]*/
+ ForwardingConstructorSuperClass(arg);
+}
+
+class ForwardingConstructorClass = ForwardingConstructorSuperClass
+ with EmptyMixin;
+
+/*element: testForwardingConstructor:
+ static=[ForwardingConstructorClass.(1)],
+ type=[inst:JSNull]
+*/
+testForwardingConstructor() => new ForwardingConstructorClass(null);
+
+class ForwardingConstructorTypedSuperClass {
+ /*kernel.element: ForwardingConstructorTypedSuperClass.:
+ static=[Object.(0)],
+ type=[check:int]
+ */
+ /*strong.element: ForwardingConstructorTypedSuperClass.:
+ static=[Object.(0)],
+ type=[inst:JSBool,param:int]
+ */
+ ForwardingConstructorTypedSuperClass(int arg);
+}
+
+class ForwardingConstructorTypedClass = ForwardingConstructorTypedSuperClass
+ with EmptyMixin;
+
+/*element: testForwardingConstructorTyped:
+ static=[ForwardingConstructorTypedClass.(1)],
+ type=[inst:JSNull]
+*/
+testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
+
+class ForwardingConstructorGenericSuperClass<T> {
+ /*kernel.element: ForwardingConstructorGenericSuperClass.:
+ static=[Object.(0)],
+ type=[check:ForwardingConstructorGenericSuperClass.T]
+ */
+ /*strong.element: ForwardingConstructorGenericSuperClass.:
+ static=[
+ Object.(0),
+ checkSubtype,
+ checkSubtypeOfRuntimeType,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:ForwardingConstructorGenericSuperClass.T]
+ */
+ ForwardingConstructorGenericSuperClass(T arg);
+}
+
+class ForwardingConstructorGenericClass<
+ S> = ForwardingConstructorGenericSuperClass<S> with EmptyMixin;
+
+/*element: testForwardingConstructorGeneric:
+ static=[
+ ForwardingConstructorGenericClass.(1),
+ assertIsSubtype,
+ throwTypeError],
+ type=[inst:JSNull]
+*/
+testForwardingConstructorGeneric() {
+ new ForwardingConstructorGenericClass<int>(null);
+}
+
+enum Enum {
+ /*kernel.element: Enum.A:static=[Enum.(2)],
+ type=[
+ check:Enum,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32]
+ */
+ /*strong.element: Enum.A:static=[Enum.(2)],
+ type=[
+ inst:JSBool,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32,
+ param:Enum]
+ */
+ A
+}
+
+/*element: testEnum:static=[Enum.A]*/
+testEnum() => Enum.A;
+
+/*kernel.element: staticGenericMethod:
+ type=[
+ check:List<staticGenericMethod.T>,
+ check:staticGenericMethod.T,
+ inst:List<dynamic>]
+ */
+/*strong.element: staticGenericMethod:
+ static=[
+ checkSubtype,
+ checkSubtypeOfRuntimeType,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ inst:List<staticGenericMethod.T>,
+ param:Object,
+ param:staticGenericMethod.T]
+*/
+List<T> staticGenericMethod<T>(T arg) => [arg];
+
+/*kernel.element: testStaticGenericMethod:
+ static=[staticGenericMethod(1)],
+ type=[inst:JSBool]
+*/
+/*strong.element: testStaticGenericMethod:
+ static=[staticGenericMethod<bool>(1)],
+ type=[inst:JSBool]
+*/
+testStaticGenericMethod() {
+ staticGenericMethod<bool>(true);
+}
+
+/*kernel.element: testInstanceGenericMethod:
+ dynamic=[genericMethod(1)],
+ static=[
+ GenericClass.generative(0),
+ assertIsSubtype,
+ throwTypeError],
+ type=[inst:JSBool]
+*/
+/*strong.element: testInstanceGenericMethod:
+ dynamic=[genericMethod<bool>(1)],
+ static=[
+ GenericClass.generative(0),
+ assertIsSubtype,
+ throwTypeError],
+ type=[inst:JSBool]
+*/
+testInstanceGenericMethod() {
+ new GenericClass<int, String>.generative().genericMethod<bool>(false);
+}
+
+abstract class AbstractClass {
+ // ignore: UNUSED_FIELD
+ final _field;
+
+ /*kernel.element: AbstractClass.:type=[check:AbstractClass,inst:JSNull]*/
+ /*strong.element: AbstractClass.:type=[inst:JSNull]*/
+ factory AbstractClass() => null;
+}
+
+/*element: testAbstractClassWithField:static=[AbstractClass.(0)]*/
+testAbstractClassWithField() => new AbstractClass();
+
+/*element: testMixinInstantiation:static=[Sub.(0)]*/
+testMixinInstantiation() => new Sub();
+
+/*element: testNamedMixinInstantiation:static=[NamedMixin.(0)]*/
+testNamedMixinInstantiation() => new NamedMixin();
+
+/*element: testGenericMixinInstantiation:
+ static=[
+ GenericSub.(0),
+ assertIsSubtype,
+ throwTypeError]
+*/
+testGenericMixinInstantiation() => new GenericSub<int, String>();
+
+/*element: testGenericNamedMixinInstantiation:
+ static=[
+ GenericNamedMixin.(0),
+ assertIsSubtype,
+ throwTypeError]
+*/
+testGenericNamedMixinInstantiation() => new GenericNamedMixin<int, String>();
+
+class Class {
+ /*element: GenericClass.generative:static=[Object.(0)]*/
+ const Class.generative();
+}
+
+class GenericClass<X, Y> {
+ const GenericClass.generative();
+
+ /*kernel.element: GenericClass.genericMethod:
+ type=[
+ check:Map<GenericClass.X,genericMethod.T>,
+ check:genericMethod.T,
+ inst:JSNull,
+ inst:Map<dynamic,dynamic>]
+ */
+ /*strong.element: GenericClass.genericMethod:
+ static=[
+ checkSubtype,
+ checkSubtypeOfRuntimeType,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ inst:Map<GenericClass.X,genericMethod.T>,
+ param:Object,
+ param:genericMethod.T]
+ */
+ Map<X, T> genericMethod<T>(T arg) => {null: arg};
+}
+
+/*element: Super.:static=[Object.(0)]*/
+class Super {}
+
+class Mixin1 {}
+
+class Mixin2 {}
+
+/*element: Sub.:static=[_Sub&Super&Mixin1&Mixin2.(0)]*/
+class Sub extends Super with Mixin1, Mixin2 {}
+
+class NamedMixin = Super with Mixin1, Mixin2;
+
+/*element: GenericSuper.:static=[Object.(0)]*/
+class GenericSuper<X1, Y1> {}
+
+class GenericMixin1<X2, Y2> {}
+
+class GenericMixin2<X3, Y3> {}
+
+/*element: GenericSub.:
+ static=[_GenericSub&GenericSuper&GenericMixin1&GenericMixin2.(0)]
+*/
+class GenericSub<X4, Y4> extends GenericSuper<X4, Y4>
+ with GenericMixin1<X4, Y4>, GenericMixin2<X4, Y4> {}
+
+class GenericNamedMixin<X5, Y5> = GenericSuper<X5, Y5>
+ with GenericMixin1<X5, Y5>, GenericMixin2<X5, Y5>;
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
new file mode 100644
index 0000000..440aded
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[
+ testConstRedirectingFactoryInvoke(0),
+ testConstRedirectingFactoryInvokeGeneric(0),
+ testConstRedirectingFactoryInvokeGenericDynamic(0),
+ testConstRedirectingFactoryInvokeGenericRaw(0),
+ testConstructorInvoke(0),
+ testConstructorInvokeGeneric(0),
+ testConstructorInvokeGenericDynamic(0),
+ testConstructorInvokeGenericRaw(0),
+ testFactoryConstructor(0),
+ testFactoryInvoke(0),
+ testFactoryInvokeGeneric(0),
+ testFactoryInvokeGenericDynamic(0),
+ testFactoryInvokeGenericRaw(0),
+ testImplicitConstructor(0),
+ testRedirectingFactoryInvoke(0),
+ testRedirectingFactoryInvokeGeneric(0),
+ testRedirectingFactoryInvokeGenericDynamic(0),
+ testRedirectingFactoryInvokeGenericRaw(0)]
+*/
+main() {
+ testConstructorInvoke();
+ testConstructorInvokeGeneric();
+ testConstructorInvokeGenericRaw();
+ testConstructorInvokeGenericDynamic();
+ testFactoryInvoke();
+ testFactoryInvokeGeneric();
+ testFactoryInvokeGenericRaw();
+ testFactoryInvokeGenericDynamic();
+ testRedirectingFactoryInvoke();
+ testRedirectingFactoryInvokeGeneric();
+ testRedirectingFactoryInvokeGenericRaw();
+ testRedirectingFactoryInvokeGenericDynamic();
+ testConstRedirectingFactoryInvoke();
+ testConstRedirectingFactoryInvokeGeneric();
+ testConstRedirectingFactoryInvokeGenericRaw();
+ testConstRedirectingFactoryInvokeGenericDynamic();
+ testImplicitConstructor();
+ testFactoryConstructor();
+}
+
+/*element: testConstructorInvoke:static=[Class.generative(0)]*/
+testConstructorInvoke() {
+ new Class.generative();
+}
+
+/*element: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+testConstructorInvokeGeneric() {
+ new GenericClass<int, String>.generative();
+}
+
+/*element: testConstructorInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+testConstructorInvokeGenericRaw() {
+ new GenericClass.generative();
+}
+
+/*element: testConstructorInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+testConstructorInvokeGenericDynamic() {
+ new GenericClass<dynamic, dynamic>.generative();
+}
+
+/*element: testFactoryInvoke:static=[Class.fact(0)]*/
+testFactoryInvoke() {
+ new Class.fact();
+}
+
+/*element: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype,throwTypeError]*/
+testFactoryInvokeGeneric() {
+ new GenericClass<int, String>.fact();
+}
+
+/*element: testFactoryInvokeGenericRaw:static=[GenericClass.fact(0)]*/
+testFactoryInvokeGenericRaw() {
+ new GenericClass.fact();
+}
+
+/*element: testFactoryInvokeGenericDynamic:static=[GenericClass.fact(0)]*/
+testFactoryInvokeGenericDynamic() {
+ new GenericClass<dynamic, dynamic>.fact();
+}
+
+/*element: testRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+testRedirectingFactoryInvoke() {
+ new Class.redirect();
+}
+
+/*element: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+testRedirectingFactoryInvokeGeneric() {
+ new GenericClass<int, String>.redirect();
+}
+
+/*element: testRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+testRedirectingFactoryInvokeGenericRaw() {
+ new GenericClass.redirect();
+}
+
+/*element: testRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+testRedirectingFactoryInvokeGenericDynamic() {
+ new GenericClass<dynamic, dynamic>.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+testConstRedirectingFactoryInvoke() {
+ const Class.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+testConstRedirectingFactoryInvokeGeneric() {
+ const GenericClass<int, String>.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+testConstRedirectingFactoryInvokeGenericRaw() {
+ const GenericClass.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+testConstRedirectingFactoryInvokeGenericDynamic() {
+ const GenericClass<dynamic, dynamic>.redirect();
+}
+
+/*element: ClassImplicitConstructor.:static=[Object.(0)]*/
+class ClassImplicitConstructor {}
+
+/*element: testImplicitConstructor:static=[ClassImplicitConstructor.(0)]*/
+testImplicitConstructor() => new ClassImplicitConstructor();
+
+class ClassFactoryConstructor {
+ /*kernel.element: ClassFactoryConstructor.:type=[check:ClassFactoryConstructor,inst:JSNull]*/
+ /*strong.element: ClassFactoryConstructor.:type=[inst:JSNull]*/
+ factory ClassFactoryConstructor() => null;
+}
+
+/*element: testFactoryConstructor:static=[ClassFactoryConstructor.(0)]*/
+testFactoryConstructor() => new ClassFactoryConstructor();
+
+class Class {
+ /*element: Class.generative:static=[Object.(0)]*/
+ const Class.generative();
+
+ /*kernel.element: Class.fact:type=[check:Class,inst:JSNull]*/
+ /*strong.element: Class.fact:type=[inst:JSNull]*/
+ factory Class.fact() => null;
+
+ const factory Class.redirect() = Class.generative;
+}
+
+class GenericClass<X, Y> {
+ /*element: GenericClass.generative:static=[Object.(0)]*/
+ const GenericClass.generative();
+
+ /*kernel.element: GenericClass.fact:type=[check:GenericClass<GenericClass.X,GenericClass.Y>,inst:JSNull]*/
+ /*strong.element: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
+ factory GenericClass.fact() => null;
+
+ const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
+}
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
new file mode 100644
index 0000000..ed4ea6d
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -0,0 +1,331 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:static=[
+ testAs(0),
+ testAsGeneric(0),
+ testAsGenericDynamic(0),
+ testAsGenericRaw(0),
+ testConditional(0),
+ testIfNotNull(1),
+ testIfNotNullSet(1),
+ testIfNull(1),
+ testIs(0),
+ testIsGeneric(0),
+ testIsGenericDynamic(0),
+ testIsGenericRaw(0),
+ testIsNot(0),
+ testIsNotGeneric(0),
+ testIsNotGenericDynamic(0),
+ testIsNotGenericRaw(0),
+ testIsTypedef(0),
+ testIsTypedefDeep(0),
+ testIsTypedefGeneric(0),
+ testIsTypedefGenericDynamic(0),
+ testIsTypedefGenericRaw(0),
+ testNot(0),
+ testPostDec(1),
+ testPostInc(1),
+ testPreDec(1),
+ testPreInc(1),
+ testSetIfNull(1),
+ testThrow(0),
+ testUnaryMinus(0)
+],type=[inst:JSNull]
+ */
+main() {
+ testNot();
+ testUnaryMinus();
+ testConditional();
+ testPostInc(null);
+ testPostDec(null);
+ testPreInc(null);
+ testPreDec(null);
+ testIs();
+ testIsGeneric();
+ testIsGenericRaw();
+ testIsGenericDynamic();
+ testIsNot();
+ testIsNotGeneric();
+ testIsNotGenericRaw();
+ testIsNotGenericDynamic();
+ testIsTypedef();
+ testIsTypedefGeneric();
+ testIsTypedefGenericRaw();
+ testIsTypedefGenericDynamic();
+ testIsTypedefDeep();
+ testAs();
+ testAsGeneric();
+ testAsGenericRaw();
+ testAsGenericDynamic();
+ testThrow();
+ testIfNotNull(null);
+ testIfNotNullSet(null);
+ testIfNull(null);
+ testSetIfNull(null);
+}
+
+/*element: testNot:type=[inst:JSBool]*/
+testNot() => !false;
+
+/*element: testUnaryMinus:
+ dynamic=[unary-],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testUnaryMinus() => -1;
+
+/*element: testConditional:type=[inst:JSBool,inst:JSNull,inst:JSString]*/
+// ignore: DEAD_CODE
+testConditional() => true ? null : '';
+
+/*element: testPostInc:
+ dynamic=[+],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPostInc(o) => o++;
+
+/*element: testPostDec:
+ dynamic=[-],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPostDec(o) => o--;
+
+/*element: testPreInc:
+ dynamic=[+],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPreInc(o) => ++o;
+
+/*element: testPreDec:
+ dynamic=[-],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPreDec(o) => --o;
+
+/*element: testIs:type=[inst:JSBool,inst:JSNull,is:Class]*/
+testIs() => null is Class;
+
+/*element: testIsGeneric:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:GenericClass<int,String>]
+ */
+testIsGeneric() => null is GenericClass<int, String>;
+
+/*element: testIsGenericRaw:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsGenericRaw() => null is GenericClass;
+
+/*element: testIsGenericDynamic:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsGenericDynamic() => null is GenericClass<dynamic, dynamic>;
+
+/*element: testIsNot:type=[inst:JSBool,inst:JSNull,is:Class]*/
+testIsNot() => null is! Class;
+
+/*element: testIsNotGeneric:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:GenericClass<int,String>]
+*/
+testIsNotGeneric() => null is! GenericClass<int, String>;
+
+/*element: testIsNotGenericRaw:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsNotGenericRaw() => null is! GenericClass;
+
+/*element: testIsNotGenericDynamic:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsNotGenericDynamic() => null is! GenericClass<dynamic, dynamic>;
+
+/*element: testIsTypedef:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:dynamic Function()]
+*/
+testIsTypedef() => null is Typedef;
+
+/*element: testIsTypedefGeneric:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:int Function(String)]*/
+testIsTypedefGeneric() => null is GenericTypedef<int, String>;
+
+/*element: testIsTypedefGenericRaw:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:dynamic Function(dynamic)]*/
+testIsTypedefGenericRaw() => null is GenericTypedef;
+
+/*element: testIsTypedefGenericDynamic:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:dynamic Function(dynamic)]*/
+testIsTypedefGenericDynamic() => null is GenericTypedef<dynamic, dynamic>;
+
+/*element: testIsTypedefDeep:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:List<int Function(dynamic Function(dynamic))>]*/
+testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
+
+/*element: testAs:
+ static=[throwRuntimeError],
+ type=[as:Class,inst:JSBool,inst:JSNull]
+*/
+// ignore: UNNECESSARY_CAST
+testAs() => null as Class;
+
+/*element: testAsGeneric:static=[checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo,
+ throwRuntimeError],
+ type=[as:GenericClass<int,
+ String>,
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>]*/
+// ignore: UNNECESSARY_CAST
+testAsGeneric() => null as GenericClass<int, String>;
+
+/*element: testAsGenericRaw:
+ static=[throwRuntimeError],
+ type=[as:GenericClass<dynamic,dynamic>,inst:JSBool,inst:JSNull]
+*/
+// ignore: UNNECESSARY_CAST
+testAsGenericRaw() => null as GenericClass;
+
+/*element: testAsGenericDynamic:
+ static=[throwRuntimeError],
+ type=[as:GenericClass<dynamic,dynamic>,inst:JSBool,inst:JSNull]
+*/
+// ignore: UNNECESSARY_CAST
+testAsGenericDynamic() => null as GenericClass<dynamic, dynamic>;
+
+/*element: testThrow:
+ static=[throwExpression,wrapException],
+ type=[inst:JSString]*/
+testThrow() => throw '';
+
+/*element: testIfNotNull:dynamic=[==,foo],type=[inst:JSNull]*/
+testIfNotNull(o) => o?.foo;
+
+/*element: testIfNotNullSet:dynamic=[==,foo=],type=[inst:JSBool,inst:JSNull]*/
+testIfNotNullSet(o) => o?.foo = true;
+
+/*element: testIfNull:dynamic=[==],type=[inst:JSBool,inst:JSNull]*/
+testIfNull(o) => o ?? true;
+
+/*element: testSetIfNull:dynamic=[==],type=[inst:JSBool,inst:JSNull]*/
+testSetIfNull(o) => o ??= true;
+
+class Class {}
+
+class GenericClass<X, Y> {}
+
+typedef Typedef();
+
+typedef X GenericTypedef<X, Y>(Y y);
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments_strong.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments_strong.dart
new file mode 100644
index 0000000..defa672
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments_strong.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_internal';
+
+class A<T> {}
+
+class B<S, U> {}
+
+/*element: C.:static=[Object.(0)]*/
+class C implements A<int>, B<String, bool> {}
+
+/*element: testA:
+ dynamic=[call<A.T>(0)],
+ static=[
+ checkSubtype,
+ extractTypeArguments<A<dynamic>>(2),
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ impl:A<dynamic>,
+ impl:Function,
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,is:A<A.T>]
+*/
+testA(c, f) => extractTypeArguments<A>(c, f);
+
+/*element: testB:
+ dynamic=[call<B.S,B.U>(0)],
+ static=[
+ checkSubtype,
+ extractTypeArguments<B<dynamic,dynamic>>(2),
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ impl:B<dynamic,dynamic>,
+ impl:Function,
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ is:B<B.S,B.U>]
+*/
+testB(c, f) => extractTypeArguments<B>(c, f);
+
+/*element: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
+main() {
+ var c = new C();
+ testA(c, null);
+ testB(c, null);
+}
diff --git a/tests/compiler/dart2js/impact/data/fallthrough.dart b/tests/compiler/dart2js/impact/data/fallthrough.dart
new file mode 100644
index 0000000..a49177a
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/fallthrough.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[testSwitchWithFallthrough(1)],
+ type=[inst:JSNull]
+*/
+main() {
+ testSwitchWithFallthrough(null);
+}
+
+/*element: testSwitchWithFallthrough:
+ static=[
+ FallThroughError._create(2),
+ throwExpression,
+ wrapException],
+ type=[inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testSwitchWithFallthrough(o) {
+ switch (o) {
+ case 0:
+ // ignore: CASE_BLOCK_NOT_TERMINATED
+ case 1:
+ o = 2;
+ case 2:
+ o = 3;
+ return;
+ case 3:
+ default:
+ }
+}
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
new file mode 100644
index 0000000..a262272
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[
+ testDefaultValuesNamed(0),
+ testDefaultValuesPositional(0),
+ testFieldInitializer1(0),
+ testFieldInitializer2(0),
+ testFieldInitializer3(0),
+ testGenericClass(0),
+ testInstanceFieldTyped(0),
+ testInstanceFieldWithInitializer(0),
+ testSuperInitializer(0),
+ testThisInitializer(0)]
+*/
+main() {
+ testDefaultValuesPositional();
+ testDefaultValuesNamed();
+ testFieldInitializer1();
+ testFieldInitializer2();
+ testFieldInitializer3();
+ testInstanceFieldWithInitializer();
+ testInstanceFieldTyped();
+ testThisInitializer();
+ testSuperInitializer();
+ testGenericClass();
+}
+
+/*kernel.element: testDefaultValuesPositional:type=[check:bool,inst:JSBool]*/
+/*strong.element: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
+testDefaultValuesPositional([bool value = false]) {}
+
+/*kernel.element: testDefaultValuesNamed:type=[check:bool,inst:JSBool]*/
+/*strong.element: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
+testDefaultValuesNamed({bool value: false}) {}
+
+class ClassFieldInitializer1 {
+ /*element: ClassFieldInitializer1.field:type=[inst:JSNull]*/
+ var field;
+
+ /*element: ClassFieldInitializer1.:static=[Object.(0),init:ClassFieldInitializer1.field]*/
+ ClassFieldInitializer1(this.field);
+}
+
+/*element: testFieldInitializer1:
+ static=[ClassFieldInitializer1.(1)],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testFieldInitializer1() => new ClassFieldInitializer1(42);
+
+class ClassFieldInitializer2 {
+ /*element: ClassFieldInitializer2.field:type=[inst:JSNull]*/
+ var field;
+
+ /*element: ClassFieldInitializer2.:static=[Object.(0),init:ClassFieldInitializer2.field]*/
+ ClassFieldInitializer2(value) : field = value;
+}
+
+/*element: testFieldInitializer2:
+ static=[ClassFieldInitializer2.(1)],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testFieldInitializer2() => new ClassFieldInitializer2(42);
+
+class ClassFieldInitializer3 {
+ /*element: ClassFieldInitializer3.field:type=[inst:JSNull]*/
+ var field;
+
+ /*element: ClassFieldInitializer3.a:static=[Object.(0),init:ClassFieldInitializer3.field],type=[inst:JSNull]*/
+ ClassFieldInitializer3.a();
+
+ /*element: ClassFieldInitializer3.b:static=[Object.(0),init:ClassFieldInitializer3.field]*/
+ ClassFieldInitializer3.b(value) : field = value;
+}
+
+/*element: testFieldInitializer3:
+ static=[ClassFieldInitializer3.a(0),ClassFieldInitializer3.b(1)],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testFieldInitializer3() {
+ new ClassFieldInitializer3.a();
+ new ClassFieldInitializer3.b(42);
+}
+
+/*element: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
+class ClassInstanceFieldWithInitializer {
+ /*kernel.element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool]*/
+ /*strong.element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
+ var field = false;
+}
+
+/*element: testInstanceFieldWithInitializer:static=[ClassInstanceFieldWithInitializer.(0)]*/
+testInstanceFieldWithInitializer() => new ClassInstanceFieldWithInitializer();
+
+/*element: ClassInstanceFieldTyped.:static=[Object.(0)]*/
+class ClassInstanceFieldTyped {
+ /*kernel.element: ClassInstanceFieldTyped.field:type=[check:int,inst:JSNull]*/
+ /*strong.element: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
+ int field;
+}
+
+/*element: testInstanceFieldTyped:static=[ClassInstanceFieldTyped.(0)]*/
+testInstanceFieldTyped() => new ClassInstanceFieldTyped();
+
+class ClassThisInitializer {
+ /*element: ClassThisInitializer.:static=[ClassThisInitializer.internal(0)]*/
+ ClassThisInitializer() : this.internal();
+
+ /*element: ClassThisInitializer.internal:static=[Object.(0)]*/
+ ClassThisInitializer.internal();
+}
+
+/*element: testThisInitializer:static=[ClassThisInitializer.(0)]*/
+testThisInitializer() => new ClassThisInitializer();
+
+class ClassSuperInitializer extends ClassThisInitializer {
+ /*element: ClassSuperInitializer.:static=[ClassThisInitializer.internal(0)]*/
+ ClassSuperInitializer() : super.internal();
+}
+
+/*element: testSuperInitializer:static=[ClassSuperInitializer.(0)]*/
+testSuperInitializer() => new ClassSuperInitializer();
+
+class ClassGeneric<T> {
+ /*kernel.element: ClassGeneric.:static=[Object.(0)],type=[check:ClassGeneric.T]*/
+ /*strong.element: ClassGeneric.:
+ static=[
+ Object.(0),
+ checkSubtype,
+ checkSubtypeOfRuntimeType,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:ClassGeneric.T]
+ */
+ ClassGeneric(T arg);
+}
+
+/*element: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype,throwTypeError],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+testGenericClass() => new ClassGeneric<int>(0);
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
new file mode 100644
index 0000000..6de7f52
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -0,0 +1,672 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[
+ testClosure(0),
+ testClosureInvoke(0),
+ testDynamicGet(1),
+ testDynamicInvoke(1),
+ testDynamicPrivateMethodInvoke(0),
+ testDynamicSet(1),
+ testInvokeIndex(1),
+ testInvokeIndexSet(1),
+ testLocalFunction(0),
+ testLocalFunctionGet(0),
+ testLocalFunctionInvoke(0),
+ testLocalFunctionTyped(0),
+ testLocalWithInitializer(0),
+ testLocalWithInitializerTyped(0),
+ testLocalWithoutInitializer(0),
+ testStaticFunctionGet(0),
+ testTopLevelField(0),
+ testTopLevelFieldConst(0),
+ testTopLevelFieldFinal(0),
+ testTopLevelFieldGeneric1(0),
+ testTopLevelFieldGeneric2(0),
+ testTopLevelFieldGeneric3(0),
+ testTopLevelFieldLazy(0),
+ testTopLevelFieldTyped(0),
+ testTopLevelFieldWrite(0),
+ testTopLevelFunctionGet(0),
+ testTopLevelFunctionTyped(0),
+ testTopLevelGetterGet(0),
+ testTopLevelGetterGetTyped(0),
+ testTopLevelInvoke(0),
+ testTopLevelInvokeTyped(0),
+ testTopLevelSetterSet(0),
+ testTopLevelSetterSetTyped(0)],
+ type=[inst:JSNull]
+*/
+main() {
+ testTopLevelInvoke();
+ testTopLevelInvokeTyped();
+ testTopLevelFunctionTyped();
+ testTopLevelFunctionGet();
+ testTopLevelGetterGet();
+ testTopLevelGetterGetTyped();
+ testTopLevelSetterSet();
+ testTopLevelSetterSetTyped();
+ testTopLevelField();
+ testTopLevelFieldLazy();
+ testTopLevelFieldConst();
+ testTopLevelFieldFinal();
+ testTopLevelFieldTyped();
+ testTopLevelFieldGeneric1();
+ testTopLevelFieldGeneric2();
+ testTopLevelFieldGeneric3();
+ testTopLevelFieldWrite();
+ testStaticFunctionGet();
+ testDynamicInvoke(null);
+ testDynamicGet(null);
+ testDynamicSet(null);
+ testLocalWithoutInitializer();
+ testLocalWithInitializer();
+ testLocalWithInitializerTyped();
+ testLocalFunction();
+ testLocalFunctionTyped();
+ testLocalFunctionInvoke();
+ testLocalFunctionGet();
+ testClosure();
+ testClosureInvoke();
+ testInvokeIndex(null);
+ testInvokeIndexSet(null);
+ testDynamicPrivateMethodInvoke();
+}
+
+/*element: topLevelFunction1:*/
+topLevelFunction1(a) {}
+
+/*element: topLevelFunction2:type=[inst:JSNull]*/
+topLevelFunction2(a, [b, c]) {}
+
+/*element: topLevelFunction3:type=[inst:JSNull]*/
+topLevelFunction3(a, {b, c}) {}
+
+/*element: testTopLevelInvoke:
+ static=[
+ topLevelFunction1(1),
+ topLevelFunction2(1),
+ topLevelFunction2(2),
+ topLevelFunction2(3),
+ topLevelFunction3(1),
+ topLevelFunction3(1,b),
+ topLevelFunction3(1,b,c),
+ topLevelFunction3(1,b,c),
+ topLevelFunction3(1,c)],
+ type=[
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testTopLevelInvoke() {
+ topLevelFunction1(0);
+ topLevelFunction2(1);
+ topLevelFunction2(2, 3);
+ topLevelFunction2(4, 5, 6);
+ topLevelFunction3(7);
+ topLevelFunction3(8, b: 9);
+ topLevelFunction3(10, c: 11);
+ topLevelFunction3(12, b: 13, c: 14);
+ topLevelFunction3(15, c: 16, b: 17);
+}
+
+/*kernel.element: topLevelFunction1Typed:type=[check:int,check:void]*/
+/*strong.element: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
+void topLevelFunction1Typed(int a) {}
+
+/*kernel.element: topLevelFunction2Typed:
+ type=[
+ check:String,
+ check:double,
+ check:int,
+ check:num,
+ inst:JSNull]
+*/
+/*strong.element: topLevelFunction2Typed:
+ type=[
+ inst:JSBool,
+ inst:JSNull,
+ param:String,
+ param:double,
+ param:num]
+*/
+int topLevelFunction2Typed(String a, [num b, double c]) => null;
+
+/*kernel.element: topLevelFunction3Typed:
+ type=[
+ check:List<int>,
+ check:Map<String,bool>,
+ check:bool,
+ check:double,
+ inst:JSNull]
+*/
+/*strong.element: topLevelFunction3Typed:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:List<int>,
+ param:Map<String,bool>,
+ param:bool]
+*/
+double topLevelFunction3Typed(bool a, {List<int> b, Map<String, bool> c}) {
+ return null;
+}
+
+/*kernel.element: testTopLevelInvokeTyped:
+ static=[
+ topLevelFunction1Typed(1),
+ topLevelFunction2Typed(1),
+ topLevelFunction2Typed(2),
+ topLevelFunction2Typed(3),
+ topLevelFunction3Typed(1),
+ topLevelFunction3Typed(1,b),
+ topLevelFunction3Typed(1,b,c),
+ topLevelFunction3Typed(1,b,c),
+ topLevelFunction3Typed(1,c)],
+ type=[
+ inst:JSBool,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNull,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32,
+ inst:List<dynamic>,
+ inst:Map<dynamic,dynamic>]
+*/
+/*strong.element: testTopLevelInvokeTyped:
+ static=[
+ topLevelFunction1Typed(1),
+ topLevelFunction2Typed(1),
+ topLevelFunction2Typed(2),
+ topLevelFunction2Typed(3),
+ topLevelFunction3Typed(1),
+ topLevelFunction3Typed(1,b),
+ topLevelFunction3Typed(1,b,c),
+ topLevelFunction3Typed(1,b,c),
+ topLevelFunction3Typed(1,c)],
+ type=[
+ inst:JSBool,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNull,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32,
+ inst:List<int>,
+ inst:Map<String,bool>]
+*/
+testTopLevelInvokeTyped() {
+ topLevelFunction1Typed(0);
+ topLevelFunction2Typed('1');
+ topLevelFunction2Typed('2', 3);
+ topLevelFunction2Typed('3', 5, 6.0);
+ topLevelFunction3Typed(true);
+ topLevelFunction3Typed(false, b: []);
+ topLevelFunction3Typed(null, c: {});
+ topLevelFunction3Typed(true, b: [13], c: {'14': true});
+ topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
+}
+
+/*kernel.element: topLevelFunctionTyped1:type=[check:void Function(num)]*/
+/*strong.element: topLevelFunctionTyped1:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:void Function(num)]
+*/
+topLevelFunctionTyped1(void a(num b)) {}
+
+/*kernel.element: topLevelFunctionTyped2:type=[check:void Function(num,[String])]*/
+/*strong.element: topLevelFunctionTyped2:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:void Function(num,[String])]
+*/
+topLevelFunctionTyped2(void a(num b, [String c])) {}
+
+/*kernel.element: topLevelFunctionTyped3:
+ type=[check:void Function(num,{String c,int d})]
+*/
+/*strong.element: topLevelFunctionTyped3:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:void Function(num,{String c,int d})]
+*/
+topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
+
+/*kernel.element: topLevelFunctionTyped4:
+ type=[check:void Function(num,{int c,String d})]
+*/
+/*strong.element: topLevelFunctionTyped4:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:void Function(num,{int c,String d})]
+*/
+topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
+
+/*element: testTopLevelFunctionTyped:
+ static=[
+ topLevelFunctionTyped1(1),
+ topLevelFunctionTyped2(1),
+ topLevelFunctionTyped3(1),
+ topLevelFunctionTyped4(1)],
+ type=[inst:JSNull]
+*/
+testTopLevelFunctionTyped() {
+ topLevelFunctionTyped1(null);
+ topLevelFunctionTyped2(null);
+ topLevelFunctionTyped3(null);
+ topLevelFunctionTyped4(null);
+}
+
+/*element: testTopLevelFunctionGet:static=[topLevelFunction1]*/
+testTopLevelFunctionGet() => topLevelFunction1;
+
+/*element: topLevelGetter:type=[inst:JSNull]*/
+get topLevelGetter => null;
+
+/*element: testTopLevelGetterGet:static=[topLevelGetter]*/
+testTopLevelGetterGet() => topLevelGetter;
+
+/*kernel.element: topLevelGetterTyped:type=[check:int,inst:JSNull]*/
+/*strong.element: topLevelGetterTyped:type=[inst:JSNull]*/
+int get topLevelGetterTyped => null;
+
+/*element: testTopLevelGetterGetTyped:static=[topLevelGetterTyped]*/
+testTopLevelGetterGetTyped() => topLevelGetterTyped;
+
+/*element: topLevelSetter=:*/
+set topLevelSetter(_) {}
+
+/*element: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
+testTopLevelSetterSet() => topLevelSetter = null;
+
+/*kernel.element: topLevelSetterTyped=:type=[check:int,check:void]*/
+/*strong.element: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
+void set topLevelSetterTyped(int value) {}
+
+/*element: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
+testTopLevelSetterSetTyped() => topLevelSetterTyped = null;
+
+/*element: topLevelField:type=[inst:JSNull]*/
+var topLevelField;
+
+/*element: testTopLevelField:static=[topLevelField]*/
+testTopLevelField() => topLevelField;
+
+/*element: topLevelFieldLazy:static=[throwCyclicInit,topLevelFunction1(1)],type=[inst:JSNull]*/
+var topLevelFieldLazy = topLevelFunction1(null);
+
+/*element: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
+testTopLevelFieldLazy() => topLevelFieldLazy;
+
+/*element: topLevelFieldConst:type=[inst:JSNull]*/
+const topLevelFieldConst = null;
+
+/*element: testTopLevelFieldConst:static=[topLevelFieldConst]*/
+testTopLevelFieldConst() => topLevelFieldConst;
+
+/*element: topLevelFieldFinal:static=[throwCyclicInit,topLevelFunction1(1)],type=[inst:JSNull]*/
+final topLevelFieldFinal = topLevelFunction1(null);
+
+/*element: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
+testTopLevelFieldFinal() => topLevelFieldFinal;
+
+/*kernel.element: topLevelFieldTyped:type=[check:int,inst:JSNull]*/
+/*strong.element: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
+int topLevelFieldTyped;
+
+/*element: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
+testTopLevelFieldTyped() => topLevelFieldTyped;
+
+/*kernel.element: topLevelFieldGeneric1:type=[check:GenericClass<dynamic,dynamic>,inst:JSNull]*/
+/*strong.element: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+GenericClass topLevelFieldGeneric1;
+
+/*element: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
+testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
+
+/*kernel.element: topLevelFieldGeneric2:type=[check:GenericClass<dynamic,dynamic>,inst:JSNull]*/
+/*strong.element: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
+
+/*element: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
+testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
+
+/*kernel.element: topLevelFieldGeneric3:type=[check:GenericClass<int,String>,inst:JSNull]*/
+/*strong.element: topLevelFieldGeneric3:
+ static=[
+ checkSubtype,
+ getRuntimeTypeArgument,
+ getRuntimeTypeArgumentIntercepted,
+ getRuntimeTypeInfo,
+ getTypeArgumentByIndex,
+ setRuntimeTypeInfo],
+ type=[
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:GenericClass<int,String>]
+*/
+GenericClass<int, String> topLevelFieldGeneric3;
+
+/*element: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
+testTopLevelFieldGeneric3() => topLevelFieldGeneric3;
+
+/*element: testTopLevelFieldWrite:static=[set:topLevelField],type=[inst:JSNull]*/
+testTopLevelFieldWrite() => topLevelField = null;
+
+class StaticFunctionGetClass {
+ /*element: StaticFunctionGetClass.foo:*/
+ static foo() {}
+}
+
+/*element: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
+testStaticFunctionGet() => StaticFunctionGetClass.foo;
+
+/*element: testDynamicInvoke:
+ dynamic=[
+ f1(1),
+ f2(1),
+ f3(2),
+ f4(3),
+ f5(1),
+ f6(1,b),
+ f7(1,c),
+ f8(1,b,c),
+ f9(1,b,c)],
+ type=[
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testDynamicInvoke(o) {
+ o.f1(0);
+ o.f2(1);
+ o.f3(2, 3);
+ o.f4(4, 5, 6);
+ o.f5(7);
+ o.f6(8, b: 9);
+ o.f7(10, c: 11);
+ o.f8(12, b: 13, c: 14);
+ o.f9(15, c: 16, b: 17);
+}
+
+/*element: testDynamicGet:dynamic=[foo]*/
+testDynamicGet(o) => o.foo;
+
+/*element: testDynamicSet:
+ dynamic=[foo=],
+ type=[
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testDynamicSet(o) => o.foo = 42;
+
+// TODO(johnniwinther): Remove 'inst:Null'.
+/*element: testLocalWithoutInitializer:type=[inst:JSNull,inst:Null]*/
+testLocalWithoutInitializer() {
+ // ignore: UNUSED_LOCAL_VARIABLE
+ var l;
+}
+
+/*element: testLocalWithInitializer:
+ type=[
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testLocalWithInitializer() {
+ // ignore: UNUSED_LOCAL_VARIABLE
+ var l = 42;
+}
+
+/*kernel.element: testLocalWithInitializerTyped:
+ type=[
+ check:int,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+/*strong.element: testLocalWithInitializerTyped:
+ type=[
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testLocalWithInitializerTyped() {
+ // ignore: UNUSED_LOCAL_VARIABLE
+ int l = 42;
+}
+
+/*kernel.element: testLocalFunction:static=[def:localFunction],type=[inst:Function]*/
+/*strong.element: testLocalFunction:
+ static=[
+ computeSignature,
+ def:localFunction,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[
+ inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalFunction() {
+ // ignore: UNUSED_ELEMENT
+ localFunction() {}
+}
+
+/*kernel.element: testLocalFunctionTyped:
+ static=[def:localFunction],
+ type=[check:String,check:int,inst:Function,inst:JSNull]
+*/
+/*strong.element: testLocalFunctionTyped:
+ static=[
+ computeSignature,
+ def:localFunction,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSBool,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSNull,
+ inst:JSUnmodifiableArray<dynamic>,
+ param:String]*/
+testLocalFunctionTyped() {
+ // ignore: UNUSED_ELEMENT
+ int localFunction(String a) => null;
+}
+
+/*kernel.element: testLocalFunctionInvoke:static=[def:localFunction],
+ type=[inst:Function]*/
+/*strong.element: testLocalFunctionInvoke:static=[computeSignature,
+ def:localFunction,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ localFunction(0),
+ setRuntimeTypeInfo],
+ type=[inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]*/
+testLocalFunctionInvoke() {
+ localFunction() {}
+ localFunction();
+}
+
+/*kernel.element: testLocalFunctionGet:static=[def:localFunction],
+ type=[inst:Function]*/
+/*strong.element: testLocalFunctionGet:static=[computeSignature,
+ def:localFunction,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]*/
+testLocalFunctionGet() {
+ localFunction() {}
+ localFunction;
+}
+
+/*kernel.element: testClosure:static=[def:<anonymous>],
+ type=[inst:Function]*/
+/*strong.element: testClosure:static=[computeSignature,
+ def:<anonymous>,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]*/
+testClosure() {
+ () {};
+}
+
+/*kernel.element: testClosureInvoke:dynamic=[call(0)],
+ static=[def:<anonymous>],
+ type=[inst:Function]*/
+/*strong.element: testClosureInvoke:dynamic=[call(0)],
+ static=[computeSignature,
+ def:<anonymous>,
+ getRuntimeTypeArguments,
+ getRuntimeTypeInfo,
+ setRuntimeTypeInfo],
+ type=[inst:Function,
+ inst:JSArray<dynamic>,
+ inst:JSExtendableArray<dynamic>,
+ inst:JSFixedArray<dynamic>,
+ inst:JSMutableArray<dynamic>,
+ inst:JSUnmodifiableArray<dynamic>]*/
+testClosureInvoke() {
+ () {}();
+}
+
+/*element: testInvokeIndex:dynamic=[[]],
+ type=[inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]*/
+testInvokeIndex(o) => o[42];
+
+/*element: testInvokeIndexSet:dynamic=[[]=],
+ type=[inst:JSDouble,
+ inst:JSInt,
+ inst:JSNull,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]*/
+testInvokeIndexSet(o) => o[42] = null;
+
+/*element: testDynamicPrivateMethodInvoke:dynamic=[_privateMethod(0)],type=[inst:JSNull]*/
+testDynamicPrivateMethodInvoke([o]) => o._privateMethod();
+
+class GenericClass<X, Y> {}
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
new file mode 100644
index 0000000..b063cee
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library jsinterop;
+
+import 'package:js/js.dart';
+
+/*element: main:static=[testJsInteropClass(0),testJsInteropMethod(0)]*/
+main() {
+ testJsInteropMethod();
+ testJsInteropClass();
+}
+
+/*kernel.element: testJsInteropMethod:type=[check:int]*/
+/*strong.element: testJsInteropMethod:*/
+@JS()
+external int testJsInteropMethod();
+
+@JS()
+class JsInteropClass {
+ /*element: JsInteropClass.:static=[JavaScriptObject.(0)]*/
+ external JsInteropClass();
+
+ /*kernel.element: JsInteropClass.method:
+ type=[
+ check:double,
+ native:ApplicationCacheErrorEvent,
+ native:DomError,
+ native:DomException,
+ native:ErrorEvent,
+ native:JsInteropClass,
+ native:MediaError,
+ native:NavigatorUserMediaError,
+ native:OverconstrainedError,
+ native:PositionError,
+ native:SensorErrorEvent,
+ native:SpeechRecognitionError,
+ native:SqlError]
+ */
+ /*strong.element: JsInteropClass.method:
+ type=[
+ native:ApplicationCacheErrorEvent,
+ native:DomError,
+ native:DomException,
+ native:ErrorEvent,
+ native:JsInteropClass,
+ native:MediaError,
+ native:NavigatorUserMediaError,
+ native:OverconstrainedError,
+ native:PositionError,
+ native:SensorErrorEvent,
+ native:SpeechRecognitionError,
+ native:SqlError]
+ */
+ @JS()
+ external double method();
+}
+
+/*element: testJsInteropClass:dynamic=[method(0)],static=[JsInteropClass.(0)]*/
+testJsInteropClass() => new JsInteropClass().method();
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
new file mode 100644
index 0000000..65a8ea5
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -0,0 +1,216 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:static=[
+ testBoolFromEnvironment(0),
+ testComplexConstSymbol(0),
+ testConstSymbol(0),
+ testDouble(0),
+ testEmpty(0),
+ testEmptyListLiteral(0),
+ testEmptyListLiteralConstant(0),
+ testEmptyListLiteralDynamic(0),
+ testEmptyListLiteralTyped(0),
+ testEmptyMapLiteral(0),
+ testEmptyMapLiteralConstant(0),
+ testEmptyMapLiteralDynamic(0),
+ testEmptyMapLiteralTyped(0),
+ testFalse(0),
+ testIfNullConstSymbol(0),
+ testInt(0),
+ testNonEmptyListLiteral(0),
+ testNonEmptyMapLiteral(0),
+ testNull(0),
+ testString(0),
+ testStringInterpolation(0),
+ testStringInterpolationConst(0),
+ testStringJuxtaposition(0),
+ testSymbol(0),
+ testTrue(0),
+ testTypeLiteral(0)]
+*/
+main() {
+ testEmpty();
+ testNull();
+ testTrue();
+ testFalse();
+ testInt();
+ testDouble();
+ testString();
+ testStringInterpolation();
+ testStringInterpolationConst();
+ testStringJuxtaposition();
+ testSymbol();
+ testConstSymbol();
+ testComplexConstSymbol();
+ testIfNullConstSymbol();
+ testTypeLiteral();
+ testBoolFromEnvironment();
+ testEmptyListLiteral();
+ testEmptyListLiteralDynamic();
+ testEmptyListLiteralTyped();
+ testEmptyListLiteralConstant();
+ testNonEmptyListLiteral();
+ testEmptyMapLiteral();
+ testEmptyMapLiteralDynamic();
+ testEmptyMapLiteralTyped();
+ testEmptyMapLiteralConstant();
+ testNonEmptyMapLiteral();
+}
+
+/*element: testEmpty:*/
+testEmpty() {}
+
+/*element: testNull:type=[inst:JSNull]*/
+testNull() => null;
+
+/*element: testTrue:type=[inst:JSBool]*/
+testTrue() => true;
+
+/*element: testFalse:type=[inst:JSBool]*/
+testFalse() => false;
+
+/*element: testInt:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+testInt() => 42;
+
+/*element: testDouble:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+testDouble() => 37.5;
+
+/*element: testString:type=[inst:JSString]*/
+testString() => 'foo';
+
+/*element: testStringInterpolation:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSString]*/
+testStringInterpolation() => '${true}';
+
+/*element: testStringInterpolationConst:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSString]*/
+testStringInterpolationConst() {
+ const b = '${true}';
+ return b;
+}
+
+/*element: testStringJuxtaposition:dynamic=[toString(0)],static=[S],type=[inst:JSString]*/
+testStringJuxtaposition() => 'a' 'b';
+
+/*element: testSymbol:static=[Symbol.],type=[inst:Symbol]*/
+testSymbol() => #main;
+
+/*element: testConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated],type=[inst:JSString,inst:Symbol]*/
+testConstSymbol() => const Symbol('main');
+
+/*kernel.element: complexSymbolField1:
+ dynamic=[==,length],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32]
+*/
+/*strong.element: complexSymbolField1:
+ dynamic=[==,length],
+ type=[inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,param:bool]
+*/
+const complexSymbolField1 = "true".length == 4;
+
+/*kernel.element: complexSymbolField2:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSNull,inst:JSString]*/
+/*strong.element: complexSymbolField2:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]*/
+const complexSymbolField2 = "true" "false" "${true}${null}";
+
+/*kernel.element: complexSymbolField3:
+dynamic=[+,unary-],
+static=[
+ GenericClass.generative(0),
+ String.fromEnvironment(1),
+ Symbol.,assertIsSubtype,
+ bool.fromEnvironment(1,defaultValue),
+ identical(2),
+ int.fromEnvironment(1,defaultValue),
+ override,
+ testComplexConstSymbol,
+ throwTypeError],
+type=[
+ check:int,
+ inst:ConstantMap<dynamic,dynamic>,
+ inst:ConstantProtoMap<dynamic,dynamic>,
+ inst:ConstantStringMap<dynamic,dynamic>,
+ inst:GeneralConstantMap<dynamic,dynamic>,
+ inst:JSBool,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32,
+ inst:List<int>,
+ inst:Symbol]
+*/
+/*strong.element: complexSymbolField3:dynamic=[+,unary-],static=[GenericClass.generative(0),String.fromEnvironment(1),Symbol.,assertIsSubtype,bool.fromEnvironment(1,defaultValue),checkSubtype,getRuntimeTypeArgument,getRuntimeTypeArgumentIntercepted,getRuntimeTypeInfo,getTypeArgumentByIndex,identical(2),int.fromEnvironment(1,defaultValue),override,setRuntimeTypeInfo,testComplexConstSymbol,throwTypeError],type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSArray<dynamic>,inst:JSBool,inst:JSDouble,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSInt,inst:JSMutableArray<dynamic>,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,inst:JSUnmodifiableArray<dynamic>,inst:List<int>,inst:Symbol,param:Map<Object,Object>]*/
+const complexSymbolField3 = const {
+ 0: const bool.fromEnvironment('a', defaultValue: true),
+ false: const int.fromEnvironment('b', defaultValue: 42),
+ const <int>[]: const String.fromEnvironment('c'),
+ testComplexConstSymbol: #testComplexConstSymbol,
+ 1 + 2: identical(0, -0),
+ // ignore: dead_code
+ true || false: false && true,
+ override: const GenericClass<int, String>.generative(),
+};
+
+/*kernel.element: complexSymbolField:static=[complexSymbolField1,complexSymbolField2,complexSymbolField3]*/
+/*strong.element: complexSymbolField:static=[complexSymbolField1,complexSymbolField2,complexSymbolField3],type=[inst:JSBool,param:Object]*/
+const complexSymbolField =
+ complexSymbolField1 ? complexSymbolField2 : complexSymbolField3;
+
+/*kernel.element: testComplexConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated,complexSymbolField],type=[inst:Symbol]*/
+/*strong.element: testComplexConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated,complexSymbolField],type=[impl:String,inst:JSBool,inst:Symbol]*/
+testComplexConstSymbol() => const Symbol(complexSymbolField);
+
+/*element: testIfNullConstSymbol:dynamic=[==],static=[Symbol.,Symbol.(1),Symbol.validated],type=[inst:JSNull,inst:JSString,inst:Symbol]*/
+testIfNullConstSymbol() => const Symbol(null ?? 'foo');
+
+/*element: testTypeLiteral:static=[createRuntimeType],type=[inst:Type,inst:TypeImpl,lit:Object]*/
+testTypeLiteral() => Object;
+
+/*element: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
+testBoolFromEnvironment() => const bool.fromEnvironment('FOO');
+
+/*element: testEmptyListLiteral:type=[inst:List<dynamic>]*/
+testEmptyListLiteral() => [];
+
+/*element: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
+testEmptyListLiteralDynamic() => <dynamic>[];
+
+/*kernel.element: testEmptyListLiteralTyped:type=[check:String,inst:List<String>]*/
+/*strong.element: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+testEmptyListLiteralTyped() => <String>[];
+
+/*element: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
+testEmptyListLiteralConstant() => const [];
+
+/*kernel.element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<dynamic>]*/
+/*strong.element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+testNonEmptyListLiteral() => [true];
+
+/*element: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
+testEmptyMapLiteral() => {};
+
+/*element: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
+testEmptyMapLiteralDynamic() => <dynamic, dynamic>{};
+
+/*kernel.element: testEmptyMapLiteralTyped:type=[check:String,check:int,inst:Map<String,int>]*/
+/*strong.element: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+testEmptyMapLiteralTyped() => <String, int>{};
+
+/*element: testEmptyMapLiteralConstant:
+type=[
+ inst:ConstantMap<dynamic,dynamic>,
+ inst:ConstantProtoMap<dynamic,dynamic>,
+ inst:ConstantStringMap<dynamic,dynamic>,
+ inst:GeneralConstantMap<dynamic,dynamic>]*/
+testEmptyMapLiteralConstant() => const {};
+
+/*kernel.element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<dynamic,dynamic>]*/
+/*strong.element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+testNonEmptyMapLiteral() => {null: true};
+
+class GenericClass<X, Y> {
+ /*element: GenericClass.generative:static=[Object.(0)]*/
+ const GenericClass.generative();
+}
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
new file mode 100644
index 0000000..f396310a
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_foreign_helper' as foreign show JS;
+// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_js_helper';
+import 'dart:html_common';
+
+/*element: main:static=[testJSCall(0),
+ testNativeField(1),
+ testNativeMethod(0),
+ testNativeMethodCreates(0),
+ testNativeMethodReturns(0)],
+ type=[inst:JSNull]*/
+main() {
+ testJSCall();
+ testNativeMethod();
+ testNativeField(null);
+ testNativeMethodCreates();
+ testNativeMethodReturns();
+}
+
+/*kernel.element: testJSCall:
+ static=[JS(3)],
+ type=[inst:JSNull,inst:JSString,native:bool,native:int]
+*/
+/*strong.element: testJSCall:
+ static=[JS<dynamic>(3)],
+ type=[inst:JSNull,inst:JSString,native:bool,native:int]
+*/
+testJSCall() => foreign.JS(
+ 'int|bool|NativeUint8List|Rectangle|IdbFactory|SqlDatabase|TypedData|ContextAttributes',
+ '#',
+ null);
+
+/*element: testNativeMethod:*/
+@JSName('foo')
+@SupportedBrowser(SupportedBrowser.CHROME)
+// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+testNativeMethod() native;
+
+/*element: testNativeMethodCreates:
+ type=[native:JSArray<JSArray.E>,native:Null,native:int]
+*/
+@Creates('int|Null|JSArray')
+// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+testNativeMethodCreates() native;
+
+// This will trigger native instantiation and therefore include type use
+// `native:X` for all native types. This is truncated to `type=[*]` to avoid
+// dependency on the particular types. If `testNativeMethodReturns` was not
+// called `testNativeMethodCreates` would instead trigger the native
+// instantiations, so the blame is a bit arbitrary.
+/*element: testNativeMethodReturns:type=[*]*/
+@Returns('String|Null|JSArray')
+// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+testNativeMethodReturns() native;
+
+@Native("NativeClass")
+class NativeClass {
+ /*kernel.element: NativeClass.field:
+ type=[
+ check:Object,
+ inst:JSNull,
+ native:JSExtendableArray<JSExtendableArray.E>,
+ native:Object,
+ native:String,
+ native:bool,
+ native:double,
+ native:int]
+ */
+ /*strong.element: NativeClass.field:
+ type=[
+ inst:JSBool,
+ inst:JSNull,
+ native:JSExtendableArray<JSExtendableArray.E>,
+ native:Object,
+ native:String,
+ native:bool,
+ native:double,
+ native:int,
+ param:Object]
+ */
+ @annotation_Creates_SerializedScriptValue
+ final Object field;
+
+ factory NativeClass._() {
+ throw new UnsupportedError("Not supported");
+ }
+}
+
+/*kernel.element: testNativeField:
+ dynamic=[field],
+ type=[check:NativeClass]
+*/
+/*strong.element: testNativeField:
+ dynamic=[field],
+ static=[defineProperty],
+ type=[inst:JSBool,param:NativeClass]
+*/
+testNativeField(NativeClass c) => c.field;
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
new file mode 100644
index 0000000..9ab5130
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[
+ testAssert(0),
+ testAssertWithMessage(0),
+ testForIn(1),
+ testForInTyped(1),
+ testIfThen(0),
+ testIfThenElse(0),
+ testSwitchWithoutFallthrough(1),
+ testTryCatch(0),
+ testTryCatchOn(0),
+ testTryCatchStackTrace(0),
+ testTryFinally(0)],
+ type=[inst:JSNull]
+*/
+main() {
+ testIfThen();
+ testIfThenElse();
+ testForIn(null);
+ testForInTyped(null);
+ testTryCatch();
+ testTryCatchOn();
+ testTryCatchStackTrace();
+ testTryFinally();
+ testSwitchWithoutFallthrough(null);
+ testAssert();
+ testAssertWithMessage();
+}
+
+/*element: testIfThen:
+ type=[
+ inst:JSBool,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testIfThen() {
+ // ignore: DEAD_CODE
+ if (false) return 42;
+ return 1;
+}
+
+/*element: testIfThenElse:
+ type=[
+ inst:JSBool,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testIfThenElse() {
+ if (true)
+ return 42;
+ else
+ // ignore: DEAD_CODE
+ return 1;
+}
+
+/*kernel.element: testForIn:
+ dynamic=[
+ current,
+ iterator,
+ moveNext(0)],
+ static=[
+ checkConcurrentModificationError],
+ type=[
+ inst:JSNull,
+ inst:Null]
+*/
+/*strong.element: testForIn:
+ dynamic=[
+ current,
+ iterator,
+ moveNext(0)],
+ static=[checkConcurrentModificationError],
+ type=[
+ impl:Iterable<dynamic>,
+ inst:JSBool,
+ inst:JSNull,
+ inst:Null]
+*/
+testForIn(o) {
+ // ignore: UNUSED_LOCAL_VARIABLE
+ for (var e in o) {}
+}
+
+/*kernel.element: testForInTyped:
+ dynamic=[
+ current,
+ iterator,
+ moveNext(0)],
+ static=[
+ checkConcurrentModificationError],
+ type=[
+ check:int,
+ inst:JSNull,
+ inst:Null]
+*/
+/*strong.element: testForInTyped:
+ dynamic=[
+ current,
+ iterator,
+ moveNext(0)],
+ static=[checkConcurrentModificationError],
+ type=[
+ impl:Iterable<dynamic>,
+ impl:int,
+ inst:JSBool,
+ inst:JSNull,
+ inst:Null]
+*/
+testForInTyped(o) {
+ // ignore: UNUSED_LOCAL_VARIABLE
+ for (int e in o) {}
+}
+
+/*element: testTryCatch:
+ static=[unwrapException],
+ type=[
+ inst:PlainJavaScriptObject,
+ inst:UnknownJavaScriptObject]
+*/
+testTryCatch() {
+ try {} catch (e) {}
+}
+
+/*element: testTryCatchOn:
+ static=[unwrapException],
+ type=[
+ catch:String,
+ inst:JSBool,
+ inst:PlainJavaScriptObject,
+ inst:UnknownJavaScriptObject]
+*/
+testTryCatchOn() {
+ // ignore: UNUSED_CATCH_CLAUSE
+ try {} on String catch (e) {}
+}
+
+/*element: testTryCatchStackTrace:
+ static=[
+ getTraceFromException,
+ unwrapException],
+ type=[
+ inst:PlainJavaScriptObject,
+ inst:UnknownJavaScriptObject,
+ inst:_StackTrace]
+*/
+testTryCatchStackTrace() {
+ // ignore: UNUSED_CATCH_STACK
+ try {} catch (e, s) {}
+}
+
+/*element: testTryFinally:*/
+testTryFinally() {
+ try {} finally {}
+}
+
+/*element: testSwitchWithoutFallthrough:
+ static=[
+ throwExpression,
+ wrapException],
+ type=[
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32]
+*/
+testSwitchWithoutFallthrough(o) {
+ switch (o) {
+ case 0:
+ case 1:
+ o = 2;
+ break;
+ case 2:
+ o = 3;
+ return;
+ case 3:
+ throw '';
+ case 4:
+ default:
+ }
+}
+
+/*element: testAssert:static=[assertHelper],type=[inst:JSBool]*/
+testAssert() {
+ assert(true);
+}
+
+/*element: testAssertWithMessage:static=[assertTest,assertThrow],type=[inst:JSBool,inst:JSString]*/
+testAssertWithMessage() {
+ assert(true, 'ok');
+}
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
new file mode 100644
index 0000000..7dd7401
--- /dev/null
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/frontend_strategy.dart';
+import 'package:compiler/src/kernel/element_map.dart';
+import 'package:compiler/src/kernel/kernel_strategy.dart';
+import 'package:compiler/src/universe/world_impact.dart';
+import 'package:compiler/src/universe/use.dart';
+import '../equivalence/id_equivalence.dart';
+import '../equivalence/id_equivalence_helper.dart';
+
+main(List<String> args) {
+ ImpactCacheDeleter.retainCachesForTesting = true;
+ asyncTest(() async {
+ Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
+ await checkTests(dataDir, computeMemberImpact,
+ args: args, skipForStrong: ['fallthrough.dart'], testFrontend: true);
+ });
+}
+
+class Tags {
+ static const String typeUse = 'type';
+ static const String staticUse = 'static';
+ static const String dynamicUse = 'dynamic';
+ static const String constantUse = 'constant';
+}
+
+/// Compute type inference data for [member] from kernel based inference.
+///
+/// Fills [actualMap] with the data.
+void computeMemberImpact(
+ Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
+ {bool verbose: false}) {
+ KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
+ WorldImpact impact = compiler.impactCache[member];
+ MemberDefinition definition =
+ frontendStrategy.elementMap.getMemberDefinition(member);
+ Features features = new Features();
+ if (impact.typeUses.length > 50) {
+ features.addElement(Tags.typeUse, '*');
+ } else {
+ for (TypeUse use in impact.typeUses) {
+ features.addElement(Tags.typeUse, use.shortText);
+ }
+ }
+ if (impact.staticUses.length > 50) {
+ features.addElement(Tags.staticUse, '*');
+ } else {
+ for (StaticUse use in impact.staticUses) {
+ features.addElement(Tags.staticUse, use.shortText);
+ }
+ }
+ for (DynamicUse use in impact.dynamicUses) {
+ features.addElement(Tags.dynamicUse, use.shortText);
+ }
+ for (ConstantUse use in impact.constantUses) {
+ features.addElement(Tags.constantUse, use.shortText);
+ }
+ Id id = computeEntityId(definition.node);
+ actualMap[id] = new ActualData(new IdValue(id, features.getText()),
+ computeSourceSpanFromTreeNode(definition.node), member);
+}
diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
index 7796132..4094778 100644
--- a/tests/compiler/dart2js/inference/inference_test_helper.dart
+++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
@@ -9,6 +9,7 @@
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/types/types.dart';
import 'package:compiler/src/js_model/locals.dart';
import 'package:compiler/src/kernel/element_map.dart';
@@ -105,7 +106,7 @@
.run(definition.node);
}
-/// AST visitor for computing inference data for a member.
+/// IR visitor for computing inference data for a member.
class TypeMaskIrComputer extends IrDataExtractor
with ComputeValueMixin<ir.Node> {
final GlobalTypeInferenceResults<ir.Node> results;
diff --git a/tests/compiler/dart2js/inference/list_tracer_test.dart b/tests/compiler/dart2js/inference/list_tracer_test.dart
index 4e3b241..e7713ce 100644
--- a/tests/compiler/dart2js/inference/list_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/list_tracer_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask;
+import 'package:compiler/src/types/masks.dart' show ContainerTypeMask, TypeMask;
import 'package:expect/expect.dart';
import 'type_mask_test_helper.dart';
diff --git a/tests/compiler/dart2js/inference/load_deferred_library_test.dart b/tests/compiler/dart2js/inference/load_deferred_library_test.dart
index 78a0ea5..62d1b4a 100644
--- a/tests/compiler/dart2js/inference/load_deferred_library_test.dart
+++ b/tests/compiler/dart2js/inference/load_deferred_library_test.dart
@@ -11,7 +11,7 @@
import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/kernel/element_map.dart';
import 'package:compiler/src/types/abstract_value_domain.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import 'package:kernel/ast.dart' as ir;
diff --git a/tests/compiler/dart2js/inference/map_tracer_test.dart b/tests/compiler/dart2js/inference/map_tracer_test.dart
index c450698..4336589 100644
--- a/tests/compiler/dart2js/inference/map_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/map_tracer_test.dart
@@ -6,7 +6,8 @@
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
-import 'package:compiler/src/types/types.dart' show MapTypeMask, TypeMask;
+import 'package:compiler/src/types/abstract_value_domain.dart';
+import 'package:compiler/src/types/masks.dart' show MapTypeMask, TypeMask;
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
@@ -233,7 +234,7 @@
TypeGraphInferrer typesInferrer =
compiler.globalInference.typesInferrerInternal;
ClosedWorld closedWorld = typesInferrer.closedWorld;
- CommonMasks commonMasks = closedWorld.abstractValueDomain;
+ AbstractValueDomain commonMasks = closedWorld.abstractValueDomain;
TypeMask emptyType = new TypeMask.nonNullEmpty();
MemberEntity aKey = findMember(closedWorld, 'aKey');
TypeMask aKeyType = typesInferrer.getTypeOfMember(aKey);
diff --git a/tests/compiler/dart2js/inference/type_combination_test.dart b/tests/compiler/dart2js/inference/type_combination_test.dart
index 2d84f97..64216dc 100644
--- a/tests/compiler/dart2js/inference/type_combination_test.dart
+++ b/tests/compiler/dart2js/inference/type_combination_test.dart
@@ -7,10 +7,9 @@
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/world.dart';
import 'type_mask_test_helper.dart';
-import '../compiler_helper.dart';
import '../memory_compiler.dart';
TypeMask nullType;
diff --git a/tests/compiler/dart2js/inference/type_mask2_test.dart b/tests/compiler/dart2js/inference/type_mask2_test.dart
index 3cd3137..c5e075a 100644
--- a/tests/compiler/dart2js/inference/type_mask2_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask2_test.dart
@@ -8,7 +8,7 @@
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/world.dart' show ClosedWorld;
import '../type_test_helper.dart';
diff --git a/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
index b520387..a680f5b 100644
--- a/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
@@ -7,7 +7,7 @@
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/world.dart';
import '../memory_compiler.dart';
diff --git a/tests/compiler/dart2js/inference/type_mask_test.dart b/tests/compiler/dart2js/inference/type_mask_test.dart
index 91b1968..4561962 100644
--- a/tests/compiler/dart2js/inference/type_mask_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask_test.dart
@@ -4,7 +4,7 @@
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
diff --git a/tests/compiler/dart2js/inference/type_mask_test_helper.dart b/tests/compiler/dart2js/inference/type_mask_test_helper.dart
index a3b661b..f979741 100644
--- a/tests/compiler/dart2js/inference/type_mask_test_helper.dart
+++ b/tests/compiler/dart2js/inference/type_mask_test_helper.dart
@@ -4,7 +4,7 @@
library type_mask_test_helper;
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/world.dart' show ClosedWorld;
export 'package:compiler/src/types/types.dart';
diff --git a/tests/compiler/dart2js/inference/union_type_test.dart b/tests/compiler/dart2js/inference/union_type_test.dart
index 1890622..37f4e29 100644
--- a/tests/compiler/dart2js/inference/union_type_test.dart
+++ b/tests/compiler/dart2js/inference/union_type_test.dart
@@ -4,7 +4,7 @@
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
-import "package:compiler/src/types/types.dart";
+import "package:compiler/src/types/masks.dart";
import "package:compiler/src/world.dart";
import '../type_test_helper.dart';
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 3f92e4c..6564b2b 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -204,9 +204,6 @@
compiler.processLoadedLibraries(new MemoryLoadedLibraries(copiedLibraries));
ResolutionEnqueuer resolutionEnqueuer = compiler.startResolution();
- compiler.backend.constantCompilerTask
- .copyConstantValues(cachedCompiler.backend.constantCompilerTask);
-
Iterable<MemberEntity> cachedTreeElements =
cachedCompiler.enqueuer.resolution.processedEntities;
cachedTreeElements.forEach((MemberEntity element) {
@@ -221,19 +218,12 @@
// One potential problem that can occur when reusing elements is that there
// is a stale reference to an old compiler object. By nulling out the old
// compiler's fields, such stale references are easier to identify.
- cachedCompiler.scanner = null;
- cachedCompiler.dietParser = null;
- cachedCompiler.parser = null;
- cachedCompiler.patchParser = null;
cachedCompiler.libraryLoader = null;
- cachedCompiler.resolver = null;
- cachedCompiler.checker = null;
cachedCompiler.globalInference = null;
cachedCompiler.backend = null;
// Don't null out the enqueuer as it prevents us from using cachedCompiler
// more than once.
cachedCompiler.deferredLoadTask = null;
- cachedCompiler.mirrorUsageAnalyzerTask = null;
cachedCompiler.dumpInfoTask = null;
}
return compiler;
diff --git a/tests/compiler/dart2js/model/enqueuer_test.dart b/tests/compiler/dart2js/model/enqueuer_test.dart
index 567a11f..1912168 100644
--- a/tests/compiler/dart2js/model/enqueuer_test.dart
+++ b/tests/compiler/dart2js/model/enqueuer_test.dart
@@ -13,7 +13,7 @@
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/enqueue.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/selector.dart';
import 'package:compiler/src/universe/world_impact.dart';
diff --git a/tests/compiler/dart2js/model/strong_mode_impact_test.dart b/tests/compiler/dart2js/model/strong_mode_impact_test.dart
index 188bd2e..907a0cc 100644
--- a/tests/compiler/dart2js/model/strong_mode_impact_test.dart
+++ b/tests/compiler/dart2js/model/strong_mode_impact_test.dart
@@ -8,6 +8,7 @@
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/frontend_strategy.dart';
import 'package:compiler/src/world.dart';
import 'package:compiler/src/universe/use.dart';
import 'package:compiler/src/universe/world_impact.dart';
@@ -89,12 +90,10 @@
: new Impact(checkedModeChecks: ['int', 'String']),
};
+ ImpactCacheDeleter.retainCachesForTesting = true;
CompilationResult result = await runCompiler(
memorySourceFiles: {'main.dart': source},
- options: strongMode ? [Flags.strongMode] : [],
- beforeRun: (compiler) {
- compiler.impactCacheDeleter.retainCachesForTesting = true;
- });
+ options: strongMode ? [Flags.strongMode] : []);
Expect.isTrue(result.isSuccess);
Compiler compiler = result.compiler;
diff --git a/tests/compiler/dart2js/model/subtype_test.dart b/tests/compiler/dart2js/model/subtype_test.dart
index 63eaa41..7a44b77 100644
--- a/tests/compiler/dart2js/model/subtype_test.dart
+++ b/tests/compiler/dart2js/model/subtype_test.dart
@@ -9,7 +9,6 @@
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart' show ClassEntity;
import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
import 'package:expect/expect.dart';
import '../type_test_helper.dart';
@@ -44,10 +43,6 @@
Expect.isTrue(env.isPotentialSubtype(subtype, supertype),
'$subtype <: $supertype (potential)');
}
- if (env.types is Types) {
- Expect.equals(expectMoreSpecific, env.isMoreSpecific(subtype, supertype),
- '$subtype << $supertype');
- }
}
void testElementTypes(TypeEnvironment env, String subname, String supername,
diff --git a/tests/compiler/dart2js/receiver_type_test.dart b/tests/compiler/dart2js/receiver_type_test.dart
index da0a7a2..ac1c71f 100644
--- a/tests/compiler/dart2js/receiver_type_test.dart
+++ b/tests/compiler/dart2js/receiver_type_test.dart
@@ -5,7 +5,7 @@
import 'dart:async';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
import 'package:compiler/src/universe/selector.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/rti/rti_need_test_helper.dart b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
index d13dae2..d7a44f5 100644
--- a/tests/compiler/dart2js/rti/rti_need_test_helper.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
@@ -9,9 +9,7 @@
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
-import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/js_backend/runtime_types.dart';
import 'package:compiler/src/kernel/element_map.dart';
@@ -165,10 +163,6 @@
}
if (frontendClosure != null) {
- if (frontendClosure is LocalFunctionElement &&
- rtiNeed.localFunctionNeedsSignature(frontendClosure)) {
- features.add(Tags.needsSignature);
- }
addFrontendData(frontendClosure);
if (rtiNeedBuilder.localFunctionsUsingTypeVariableLiterals
.contains(frontendClosure)) {
@@ -187,7 +181,7 @@
}
/// Visitor that determines whether a type refers to [entity].
-class FindTypeVisitor extends BaseResolutionDartTypeVisitor<bool, Null> {
+class FindTypeVisitor extends BaseDartTypeVisitor<bool, Null> {
final Entity entity;
FindTypeVisitor(this.entity);
diff --git a/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart b/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart
index 75c211b..cc49c33 100644
--- a/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart
@@ -10,19 +10,6 @@
import 'package:expect/expect.dart';
import 'package:source_maps/source_maps.dart';
import 'package:compiler/src/apiimpl.dart';
-import 'package:compiler/src/elements/elements.dart'
- show
- AstElement,
- ClassElement,
- CompilationUnitElement,
- Element,
- FunctionElement,
- LibraryElement,
- MemberElement;
-import 'package:compiler/src/io/source_file.dart' show SourceFile;
-import 'package:compiler/src/io/source_information.dart'
- show computeElementNameForSourceMaps;
-import 'package:kernel/ast.dart' show Location;
validateSourceMap(Uri targetUri,
{Uri mainUri, Position mainPosition, CompilerImpl compiler}) {
@@ -102,6 +89,8 @@
checkNames(
Uri targetUri, Uri mapUri, SingleMapping sourceMap, CompilerImpl compiler) {
+ // TODO(johnniwinther): Port this to work on kernel based elements.
+ /*
Map<Uri, CompilationUnitElement> compilationUnitMap = {};
void mapCompilationUnits(LibraryElement library) {
@@ -142,9 +131,8 @@
Interval intervalFromElement(AstElement element) {
if (!element.hasNode) return null;
- var begin = element.node.getBeginToken().charOffset;
- var endToken = element.node.getEndToken();
- int end = endToken.charOffset + endToken.charCount;
+ var begin = 0;
+ int end = 0;
return new Interval(
positionFromOffset(begin), positionFromOffset(end));
}
@@ -224,7 +212,7 @@
});
}
}
- });
+ });*/
}
RegExp mainSignaturePrefix = new RegExp(r'main: \[?function\(');
diff --git a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
index 70a70c1..88372a5 100644
--- a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
@@ -9,7 +9,6 @@
import 'package:compiler/compiler_new.dart';
import 'package:compiler/src/apiimpl.dart' as api;
import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/io/code_output.dart';
import 'package:compiler/src/io/source_file.dart';
diff --git a/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart b/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart
index 194dfed..ead452a 100644
--- a/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart
+++ b/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart
@@ -8,9 +8,9 @@
import 'dart:convert';
import 'dart:io';
+import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/io/position_information.dart';
@@ -615,12 +615,15 @@
}
class CodeSources {
- Map<Element, CodeSource> codeSourceMap = <Element, CodeSource>{};
+ Map<Entity, CodeSource> codeSourceMap = <Entity, CodeSource>{};
Map<Uri, Map<Interval, CodeSource>> uriCodeSourceMap =
<Uri, Map<Interval, CodeSource>>{};
CodeSources(SourceMapProcessor processor, SourceMaps sourceMaps) {
- CodeSource computeCodeSource(Element element) {
+ ElementEnvironment elementEnvironment =
+ sourceMaps.compiler.backendClosedWorldForTesting.elementEnvironment;
+
+ CodeSource computeCodeSource(Entity element) {
return codeSourceMap.putIfAbsent(element, () {
CodeSource codeSource = codeSourceFromElement(element);
if (codeSource.begin != null) {
@@ -650,26 +653,18 @@
}
intervals[interval] = codeSource;
}
- if (element is ClassElement) {
- element.forEachLocalMember((Element member) {
- codeSource.members.add(computeCodeSource(member));
- });
- element.implementation.forEachLocalMember((Element member) {
- codeSource.members.add(computeCodeSource(member));
- });
- } else if (element is MemberElement) {
- element.nestedClosures.forEach((Element closure) {
- codeSource.members.add(computeCodeSource(closure));
- });
+ if (element is ClassEntity) {
+ elementEnvironment.forEachConstructor(element, computeCodeSource);
+ elementEnvironment.forEachLocalClassMember(
+ element, computeCodeSource);
}
return codeSource;
});
}
- for (LibraryElement library
- in sourceMaps.compiler.libraryLoader.libraries) {
- library.forEachLocalMember(computeCodeSource);
- library.implementation.forEachLocalMember(computeCodeSource);
+ for (LibraryEntity library in elementEnvironment.libraries) {
+ elementEnvironment.forEachClass(library, computeCodeSource);
+ elementEnvironment.forEachLibraryMember(library, computeCodeSource);
}
uriCodeSourceMap.forEach((Uri uri, Map<Interval, CodeSource> intervals) {
@@ -882,32 +877,25 @@
}
/// Compute a [CodeSource] for source span of [element].
-CodeSource codeSourceFromElement(Entity _element) {
+CodeSource codeSourceFromElement(Entity element) {
// TODO(johnniwinther): Handle kernel based elements.
- Element element = _element;
CodeKind kind;
Uri uri;
String name;
int begin;
int end;
- if (element.isLibrary) {
- LibraryElement library = element;
+ if (element is LibraryEntity) {
kind = CodeKind.LIBRARY;
- name = library.name;
- uri = library.entryCompilationUnit.script.resourceUri;
- } else if (element.isClass) {
+ name = element.name;
+ uri = element.canonicalUri;
+ } else if (element is ClassEntity) {
kind = CodeKind.CLASS;
name = element.name;
- uri = element.compilationUnit.script.resourceUri;
- } else {
- AstElement astElement = element.implementation;
+ uri = element.library.canonicalUri;
+ } else if (element is MemberEntity) {
kind = CodeKind.MEMBER;
- uri = astElement.compilationUnit.script.resourceUri;
- name = computeElementNameForSourceMaps(astElement);
- if (astElement.hasNode) {
- begin = astElement.node.getBeginToken().charOffset;
- end = astElement.node.getEndToken().charEnd;
- }
+ uri = element.library.canonicalUri;
+ name = computeElementNameForSourceMaps(element);
}
return new CodeSource(kind, uri, name, begin, end);
}
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 36496c2..51e1680 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -6,37 +6,24 @@
import 'dart:async';
import 'package:expect/expect.dart';
-import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/compiler.dart' show Compiler;
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/elements.dart'
- show ClassElement, LibraryElement, TypedefElement;
+import 'package:compiler/src/frontend_strategy.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/universe/world_builder.dart';
import 'package:compiler/src/world.dart' show ClosedWorld;
import 'memory_compiler.dart' as memory;
-DartType instantiate(Entity element, List<DartType> arguments) {
- if (element is ClassElement) {
- return new ResolutionInterfaceType(element, arguments);
- } else if (element is ClassEntity) {
- return new InterfaceType(element, arguments);
- } else {
- assert(element is TypedefElement);
- return new ResolutionTypedefType(element, arguments);
- }
+DartType instantiate(ClassEntity element, List<DartType> arguments) {
+ return new InterfaceType(element, arguments);
}
class TypeEnvironment {
final Compiler compiler;
final bool testBackendWorld;
- Resolution get resolution => compiler.resolution;
-
static Future<TypeEnvironment> create(String source,
{bool expectNoErrors: false,
bool expectNoWarningsOrErrors: false,
@@ -73,8 +60,7 @@
..addAll(options)),
diagnosticHandler: collector,
beforeRun: (compiler) {
- ElementResolutionWorldBuilder.useInstantiationMap = true;
- compiler.impactCacheDeleter.retainCachesForTesting = true;
+ ImpactCacheDeleter.retainCachesForTesting = true;
compiler.stopAfterTypeInference = stopAfterTypeInference;
});
compiler = result.compiler;
@@ -108,15 +94,11 @@
}
DartTypes get types {
- if (resolution != null) {
- return resolution.types;
+ if (testBackendWorld) {
+ return compiler.backendClosedWorldForTesting.dartTypes;
} else {
- if (testBackendWorld) {
- return compiler.backendClosedWorldForTesting.dartTypes;
- } else {
- KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
- return frontendStrategy.elementMap.types;
- }
+ KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
+ return frontendStrategy.elementMap.types;
}
}
@@ -126,15 +108,7 @@
element ??= elementEnvironment.lookupClass(mainLibrary, name);
element ??=
elementEnvironment.lookupClass(commonElements.coreLibrary, name);
- if (element == null && mainLibrary is LibraryElement) {
- element = mainLibrary.find(name);
- }
Expect.isNotNull(element, "No element named '$name' found.");
- if (element is ClassElement) {
- element.ensureResolved(compiler.resolution);
- } else if (element is TypedefElement) {
- element.computeType(compiler.resolution);
- }
return element;
}
@@ -142,9 +116,6 @@
LibraryEntity mainLibrary = elementEnvironment.mainLibrary;
ClassEntity element = elementEnvironment.lookupClass(mainLibrary, name);
Expect.isNotNull(element, "No class named '$name' found.");
- if (element is ClassElement) {
- element.ensureResolved(compiler.resolution);
- }
return element;
}
@@ -157,25 +128,16 @@
} else if (element is ClassEntity) {
return elementEnvironment.getThisType(element);
} else {
- /// ignore: undefined_method
- return element.computeType(compiler.resolution);
+ throw 'Unexpected element $element';
}
}
DartType operator [](String name) {
if (name == 'dynamic') {
- if (resolution != null) {
- return const ResolutionDynamicType();
- } else {
- return const DynamicType();
- }
+ return const DynamicType();
}
if (name == 'void') {
- if (resolution != null) {
- return const ResolutionVoidType();
- } else {
- return const VoidType();
- }
+ return const VoidType();
}
return getElementType(name);
}
@@ -231,36 +193,6 @@
return types.isPotentialSubtype(T, S);
}
- bool isMoreSpecific(ResolutionDartType T, ResolutionDartType S) {
- return (types as Types).isMoreSpecific(T, S);
- }
-
- ResolutionDartType computeLeastUpperBound(
- ResolutionDartType T, ResolutionDartType S) {
- return (types as Types).computeLeastUpperBound(T, S);
- }
-
- ResolutionDartType flatten(ResolutionDartType T) {
- return (types as Types).flatten(T);
- }
-
- ResolutionFunctionType functionType(
- ResolutionDartType returnType, List<ResolutionDartType> parameters,
- {List<ResolutionDartType> optionalParameters:
- const <ResolutionDartType>[],
- Map<String, ResolutionDartType> namedParameters}) {
- List<String> namedParameterNames = <String>[];
- List<ResolutionDartType> namedParameterTypes = <ResolutionDartType>[];
- if (namedParameters != null) {
- namedParameters.forEach((String name, ResolutionDartType type) {
- namedParameterNames.add(name);
- namedParameterTypes.add(type);
- });
- }
- return new ResolutionFunctionType.synthesized(returnType, parameters,
- optionalParameters, namedParameterNames, namedParameterTypes);
- }
-
ClosedWorld get closedWorld {
if (testBackendWorld) {
return compiler.backendClosedWorldForTesting;
diff --git a/tests/compiler/dart2js_extra/dummy_compiler_test.dart b/tests/compiler/dart2js_extra/dummy_compiler_test.dart
index 3e3a64f..0c13dbb 100644
--- a/tests/compiler/dart2js_extra/dummy_compiler_test.dart
+++ b/tests/compiler/dart2js_extra/dummy_compiler_test.dart
@@ -27,8 +27,6 @@
return buildLibrarySource(DEFAULT_INTERCEPTORS_LIBRARY);
} else if (uri.path.endsWith('js_helper.dart')) {
return buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY);
- } else if (uri.path.endsWith('isolate_helper.dart')) {
- return buildLibrarySource(DEFAULT_ISOLATE_HELPER_LIBRARY);
} else if (uri.path.endsWith('/async.dart')) {
return buildLibrarySource(DEFAULT_ASYNC_LIBRARY);
} else {
diff --git a/tests/compiler/dart2js_extra/instantiation_stub_2_test.dart b/tests/compiler/dart2js_extra/instantiation_stub_2_test.dart
new file mode 100644
index 0000000..49dfcaf
--- /dev/null
+++ b/tests/compiler/dart2js_extra/instantiation_stub_2_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+List<T> foo<T>([T a1, T a2, T a3, T a4, T a5, T a6, T a7]) =>
+ <T>[a1, a2, a3, a4, a5, a6, a7];
+
+class CC {
+ List<T> bar<T, U, V>([T a1, T a2, T a3, T a4, T a5, T a6]) =>
+ <T>[a1, a2, a3, a4, a5, a6];
+}
+
+main() {
+ // We expect a call$1$5 entry for foo, accessed nowhere else in the program
+ // except via the call$5 entry on the instantiation.
+ List<int> Function(int, int, int, int, int) f = foo;
+ Expect.equals(4, f(1, 2, 3, 4, 5)[3]);
+
+ // We expect a bar$3$4 entry for bar, accessed nowhere else in the program
+ // except via the call$4 entry on the instantiation.
+ var o = new CC();
+ List<String> Function(String, String, String, String) g = o.bar;
+ Expect.equals('abcdnullnull', g('a', 'b', 'c', 'd').join(''));
+}
diff --git a/tests/compiler/dart2js_extra/mock_libraries.dart b/tests/compiler/dart2js_extra/mock_libraries.dart
index f5f6e63..025f221 100644
--- a/tests/compiler/dart2js_extra/mock_libraries.dart
+++ b/tests/compiler/dart2js_extra/mock_libraries.dart
@@ -13,7 +13,6 @@
_js_helper:_internal/js_runtime/lib/js_helper.dart
_interceptors:_internal/js_runtime/lib/interceptors.dart
_internal:internal/internal.dart
-_isolate_helper:_internal/js_runtime/lib/isolate_helper.dart
""";
String buildLibrarySource(Map<String, String> elementMap,
@@ -130,7 +129,6 @@
const String DEFAULT_PATCH_CORE_SOURCE = r'''
import 'dart:_js_helper';
import 'dart:_interceptors';
-import 'dart:_isolate_helper';
import 'dart:async';
@patch
@@ -436,14 +434,6 @@
'JavaScriptFunction': 'class JavaScriptFunction {}',
};
-const Map<String, String> DEFAULT_ISOLATE_HELPER_LIBRARY =
- const <String, String>{
- 'startRootIsolate': 'void startRootIsolate(entry, args) {}',
- '_currentIsolate': 'var _currentIsolate;',
- '_callInIsolate': 'var _callInIsolate;',
- '_WorkerBase': 'class _WorkerBase {}',
-};
-
const Map<String, String> DEFAULT_ASYNC_LIBRARY = const <String, String>{
'DeferredLibrary': 'class DeferredLibrary {}',
'Future': '''
diff --git a/tests/compiler/dart2js_native/compute_this_script_test.dart b/tests/compiler/dart2js_native/compute_this_script_test.dart
index 2cdfb52..fcf4539 100644
--- a/tests/compiler/dart2js_native/compute_this_script_test.dart
+++ b/tests/compiler/dart2js_native/compute_this_script_test.dart
@@ -2,17 +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.
-// Test of IsolateNatives.computeThisScript().
+// Test of _computeThisScript().
-import 'dart:_isolate_helper';
+import 'dart:_js_helper' show thisScript;
main() {
- String script = computeThisScript();
-
// This is somewhat brittle and relies on an implementation detail
// of our test runner, but I can think of no other way to test this.
// -- ahe
- if (!script.endsWith('/out.js')) {
- throw 'Unexpected script: "$script"';
+ if (!thisScript.endsWith('/out.js')) {
+ throw 'Unexpected script: "$thiscript"';
}
}
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 87b316b..6aac957 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -306,7 +306,6 @@
# ===== dartk + vm status lines =====
[ $compiler == dartk && $runtime == vm && $strong ]
-apply_generic_function_test: RuntimeError
iterable_fold_test/02: RuntimeError
iterable_reduce_test/01: CompileTimeError # Issue 31533
iterable_reduce_test/none: RuntimeError
@@ -321,7 +320,6 @@
apply_test/01: RuntimeError
[ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
-apply_generic_function_test: RuntimeError
iterable_fold_test/02: RuntimeError
iterable_reduce_test/01: CompileTimeError # Issue 31533
iterable_reduce_test/none: RuntimeError
diff --git a/tests/corelib_2/map_unmodifiable_cast_test.dart b/tests/corelib_2/map_unmodifiable_cast_test.dart
index 3091337..ec5b419 100644
--- a/tests/corelib_2/map_unmodifiable_cast_test.dart
+++ b/tests/corelib_2/map_unmodifiable_cast_test.dart
@@ -49,9 +49,9 @@
testNum(m2.cast<int, int>(), "Map<num>.unmod.cast<int>");
Map<Symbol, dynamic> nsm = new NsmMap().foo(a: 0);
- test(nsm, #a, 0, "nsm");
- test(nsm.cast<Object, int>(), #a, 0, "nsm.cast");
- test(nsm.retype<Object, int>(), #a, 0, "nsm.retype");
+ test(nsm, #a, 0, "nsm", noSuchMethodMap: true);
+ test(nsm.cast<Object, int>(), #a, 0, "nsm.cast", noSuchMethodMap: true);
+ test(nsm.retype<Object, int>(), #a, 0, "nsm.retype", noSuchMethodMap: true);
}
void testNum(Map<Object, Object> map, String name) {
@@ -59,11 +59,14 @@
}
void test(
- Map<Object, Object> map, Object firstKey, Object firstValue, String name) {
- Expect.isTrue(map.containsKey(firstKey), "$name.containsKey");
- Expect.equals(1, map.length, "$name.length");
- Expect.equals(firstKey, map.keys.first, "$name.keys.first");
- Expect.equals(firstValue, map.values.first, "$name.values.first");
+ Map<Object, Object> map, Object firstKey, Object firstValue, String name,
+ {bool noSuchMethodMap: false}) {
+ if (!noSuchMethodMap) {
+ Expect.isTrue(map.containsKey(firstKey), "$name.containsKey");
+ Expect.equals(1, map.length, "$name.length");
+ Expect.equals(firstKey, map.keys.first, "$name.keys.first");
+ Expect.equals(firstValue, map.values.first, "$name.values.first");
+ }
Expect.throwsUnsupportedError(map.clear, "$name.clear");
Expect.throwsUnsupportedError(() {
diff --git a/tests/language/language.status b/tests/language/language.status
index 33b2122..a228688 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -359,6 +359,14 @@
assertion_initializer_const_error_test/01: MissingCompileTimeError
assertion_initializer_const_function_error_test/01: MissingCompileTimeError
+[ $mode == debug && $hot_reload_rollback ]
+enum_duplicate_test/02: Pass, Crash # http://dartbug.com/33156
+enum_duplicate_test/none: Pass, Crash # http://dartbug.com/33156
+enum_private_test/01: Pass, Crash # http://dartbug.com/33156
+
+[ $mode == debug && ($hot_reload || $hot_reload_rollback) ]
+enum_duplicate_test/01: Pass, Crash # http://dartbug.com/33156
+
[ $runtime == dart_precompiled && $minified ]
cyclic_type_test/*: Skip # Tests below rely on Type.toString()
enum_duplicate_test/*: Skip # Uses Enum.toString()
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 1f1f0d4..b9f01fd 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -289,7 +289,7 @@
bit_operations_test/04: RuntimeError
bit_operations_test/none: RuntimeError
branch_canonicalization_test: RuntimeError
-call_function_apply_test: RuntimeError
+call_function_apply_test: RuntimeError # Issue 23873
call_nonexistent_constructor_test/01: RuntimeError
call_type_literal_test/01: RuntimeError
canonical_const2_test: RuntimeError
@@ -554,7 +554,6 @@
[ $compiler == dart2js && $fasta && $host_checked ]
async_test/setter1: Crash # 'file:*/pkg/compiler/lib/src/kernel/element_map_impl.dart': Failed assertion: line 939 pos 18: 'asyncMarker == AsyncMarker.SYNC': is not true.
closure_self_reference_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/nodes.dart': Failed assertion: line 641 pos 12: 'isClosed()': is not true.
-generic_methods_generic_function_parameter_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
generic_methods_type_expression_test/01: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
generic_methods_type_expression_test/03: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
generic_methods_type_expression_test/none: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
diff --git a/tests/language_2/built_in_identifier_illegal_test.dart b/tests/language_2/built_in_identifier_illegal_test.dart
index d3bb320..030aa76 100644
--- a/tests/language_2/built_in_identifier_illegal_test.dart
+++ b/tests/language_2/built_in_identifier_illegal_test.dart
@@ -4,20 +4,22 @@
// Check that we cannot use a pseudo keyword at the class level code.
// Pseudo keywords are not allowed to be used as class names.
-class abstract { } // //# 01: syntax error
-class as { } // //# 19: syntax error
-class dynamic { } // //# 04: compile-time error
-class export { } // //# 17: syntax error
-class external { } // //# 20: syntax error
-class factory { } // //# 05: syntax error
-class get { } // //# 06: syntax error
-class implements { } // //# 07: syntax error
-class import { } // //# 08: syntax error
-class library { } // //# 10: syntax error
-class operator { } // //# 12: syntax error
-class part { } // //# 18: syntax error
-class set { } // //# 13: syntax error
-class static { } // //# 15: syntax error
-class typedef { } // //# 16: syntax error
+class abstract { } // //# abstract: syntax error
+class as { } // //# as: syntax error
+class dynamic { } // //# dynamic: compile-time error
+class export { } // //# export: syntax error
+class external { } // //# external: syntax error
+class factory { } // //# factory: syntax error
+class get { } // //# get: syntax error
+class interface { } // //# interface: syntax error
+class implements { } // //# implements: syntax error
+class import { } // //# import: syntax error
+class mixin { } // //# mixin: syntax error
+class library { } // //# library: syntax error
+class operator { } // //# operator: syntax error
+class part { } // //# part: syntax error
+class set { } // //# set: syntax error
+class static { } // //# static: syntax error
+class typedef { } // //# typedef: syntax error
main() {}
diff --git a/tests/language_2/built_in_identifier_not_prefix_test.dart b/tests/language_2/built_in_identifier_not_prefix_test.dart
index 7666032..db1e856 100644
--- a/tests/language_2/built_in_identifier_not_prefix_test.dart
+++ b/tests/language_2/built_in_identifier_not_prefix_test.dart
@@ -17,75 +17,46 @@
// Dart test for using a built-in identifier as a library prefix.
-import 'dart:core' deferred as abstract; // //# 01: compile-time error
-import 'dart:core' deferred as as; // //# 02: compile-time error
-import 'dart:core' deferred as covariant; // //# 03: compile-time error
-import 'dart:core' deferred as deferred; // //# 04: compile-time error
-import 'dart:core' deferred as dynamic; // //# 05: compile-time error
-import 'dart:core' deferred as export; // //# 06: compile-time error
-import 'dart:core' deferred as external; // //# 07: compile-time error
-import 'dart:core' deferred as factory; // //# 08: compile-time error
-import 'dart:core' deferred as get; // //# 09: compile-time error
-import 'dart:core' deferred as implements; // //# 10: compile-time error
-import 'dart:core' deferred as import; // //# 11: compile-time error
-import 'dart:core' deferred as library; // //# 12: compile-time error
-import 'dart:core' deferred as operator; // //# 13: compile-time error
-import 'dart:core' deferred as part; // //# 14: compile-time error
-import 'dart:core' deferred as set; // //# 15: compile-time error
-import 'dart:core' deferred as static; // //# 16: compile-time error
-import 'dart:core' deferred as typedef; // //# 17: compile-time error
-import 'dart:core' as abstract; // //# 18: syntax error
-import 'dart:core' as as; // //# 19: syntax error
-import 'dart:core' as covariant; // //# 20: syntax error
-import 'dart:core' as deferred; // //# 21: syntax error
-import 'dart:core' as dynamic; // //# 22: compile-time error
-import 'dart:core' as export; // //# 23: syntax error
-import 'dart:core' as external; // //# 24: syntax error
-import 'dart:core' as factory; // //# 25: syntax error
-import 'dart:core' as get; // //# 26: syntax error
-import 'dart:core' as implements; // //# 27: syntax error
-import 'dart:core' as import; // //# 28: syntax error
-import 'dart:core' as library; // //# 29: syntax error
-import 'dart:core' as operator; // //# 30: syntax error
-import 'dart:core' as part; // //# 31: syntax error
-import 'dart:core' as set; // //# 32: syntax error
-import 'dart:core' as static; // //# 33: syntax error
-import 'dart:core' as typedef; // //# 34: syntax error
+import "dart:core" // Fine unless imported with a built-in identifier as prefix.
+deferred as abstract // //# deferred-abstract: compile-time error
+deferred as as // //# deferred-as: compile-time error
+deferred as covariant // //# deferred-covariant: compile-time error
+deferred as deferred // //# deferred-deferred: compile-time error
+deferred as dynamic // //# deferred-dynamic: compile-time error
+deferred as export // //# deferred-export: compile-time error
+deferred as external // //# deferred-external: compile-time error
+deferred as factory // //# deferred-factory: compile-time error
+deferred as get // //# deferred-get: compile-time error
+deferred as implements // //# deferred-implements: compile-time error
+deferred as import // //# deferred-import: compile-time error
+deferred as interface // //# deferred-interface: compile-time error
+deferred as library // //# deferred-library: compile-time error
+deferred as mixin // //# deferred-mixin: compile-time error
+deferred as operator // //# deferred-operator: compile-time error
+deferred as part // //# deferred-part: compile-time error
+deferred as set // //# deferred-set: compile-time error
+deferred as static // //# deferred-static: compile-time error
+deferred as typedef // //# deferred-typedef: compile-time error
+as abstract // //# abstract: compile-time error
+as as // //# as: compile-time error
+as covariant // //# covariant: compile-time error
+as deferred // //# deferred: compile-time error
+as dynamic // //# dynamic: compile-time error
+as export // //# export: compile-time error
+as external // //# external: compile-time error
+as factory // //# factory: compile-time error
+as get // //# get: compile-time error
+as implements // //# implements: compile-time error
+as import // //# import: compile-time error
+as interface // //# interface: compile-time error
+as library // //# library: compile-time error
+as mixin // //# mixin: compile-time error
+as operator // //# operator: compile-time error
+as part // //# part: compile-time error
+as set // //# set: compile-time error
+as static // //# static: compile-time error
+as typedef // //# typedef: compile-time error
+;
main() {
- abstract.loadLibrary(); // //# 01: continued
- as.loadLibrary(); // //# 02: continued
- covariant.loadLibrary(); // //# 03: continued
- deferred.loadLibrary(); // //# 04: continued
- dynamic.loadLibrary(); // //# 05: continued
- export.loadLibrary(); // //# 06: continued
- external.loadLibrary(); // //# 07: continued
- factory.loadLibrary(); // //# 08: continued
- get.loadLibrary(); // //# 09: continued
- implements.loadLibrary(); // //# 10: continued
- import.loadLibrary(); // //# 11: continued
- library.loadLibrary(); // //# 12: continued
- operator.loadLibrary(); // //# 13: continued
- part.loadLibrary(); // //# 14: continued
- set.loadLibrary(); // //# 15: continued
- static.loadLibrary(); // //# 16: continued
- typedef.loadLibrary(); // //# 17: continued
-
- abstract.int x = 42; // //# 18: continued
- as.int x = 42; // //# 19: continued
- covariant.int x = 42; // //# 20: continued
- deferred.int x = 42; // //# 21: continued
- dynamic.int x = 42; // //# 22: continued
- export.int x = 42; // //# 23: continued
- external.int x = 42; // //# 24: continued
- factory.int x = 42; // //# 25: continued
- get.int x = 42; // //# 26: continued
- implements.int x = 42; // //# 27: continued
- import.int x = 42; // //# 28: continued
- library.int x = 42; // //# 29: continued
- operator.int x = 42; // //# 30: continued
- part.int x = 42; // //# 31: continued
- set.int x = 42; // //# 32: continued
- static.int x = 42; // //# 33: continued
- typedef.int x = 42; // //# 34: continued
}
diff --git a/tests/language_2/built_in_identifier_test.dart b/tests/language_2/built_in_identifier_test.dart
index 46a02cc..50cc344 100644
--- a/tests/language_2/built_in_identifier_test.dart
+++ b/tests/language_2/built_in_identifier_test.dart
@@ -17,9 +17,11 @@
var external = 0; //# 01: ok
var factory = 0;
var get = 0;
+ var interface = 0;
var implements = 0;
var import = 0;
var library = 0;
+ var mixin = 0;
var operator = 0;
var part = 0;
var set = 0;
diff --git a/tests/language_2/built_in_identifier_type_annotation_test.dart b/tests/language_2/built_in_identifier_type_annotation_test.dart
index 2fbd24e..5225709 100644
--- a/tests/language_2/built_in_identifier_type_annotation_test.dart
+++ b/tests/language_2/built_in_identifier_type_annotation_test.dart
@@ -21,97 +21,109 @@
// Note that we have several ways to use built-in identifiers other than
// `dynamic` in other locations in a type, e.g., `Function(int set)`.
-abstract x = null; // //# 01: syntax error
-as x = null; // //# 02: syntax error
-covariant x = null; // //# 03: syntax error
-deferred x = null; // //# 04: syntax error
-dynamic x = null; // //# 05: ok
-export x = null; // //# 06: syntax error
-external x = null; // //# 07: syntax error
-factory x = null; // //# 08: syntax error
-get x = null; // //# 09: syntax error
-implements x = null; // //# 10: syntax error
-import x = null; // //# 11: syntax error
-library x = null; // //# 12: syntax error
-operator x = null; // //# 13: syntax error
-part x = null; // //# 14: syntax error
-set x = null; // //# 15: syntax error
-static x = null; // //# 16: syntax error
-typedef x = null; // //# 17: syntax error
+final // optional type before variable must not be a built-in identifier.
+abstract // //# abstract: syntax error
+as // //# as: syntax error
+covariant // //# covariant: syntax error
+deferred // //# deferred: syntax error
+dynamic // //# dynamic: ok
+export // //# export: syntax error
+external // //# external: syntax error
+factory // //# factory: syntax error
+get // //# get: syntax error
+implements // //# implements: syntax error
+import // //# import: syntax error
+interface // //# interface: syntax error
+library // //# library: syntax error
+mixin // //# mixin: syntax error
+operator // //# operator: syntax error
+part // //# part: syntax error
+set // //# set: syntax error
+static // //# static: syntax error
+typedef // //# typedef: syntax error
-abstract<int> x = null; // //# 18: syntax error
-as<int> x = null; // //# 19: syntax error
-covariant<int> x = null; // //# 20: syntax error
-deferred<int> x = null; // //# 21: syntax error
-dynamic<int> x = null; // //# 22: compile-time error
-export<int> x = null; // //# 23: syntax error
-external<int> x = null; // //# 24: syntax error
-factory<int> x = null; // //# 25: syntax error
-get<int> x = null; // //# 26: syntax error
-implements<int> x = null; // //# 27: syntax error
-import<int> x = null; // //# 28: syntax error
-library<int> x = null; // //# 29: syntax error
-operator<int> x = null; // //# 30: syntax error
-part<int> x = null; // //# 31: syntax error
-set<int> x = null; // //# 32: syntax error
-static<int> x = null; // //# 33: syntax error
-typedef<int> x = null; // //# 34: syntax error
+abstract<int> // //# abstract-gen: syntax error
+as<int> // //# as-gen: syntax error
+covariant<int> // //# covariant-gen: syntax error
+deferred<int> // //# deferred-gen: syntax error
+dynamic<int> // //# dynamic-gen: compile-time error
+export<int> // //# export-gen: syntax error
+external<int> // //# external-gen: syntax error
+factory<int> // //# factory-gen: syntax error
+get<int> // //# get-gen: syntax error
+implements<int> // //# implements-gen: syntax error
+import<int> // //# import-gen: syntax error
+interface<int> // //# interface-gen: syntax error
+library<int> // //# library-gen: syntax error
+mixin<int> // //# mixin-gen: syntax error
+operator<int> // //# operator-gen: syntax error
+part<int> // //# part-gen: syntax error
+set<int> // //# set-gen: syntax error
+static<int> // //# static-gen: syntax error
+typedef<int> // //# typedef-gen: syntax error
-List<abstract> x = null; // //# 35: syntax error
-List<as> x = null; // //# 36: syntax error
-List<covariant> x = null; // //# 37: syntax error
-List<deferred> x = null; // //# 38: syntax error
-List<dynamic> x = null; // //# 39: ok
-List<export> x = null; // //# 40: syntax error
-List<external> x = null; // //# 41: syntax error
-List<factory> x = null; // //# 42: syntax error
-List<get> x = null; // //# 43: syntax error
-List<implements> x = null; // //# 44: syntax error
-List<import> x = null; // //# 45: syntax error
-List<library> x = null; // //# 46: syntax error
-List<operator> x = null; // //# 47: syntax error
-List<part> x = null; // //# 48: syntax error
-List<set> x = null; // //# 49: syntax error
-List<static> x = null; // //# 50: syntax error
-List<typedef> x = null; // //# 51: syntax error
+List<abstract> // //# abstract-list: syntax error
+List<as> // //# as-list: syntax error
+List<covariant> // //# covariant-list: syntax error
+List<deferred> // //# deferred-list: syntax error
+List<dynamic> // //# dynamic-list: ok
+List<export> // //# export-list: syntax error
+List<external> // //# external-list: syntax error
+List<factory> // //# factory-list: syntax error
+List<get> // //# get-list: syntax error
+List<implements> // //# implements-list: syntax error
+List<import> // //# import-list: syntax error
+List<interface> // //# interface-list: syntax error
+List<library> // //# library-list: syntax error
+List<mixin> // //# mixin-list: syntax error
+List<operator> // //# operator-list: syntax error
+List<part> // //# part-list: syntax error
+List<set> // //# set-list: syntax error
+List<static> // //# static-list: syntax error
+List<typedef> // //# typedef-list: syntax error
-Function(abstract) x = null; // //# 52: syntax error
-Function(as) x = null; // //# 53: syntax error
-Function(covariant) x = null; // //# 54: syntax error
-Function(deferred) x = null; // //# 55: syntax error
-Function(dynamic) x = null; // //# 56: ok
-Function(export) x = null; // //# 57: syntax error
-Function(external) x = null; // //# 58: syntax error
-Function(factory) x = null; // //# 59: syntax error
-Function(get) x = null; // //# 60: syntax error
-Function(implements) x = null; // //# 61: syntax error
-Function(import) x = null; // //# 62: syntax error
-Function(library) x = null; // //# 63: syntax error
-Function(operator) x = null; // //# 64: syntax error
-Function(part) x = null; // //# 65: syntax error
-Function(set) x = null; // //# 66: syntax error
-Function(static) x = null; // //# 67: syntax error
-Function(typedef) x = null; // //# 68: syntax error
+Function(abstract) // //# abstract-funarg: syntax error
+Function(as) // //# as-funarg: syntax error
+Function(covariant) // //# covariant-funarg: syntax error
+Function(deferred) // //# deferred-funarg: syntax error
+Function(dynamic) // //# dynamic-funarg: ok
+Function(export) // //# export-funarg: syntax error
+Function(external) // //# external-funarg: syntax error
+Function(factory) // //# factory-funarg: syntax error
+Function(get) // //# get-funarg: syntax error
+Function(implements) // //# implements-funarg: syntax error
+Function(import) // //# import-funarg: syntax error
+Function(interface) // //# interface-funarg: syntax error
+Function(library) // //# library-funarg: syntax error
+Function(mixin) // //# mixin-funarg: syntax error
+Function(operator) // //# operator-funarg: syntax error
+Function(part) // //# part-funarg: syntax error
+Function(set) // //# set-funarg: syntax error
+Function(static) // //# static-funarg: syntax error
+Function(typedef) // //# typedef-funarg: syntax error
-abstract Function() x = null; // //# 69: syntax error
-as Function() x = null; // //# 70: syntax error
-covariant Function() x = null; // //# 71: syntax error
-deferred Function() x = null; // //# 72: syntax error
-dynamic Function() x = null; // //# 73: ok
-export Function() x = null; // //# 74: syntax error
-external Function() x = null; // //# 75: syntax error
-factory Function() x = null; // //# 76: syntax error
-get Function() x = null; // //# 77: syntax error
-implements Function() x = null; // //# 78: syntax error
-import Function() x = null; // //# 79: syntax error
-library Function() x = null; // //# 80: syntax error
-operator Function() x = null; // //# 81: syntax error
-part Function() x = null; // //# 82: syntax error
-set Function() x = null; // //# 83: syntax error
-static Function() x = null; // //# 84: syntax error
-typedef Function() x = null; // //# 85: syntax error
+abstract Function() // //# abstract-funret: syntax error
+as Function() // //# as-funret: syntax error
+covariant Function() // //# covariant-funret: syntax error
+deferred Function() // //# deferred-funret: syntax error
+dynamic Function() // //# dynamic-funret: ok
+export Function() // //# export-funret: syntax error
+external Function() // //# external-funret: syntax error
+factory Function() // //# factory-funret: syntax error
+get Function() // //# get-funret: syntax error
+implements Function() // //# implements-funret: syntax error
+import Function() // //# import-funret: syntax error
+interface Function() // //# interface-funret: syntax error
+library Function() // //# library-funret: syntax error
+mixin Function() // //# mixin-funret: syntax error
+operator Function() // //# operator-funret: syntax error
+part Function() // //# part-funret: syntax error
+set Function() // //# set-funret: syntax error
+static Function() // //# static-funret: syntax error
+typedef Function() // //# typedef-funret: syntax error
+
+x = null;
main() {
- var x = null; // //# none: ok
x.toString();
}
diff --git a/tests/language_2/constructor_type_parameter_test.dart b/tests/language_2/constructor_type_parameter_test.dart
new file mode 100644
index 0000000..d038361
--- /dev/null
+++ b/tests/language_2/constructor_type_parameter_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+ Foo<A>() {} // //# 00: compile-time error
+}
+
+main() {
+ new Foo();
+}
diff --git a/tests/language_2/f_bounded_quantification_test.dart b/tests/language_2/f_bounded_quantification_test.dart
index b1abcb0..433df64 100644
--- a/tests/language_2/f_bounded_quantification_test.dart
+++ b/tests/language_2/f_bounded_quantification_test.dart
@@ -19,5 +19,5 @@
FBound<SubBar> fsb = new FBound<SubBar>(); // //# 01: compile-time error
FBound<Baz<Bar>> fbb = new FBound<Baz<Bar>>();
- FBound<SubBaz<Bar>> fsb = new FBound<SubBaz<Bar>>(); // //# 02: compile-time error
+ FBound<SubBaz<Bar>> fsbb = new FBound<SubBaz<Bar>>(); // //# 02: compile-time error
}
diff --git a/tests/language_2/field3_test.dart b/tests/language_2/field3_test.dart
index 2f4b8ba..901dd06 100644
--- a/tests/language_2/field3_test.dart
+++ b/tests/language_2/field3_test.dart
@@ -9,11 +9,22 @@
// illegal: var cannot follow final
final var a = 0;// //# 00: syntax error
// illegal: final field declaration, must be initialized
- final a; // //# 01: compile-time error
- final a = 0; // //# none: ok
+ final b; // //# 01: compile-time error
+ final c; // //# 02: compile-time error
+ final d; // //# 03: ok
+ final e; // //# 04: ok
+ final f = 0; // //# 05: ok
+
+ C() {} //# 02: continued
+ C(this.d) {} //# 03: continued
+ C(x) : e = x {} //# 04: continued
}
main() {
- var val = new C();
- Expect.equals(val.a, 0);
+ var val = new C(); //# 00: continued
+ var val = new C(); //# 01: continued
+ var val = new C(); //# 02: continued
+ var val = new C(0); //# 03: continued
+ var val = new C(0); //# 04: continued
+ var val = new C(); //# 05: continued
}
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index bdfe9cd..23cf368 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -46,9 +46,6 @@
initializer_super_last_test/cc31: MissingCompileTimeError
initializer_super_last_test/cc32: MissingCompileTimeError
-[ $compiler == dart2js && !$strong ]
-initializer_super_last_test: Crash, CompileTimeError # Issue 31321
-
[ $compiler != dart2js && $compiler != dartdevc && !$fasta && $strong ]
type_promotion_functions_test: CompileTimeError # Issue 30895: This test requires a complete rewrite for 2.0.
@@ -121,7 +118,7 @@
function_type/*: Skip # Needs checked mode.
[ $compiler != dartk && $compiler != dartkp && $mode == debug && $runtime == vm ]
-built_in_identifier_type_annotation_test/15: Crash # Not supported by legacy VM front-end.
+built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
[ $compiler == none && $runtime == drt && !$checked ]
assertion_initializer_const_error_test/01: Fail
@@ -253,12 +250,6 @@
[ $checked && !$strong ]
type_parameter_test/05: Pass
-# We no longer expect Dart2 tests to run with the standalone VM without the new
-# common front end, but for now we get better coverage by still running them in
-# checked mode, which is mostly Dart2-compatible.
-[ !$checked && ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-*: SkipByDesign
-
[ !$fasta && !$strong ]
implicit_creation/implicit_const_context_constructor_generic_named_test: Fail # No support for implicit creation.
implicit_creation/implicit_const_context_constructor_generic_test: Fail # No support for implicit creation.
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index c9ddf1c..74be6be 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -9,7 +9,7 @@
abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
bad_initializer2_negative_test: Fail # Issue 14880
built_in_identifier_prefix_test: CompileTimeError
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError # Issue 28813
cascade_test/none: Fail # Issue 11577
config_import_corelib_test: StaticWarning, OK
conflicting_type_variable_and_setter_test: CompileTimeError # Issue 25525
@@ -17,6 +17,7 @@
const_cast2_test/none: CompileTimeError
const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
constructor_call_wrong_argument_count_negative_test: Fail # Issue 11585
+constructor_type_parameter_test/00: MissingCompileTimeError # Issue 33110
deep_nesting1_negative_test: CompileTimeError # Issue 25558
deep_nesting2_negative_test: CompileTimeError # Issue 25558
duplicate_export_negative_test: CompileTimeError
@@ -24,7 +25,8 @@
emit_const_fields_test: CompileTimeError
enum_syntax_test/05: Fail # Issue 21649
enum_syntax_test/06: Fail # Issue 21649
-field3_test/01: MissingCompileTimeError
+field3_test/01: MissingCompileTimeError # Issue 33022
+field3_test/02: MissingCompileTimeError # Issue 33022
final_syntax_test/01: Fail # Issue 11124
final_syntax_test/02: Fail # Issue 11124
final_syntax_test/03: Fail # Issue 11124
@@ -1101,6 +1103,7 @@
constant_type_literal_test/01: MissingCompileTimeError # Issue 28823
default_implementation2_test: CompileTimeError # Issue 30855
error_stacktrace_test/00: Pass
+field3_test/02: MissingCompileTimeError # Issue 33022
field3a_negative_test: StaticWarning # Issue 28823
forwarding_stub_tearoff_test: CompileTimeError
generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30207
@@ -1206,26 +1209,34 @@
async_congruence_unnamed_test/02: MissingCompileTimeError
black_listed_test/none: Fail # Issue 14228
bug32305_test: MissingCompileTimeError
-built_in_identifier_type_annotation_test/35: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/36: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/37: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/38: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/40: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/41: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/42: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/43: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/44: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/45: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/46: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/47: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/48: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/49: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/50: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/51: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/70: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/72: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/78: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/81: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/abstract-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/as-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/as-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/covariant-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/deferred-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/deferred-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/export-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/export-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/external-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/factory-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/get-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/implements-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/implements-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/import-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/import-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/interface-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/interface-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/library-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/library-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/mixin-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/mixin-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/operator-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/operator-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/part-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/part-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/set-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/static-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/typedef-list: MissingCompileTimeError # Issue 28813
call_method_implicit_invoke_local_test/05: MissingCompileTimeError
call_method_implicit_tear_off_assignable_test: StaticWarning
call_method_implicit_tear_off_implements_function_test/03: StaticWarning
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 66550b4..4579ab6 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -8,6 +8,7 @@
bit_operations_test: RuntimeError, OK # non JS number semantics
config_import_corelib_test: CompileTimeError # we need a special platform.dill file for categories=all. Once we fix that, all dart:* are supported when using '--categories=all' so this will become a RuntimeError, OK.
config_import_test: RuntimeError # Test flag is not passed to the compiler.
+constructor_type_parameter_test/00: Crash # Issue 33110
double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in dart2js; bug #11551.
issue23244_test: RuntimeError # Isolates - enum canonicalization - Issue 23244
library_env_test/has_mirror_support: RuntimeError, OK
@@ -31,9 +32,6 @@
field_override_optimization_test: RuntimeError
field_type_check2_test/01: MissingRuntimeError
-[ $compiler == dart2js && $runtime == d8 && !$checked && !$strong ]
-generic_list_checked_test: RuntimeError
-
[ $compiler == dart2js && $runtime == d8 && $fasta ]
assertion_test: RuntimeError
bug32372_test: CompileTimeError
@@ -551,10 +549,6 @@
bad_override_test/03: MissingCompileTimeError
bit_operations_test: RuntimeError
branch_canonicalization_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
canonical_const2_test: RuntimeError, OK # non JS number semantics
check_member_static_test/02: MissingCompileTimeError
class_cycle_test/02: MissingCompileTimeError
@@ -585,7 +579,6 @@
constructor_redirect1_negative_test/01: Crash # Stack Overflow
constructor_redirect2_negative_test: Crash # Stack Overflow
constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2).
-covariance_type_parameter_test/02: RuntimeError
covariant_override/tear_off_type_test: RuntimeError
covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
cyclic_constructor_test/01: Crash # Stack Overflow
@@ -615,7 +608,6 @@
external_test/20: MissingRuntimeError
external_test/21: CompileTimeError
external_test/24: CompileTimeError
-extract_type_arguments_test: RuntimeError
f_bounded_quantification4_test: RuntimeError
fauxverride_test/03: MissingCompileTimeError
fauxverride_test/05: MissingCompileTimeError
@@ -657,8 +649,6 @@
generic_methods_dynamic_test/04: MissingRuntimeError
generic_methods_generic_class_tearoff_test: RuntimeError
generic_methods_generic_function_result_test/01: MissingCompileTimeError
-generic_methods_simple_as_expression_test/02: MissingRuntimeError
-generic_methods_type_expression_test: RuntimeError
generic_methods_unused_parameter_test: RuntimeError
generic_no_such_method_dispatcher_simple_test: CompileTimeError
generic_no_such_method_dispatcher_test: CompileTimeError
@@ -683,7 +673,6 @@
int64_literal_test/none: RuntimeError
integer_division_by_zero_test: RuntimeError # Issue 8301
internal_library_test/02: Crash # NoSuchMethodError: Class 'DillLibraryBuilder' has no instance getter 'mixinApplicationClasses'.
-invocation_mirror2_test: RuntimeError # mirrors not supported
invocation_mirror_invoke_on2_test: RuntimeError
invocation_mirror_invoke_on_test: RuntimeError
issue21079_test: RuntimeError
@@ -695,7 +684,6 @@
local_function2_test/none: RuntimeError
local_function3_test/none: RuntimeError
local_function_test/none: RuntimeError
-many_overridden_no_such_method_test: RuntimeError
method_override7_test/00: MissingCompileTimeError
method_override7_test/01: MissingCompileTimeError
method_override7_test/02: MissingCompileTimeError
@@ -783,14 +771,12 @@
nested_generic_closure_test: RuntimeError
no_main_test/01: CompileTimeError
no_such_method_mock_test: RuntimeError
-no_such_method_test: RuntimeError
nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError
nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError
null_no_such_method_test: CompileTimeError
number_identity2_test: RuntimeError
numbers_test: RuntimeError, OK # non JS number semantics
-overridden_no_such_method_test: RuntimeError
override_field_test/01: MissingCompileTimeError
override_inheritance_field_test/04: CompileTimeError
override_inheritance_field_test/06: CompileTimeError
@@ -879,7 +865,6 @@
function_propagation_test: RuntimeError
generic_test/01: MissingCompileTimeError # front end does not validate `extends`
instantiate_tearoff_of_call_test: RuntimeError
-instantiate_tearoff_test: RuntimeError
mixin_type_parameter_inference_error_test/none: CompileTimeError
mixin_type_parameter_inference_previous_mixin_test/01: CompileTimeError
mixin_type_parameter_inference_previous_mixin_test/02: CompileTimeError
@@ -931,10 +916,6 @@
bad_override_test/03: MissingCompileTimeError
bit_operations_test: RuntimeError
branch_canonicalization_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
call_non_method_field_test/01: MissingCompileTimeError
call_non_method_field_test/02: MissingCompileTimeError
canonical_const2_test: RuntimeError, OK # non JS number semantics
@@ -1065,8 +1046,6 @@
generic_methods_generic_function_result_test/01: MissingCompileTimeError
generic_methods_overriding_test/01: MissingCompileTimeError
generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_simple_as_expression_test/02: MissingRuntimeError
-generic_methods_type_expression_test: RuntimeError
generic_methods_unused_parameter_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
generic_no_such_method_dispatcher_simple_test: CompileTimeError
generic_no_such_method_dispatcher_test: CompileTimeError
@@ -1086,7 +1065,6 @@
initializing_formal_type_annotation_test/02: MissingCompileTimeError
instance_creation_in_function_annotation_test: RuntimeError
instantiate_tearoff_of_call_test: CompileTimeError
-instantiate_tearoff_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
int64_literal_test/01: RuntimeError
int64_literal_test/02: RuntimeError
int64_literal_test/03: MissingCompileTimeError
@@ -1485,10 +1463,6 @@
bad_override_test/03: MissingCompileTimeError
bit_operations_test: RuntimeError
branch_canonicalization_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
call_non_method_field_test/01: MissingCompileTimeError
call_non_method_field_test/02: MissingCompileTimeError
call_with_no_such_method_test: RuntimeError
@@ -1613,8 +1587,6 @@
generic_methods_generic_function_result_test/01: MissingCompileTimeError
generic_methods_overriding_test/01: MissingCompileTimeError
generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_simple_as_expression_test/02: MissingRuntimeError
-generic_methods_type_expression_test: RuntimeError
generic_methods_unused_parameter_test: RuntimeError
generic_no_such_method_dispatcher_simple_test: CompileTimeError
generic_no_such_method_dispatcher_test: CompileTimeError
@@ -1957,6 +1929,7 @@
const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
covariant_subtyping_test: Crash
ct_const_test: RuntimeError
+nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test: RuntimeError
[ $compiler == dart2js && $fasta && !$strong ]
*: SkipByDesign
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 96bed6a..2bfb404 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -22,7 +22,10 @@
bit_operations_test: RuntimeError # No bigints on web.
bug32372_test: RuntimeError
built_in_identifier_prefix_test: CompileTimeError
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 28816
cascaded_forwarding_stubs_generic_test: RuntimeError
cascaded_forwarding_stubs_test: CompileTimeError
conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
@@ -36,6 +39,7 @@
const_types_test/14: MissingCompileTimeError
const_types_test/15: MissingCompileTimeError
constant_type_literal_test/01: MissingCompileTimeError # DDC allows type parameter type literals in const expressions.
+constructor_type_parameter_test/00: MissingCompileTimeError # Issue 33110
covariance_field_test/03: RuntimeError
covariant_override/tear_off_type_test: RuntimeError # Issue 28395
default_implementation2_test: CompileTimeError # Issue 30855
@@ -295,7 +299,10 @@
bad_override_test/01: MissingCompileTimeError
bad_override_test/02: MissingCompileTimeError
bad_override_test/03: MissingCompileTimeError
-built_in_identifier_type_annotation_test/05: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 32194
built_in_identifier_type_annotation_test/none: RuntimeError # Issue 32194
call_method_as_cast_test/06: RuntimeError # Kernel allows classes to subtype `Function` so DDK elides the explicit cast.
call_method_implicit_tear_off_implements_function_test/05: RuntimeError # Kernel is missing the implicit `call` tearoff for assignment `Function`
@@ -514,11 +521,13 @@
mixin_supertype_subclass_test/05: MissingCompileTimeError
mixin_type_parameters_errors_test/03: MissingCompileTimeError
mixin_type_parameters_errors_test/04: MissingCompileTimeError
+mock_writable_final_field_test: RuntimeError # Issue 30847
mock_writable_final_private_field_test: RuntimeError
multiline_newline_test/06: MissingCompileTimeError
multiline_newline_test/06r: MissingCompileTimeError
named_constructor_test/01: MissingCompileTimeError
named_parameters_default_eq_test/02: MissingCompileTimeError
+no_such_method_mock_test: RuntimeError # Issue 31426 - Kernel does not introduce nSM for implemented fields.
null2_test: RuntimeError # Issue 32194
null_method_test: RuntimeError # Issue 32194
null_no_such_method_test: CompileTimeError # Issue 31533
@@ -663,7 +672,8 @@
exception_test: RuntimeError # DDC doesn't implement NullThrownError?; Expect.isTrue(false) fails.
expect_test: RuntimeError # Issue 29920; Expect.identical did not fail
f_bounded_quantification3_test: RuntimeError # Issue 29920; Uncaught Error: type arguments should not be null: (F1, F2) => {
-field3_test/01: MissingCompileTimeError
+field3_test/01: MissingCompileTimeError # Issue 33022
+field3_test/02: MissingCompileTimeError # Issue 33022
field_initialization_order_test/none: RuntimeError # Expect.equals(expected: <b.a.ai.bi.>, actual: <b.bi.a.ai.>) fails.
flatten_test/05: MissingRuntimeError # Issue 29920
flatten_test/08: MissingRuntimeError # Issue 29920
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 6c07860..4a738cc 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -65,70 +65,65 @@
async_return_types_test/wrongReturnType: MissingCompileTimeError # Issue 33068
bad_override_test/01: MissingCompileTimeError # Issue 32984
bad_override_test/02: MissingCompileTimeError # Issue 32984
-call_non_method_field_test/01: MissingCompileTimeError
-call_non_method_field_test/02: MissingCompileTimeError
-check_member_static_test/01: MissingCompileTimeError
-compile_time_constant_o_test/01: MissingCompileTimeError
-compile_time_constant_o_test/02: MissingCompileTimeError
-const_cast2_test/01: CompileTimeError
-const_cast2_test/none: CompileTimeError
-const_dynamic_type_literal_test/02: MissingCompileTimeError
+call_non_method_field_test/01: MissingCompileTimeError # Issue 32975
+call_non_method_field_test/02: MissingCompileTimeError # Issue 32975
+check_member_static_test/01: MissingCompileTimeError # Issue 32613
+const_cast2_test/01: CompileTimeError # Issue 32517
+const_cast2_test/none: CompileTimeError # Issue 32517
const_instance_field_test/01: MissingCompileTimeError # Fasta bug: Const instance field. Issue 32326.
const_map2_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
const_map3_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
const_switch2_test/01: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-const_types_test/34: MissingCompileTimeError
-const_types_test/39: MissingCompileTimeError
-constructor_redirect1_negative_test/01: MissingCompileTimeError
-constructor_redirect2_negative_test: MissingCompileTimeError
+const_types_test/34: MissingCompileTimeError # Issue 32988
+const_types_test/39: MissingCompileTimeError # Issue 32988
+constructor_redirect1_negative_test/01: MissingCompileTimeError # Issue 30856
+constructor_redirect2_negative_test: MissingCompileTimeError # Issue 30856
constructor_redirect_test/01: MissingCompileTimeError # Fasta bug: Initializer refers to this.
-cyclic_constructor_test/01: MissingCompileTimeError # Fasta bug: Cyclic constructor redirection.
+constructor_type_parameter_test/00: MissingCompileTimeError # Issue 33110
+cyclic_constructor_test/01: MissingCompileTimeError # Issue 30856 (cyclic constructor redirection)
cyclic_type_variable_test/01: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
cyclic_type_variable_test/02: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
cyclic_type_variable_test/03: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
cyclic_type_variable_test/04: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
-default_factory2_test/01: MissingCompileTimeError
-default_factory_test/01: MissingCompileTimeError
+default_factory2_test/01: MissingCompileTimeError # Issue 32988
+default_factory_test/01: MissingCompileTimeError # Issue 32988
deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
-duplicate_export_negative_test: Fail # Issue 6134
-f_bounded_quantification_test/01: MissingCompileTimeError
-f_bounded_quantification_test/02: MissingCompileTimeError
-factory4_test/00: MissingCompileTimeError
-field3_test/01: MissingCompileTimeError
-field_override_test/00: MissingCompileTimeError
-field_override_test/01: MissingCompileTimeError
-generic_methods_bounds_test/01: MissingCompileTimeError
-generic_methods_overriding_test/01: MissingCompileTimeError
-generic_methods_recursive_bound_test/02: MissingCompileTimeError
-getter_override_test/03: MissingCompileTimeError
-identical_const_test/01: MissingCompileTimeError
-identical_const_test/02: MissingCompileTimeError
-identical_const_test/03: MissingCompileTimeError
-identical_const_test/04: MissingCompileTimeError
+duplicate_export_negative_test: Fail # Issue 12916
+f_bounded_quantification_test/01: MissingCompileTimeError # Issue 33018
+f_bounded_quantification_test/02: MissingCompileTimeError # Issue 33018
+factory4_test/00: MissingCompileTimeError # Issue 32988
+field3_test/01: MissingCompileTimeError # Issue 33022
+field3_test/02: MissingCompileTimeError # Issue 33022
+field_override_test/00: MissingCompileTimeError # Issue 32613
+field_override_test/01: MissingCompileTimeError # Issue 32613
+generic_methods_bounds_test/01: MissingCompileTimeError # Issue 33018
+generic_methods_overriding_test/01: MissingCompileTimeError # Issue 32613
+generic_methods_recursive_bound_test/02: MissingCompileTimeError # Issue 33018
+getter_override_test/03: MissingCompileTimeError # Issue 32984
issue31596_override_test/07: MissingCompileTimeError
issue31596_override_test/08: MissingCompileTimeError
issue31596_super_test/02: MissingCompileTimeError
issue31596_super_test/04: MissingCompileTimeError
-malbounded_instantiation_test/01: MissingCompileTimeError
-malbounded_instantiation_test/02: MissingCompileTimeError
-malbounded_instantiation_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/02: MissingCompileTimeError
-malbounded_redirecting_factory_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/04: MissingCompileTimeError
-malbounded_redirecting_factory_test/05: MissingCompileTimeError
-malbounded_type_cast2_test: MissingCompileTimeError
-malbounded_type_cast_test/00: MissingCompileTimeError
-malbounded_type_cast_test/01: MissingCompileTimeError
-malbounded_type_cast_test/02: MissingCompileTimeError
-malbounded_type_literal_test/00: MissingCompileTimeError
-malbounded_type_test2_test/00: MissingCompileTimeError
-malbounded_type_test_test/00: MissingCompileTimeError
-malbounded_type_test_test/01: MissingCompileTimeError
-malbounded_type_test_test/02: MissingCompileTimeError
-method_override7_test/03: MissingCompileTimeError
+malbounded_instantiation_test/01: MissingCompileTimeError # Issue 33018
+malbounded_instantiation_test/02: MissingCompileTimeError # Issue 33018
+malbounded_instantiation_test/03: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/02: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/03: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/04: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/05: MissingCompileTimeError # Issue 33018
+malbounded_type_cast2_test: MissingCompileTimeError # Issue 33018
+malbounded_type_cast_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_cast_test/01: MissingCompileTimeError # Issue 33018
+malbounded_type_cast_test/02: MissingCompileTimeError # Issue 33018
+malbounded_type_literal_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_test2_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_test_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_test_test/01: MissingCompileTimeError # Issue 33018
+malbounded_type_test_test/02: MissingCompileTimeError # Issue 33018
+method_override7_test/03: MissingCompileTimeError # Issue 32984
mixin_forwarding_constructor4_test/01: MissingCompileTimeError # KernelVM bug: Issue 15101
mixin_forwarding_constructor4_test/02: MissingCompileTimeError # KernelVM bug: Issue 15101
mixin_forwarding_constructor4_test/03: MissingCompileTimeError # KernelVM bug: Issue 15101
@@ -439,19 +434,21 @@
void_type_usage_test/paren_void_init: MissingCompileTimeError # Issue 32804
void_type_usage_test/paren_while: MissingCompileTimeError # Issue 32804
-[ $arch == simarm && $compiler == dartkp && $strong ]
-await_test: RuntimeError
-
-[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk ]
-export_ambiguous_main_test: MissingCompileTimeError
+[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk && $runtime == vm && $strong ]
+export_ambiguous_main_test: Crash # Issue 32618
[ $compiler != dart2js && $compiler != dartk && $compiler != dartkp && $fasta ]
const_optional_args_test/01: MissingCompileTimeError
-[ $compiler != dart2js && $fasta ]
+# The precomilation configuration uses a kernel2kernel constants evaluator
+# which is is more correct than fasta/vm in JIT mode (i.e. it catches more
+# compile-time errors).
+[ $compiler != dart2js && $compiler != dartkp && $fasta ]
compile_time_constant_c_test/02: MissingCompileTimeError
const_constructor_nonconst_field_test/01: MissingCompileTimeError
const_syntax_test/05: MissingCompileTimeError
+
+[ $compiler != dart2js && $fasta ]
mixin_super_2_test/01: MissingCompileTimeError
mixin_super_2_test/03: MissingCompileTimeError
mixin_supertype_subclass_test/02: MissingCompileTimeError
@@ -857,11 +854,6 @@
checked_setter3_test/01: MissingCompileTimeError
checked_setter3_test/02: MissingCompileTimeError
checked_setter3_test/03: MissingCompileTimeError
-compile_time_constant_k_test/01: MissingCompileTimeError
-compile_time_constant_k_test/02: MissingCompileTimeError
-compile_time_constant_k_test/03: MissingCompileTimeError
-compile_time_constant_o_test/01: RuntimeError # KernelVM bug: Constant map duplicated key.
-compile_time_constant_o_test/02: RuntimeError # KernelVM bug: Constant map duplicated key.
compile_time_constant_static5_test/11: CompileTimeError # Issue 31537
compile_time_constant_static5_test/16: CompileTimeError # Issue 31537
compile_time_constant_static5_test/21: CompileTimeError # Issue 31537
@@ -870,11 +862,9 @@
conditional_import_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
config_import_corelib_test: CompileTimeError # Issue 31533
config_import_test: RuntimeError # KernelVM bug: Configurable imports.
-const_dynamic_type_literal_test/02: RuntimeError # KernelVM bug: Constant map duplicated key.
const_evaluation_test: SkipByDesign
const_list_test: RuntimeError
const_map4_test: RuntimeError
-const_nested_test: RuntimeError # KernelVM bug: Constant evaluation.
constructor12_test: RuntimeError
constructor3_test: Fail, OK, Pass
ct_const2_test: Skip # Incompatible flag: --compile_all
@@ -974,8 +964,6 @@
main_not_a_function_test: Skip
main_test/03: RuntimeError
many_overridden_no_such_method_test: SkipByDesign
-map_literal3_test/01: MissingCompileTimeError
-map_literal3_test/02: MissingCompileTimeError
map_literal3_test/03: MissingCompileTimeError
method_override4_test/01: MissingCompileTimeError
method_override4_test/02: MissingCompileTimeError
@@ -1103,6 +1091,28 @@
tearoff_dynamic_test: RuntimeError # Compares call to "foo" (noSuchMethod) with string "foo"
type_variable_promotion_test: RuntimeError # Compares runtime type to the string "List<B>"
+# The precomilation configuration uses a kernel2kernel constants evaluator
+# which is is more correct than fasta/vm in JIT mode (i.e. it catches more
+# compile-time errors).
+[ $compiler != dartkp && $fasta ]
+compile_time_constant_o_test/01: MissingCompileTimeError # Issue 32983
+compile_time_constant_o_test/02: MissingCompileTimeError # Issue 32983
+const_dynamic_type_literal_test/02: MissingCompileTimeError # Issue 32983
+identical_const_test/01: MissingCompileTimeError # Issue 32983
+identical_const_test/02: MissingCompileTimeError # Issue 32983
+identical_const_test/03: MissingCompileTimeError # Issue 32983
+identical_const_test/04: MissingCompileTimeError # Issue 32983
+
+# The precomilation configuration uses a kernel2kernel constants evaluator
+# which is is more correct than fasta/vm in JIT mode (i.e. it catches more
+# compile-time errors).
+[ $compiler != dartkp && $fasta && $strong ]
+compile_time_constant_k_test/01: MissingCompileTimeError
+compile_time_constant_k_test/02: MissingCompileTimeError
+compile_time_constant_k_test/03: MissingCompileTimeError
+map_literal3_test/01: MissingCompileTimeError
+map_literal3_test/02: MissingCompileTimeError
+
[ $compiler == fasta && $strong ]
bad_override_test/03: MissingCompileTimeError
check_member_static_test/02: MissingCompileTimeError
@@ -1296,16 +1306,11 @@
variable_shadow_class_test/01: MissingCompileTimeError
[ $fasta && $strong ]
-compile_time_constant_k_test/01: MissingCompileTimeError
-compile_time_constant_k_test/02: MissingCompileTimeError
-compile_time_constant_k_test/03: MissingCompileTimeError
compile_time_constant_static2_test/04: MissingCompileTimeError
compile_time_constant_static3_test/04: MissingCompileTimeError
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
issue18628_2_test/01: MissingCompileTimeError
-map_literal3_test/01: MissingCompileTimeError
-map_literal3_test/02: MissingCompileTimeError
map_literal3_test/03: MissingCompileTimeError
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
redirecting_factory_malbounded_test/01: MissingCompileTimeError
@@ -1355,7 +1360,7 @@
bad_named_parameters_test/05: MissingCompileTimeError
bad_override_test/03: MissingCompileTimeError
bad_override_test/06: MissingCompileTimeError
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError
+built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError
call_constructor_on_unresolvable_class_test/01: MissingCompileTimeError
call_constructor_on_unresolvable_class_test/02: MissingCompileTimeError
call_constructor_on_unresolvable_class_test/03: MissingCompileTimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index 58fc4e0..33d21dd 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -3,9 +3,6 @@
# BSD-style license that can be found in the LICENSE file.
# Sections in this file should start with "$runtime == dart_precompiled".
-[ $arch != arm && $arch != simarm64 && $arch != x64 && $compiler == precompiler && $runtime == dart_precompiled ]
-built_in_identifier_type_annotation_test/15: Crash
-
[ $arch == arm64 && $runtime == dart_precompiled ]
large_class_declaration_test: SkipSlow # Uses too much memory.
setter4_test: MissingCompileTimeError
@@ -13,9 +10,6 @@
[ $arch == ia32 && $runtime == dart_precompiled ]
vm/regress_24517_test: Pass, Fail # Issue 24517.
-[ $arch == x64 && $compiler == precompiler && $mode == debug && $runtime == dart_precompiled ]
-built_in_identifier_type_annotation_test/15: Crash
-
[ $compiler == precompiler && $mode == debug && $runtime == dart_precompiled ]
regress_29025_test: Crash # Issue dartbug.com/29331
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index fcd9492..3674357 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -20,1360 +20,8 @@
closure_cycles_test: Pass, Slow
large_class_declaration_test: SkipSlow # Uses too much memory.
-[ $arch == ia32 && $compiler == app_jit && $runtime == vm ]
-vm/regress_24517_test: Pass, Fail # Issue 24517.
-
-[ $arch == ia32 && $compiler == none && $runtime == vm ]
-vm/regress_24517_test: Pass, Fail # Issue 24517.
-
-[ $arch == ia32 && $compiler == none && $runtime == vm && $system == windows ]
-vm/optimized_stacktrace_test: Pass, Crash # Issue 28276
-
[ $arch == ia32 && $mode == release && $runtime == vm ]
deep_nesting1_negative_test: Crash, Pass # Issue 31496
-[ $compiler == app_jit && $mode != product && $runtime == vm ]
-vm/type_vm_test/none: RuntimeError
-
-[ $compiler == app_jit && $runtime == vm ]
-async_star_cancel_while_paused_test: RuntimeError
-async_star_pause_test: Fail, OK
-async_star_regression_2238_test: CompileTimeError, RuntimeError
-class_keyword_test/02: MissingCompileTimeError # Issue 13627
-constructor3_test: Fail, OK, Pass
-ct_const2_test: Skip # Incompatible flag: --compile_all
-cyclic_type2_test: Fail, OK
-cyclic_type_test/02: Fail, OK
-cyclic_type_test/04: Fail, OK
-deferred_load_constants_test/02: Fail
-deferred_load_constants_test/03: Fail
-deferred_load_constants_test/05: Fail
-deferred_not_loaded_check_test: RuntimeError
-deferred_redirecting_factory_test: Fail, Crash # Issue 23408
-duplicate_export_negative_test: Fail # Issue 6134
-dynamic_prefix_core_test/01: RuntimeError # Issue 12478
-example_constructor_test: Fail, OK
-export_ambiguous_main_negative_test: Fail # Issue 14763
-field_initialization_order_test: Fail, OK
-hello_dart_test: Skip # Incompatible flag: --compile_all
-library_env_test/has_html_support: RuntimeError, OK
-library_env_test/has_no_io_support: RuntimeError, OK
-main_not_a_function_test: Skip
-mixin_illegal_super_use_test: Skip # Issues 24478 and 23773
-mixin_illegal_superclass_test: Skip # Issues 24478 and 23773
-multiline_strings_test: Fail # Issue 23020
-no_main_test/01: Skip
-regress_21793_test/01: MissingCompileTimeError
-regress_23408_test: Crash
-super_test: Fail, OK
-type_parameter_test/05: MissingCompileTimeError
-type_variable_scope_test/03: MissingCompileTimeError
-unicode_bom_test: Fail # Issue 16067
-vm/debug_break_enabled_vm_test/01: Crash, OK # Expected to hit breakpoint.
-vm/regress_27201_test: Fail
-vm/regress_29145_test: Skip # Issue 29145
-vm/type_cast_vm_test: RuntimeError # Expects line and column numbers
-
-[ $compiler == app_jit && $runtime == vm && $checked ]
-dynamic_test: RuntimeError
-generic_functions_test: Pass # Issue 25869
-generic_local_functions_test: Pass # Issue 25869
-generic_methods_function_type_test: Pass # Issue 25869
-generic_methods_generic_function_parameter_test: Pass # Issue 25869
-generic_methods_new_test: Pass # Issue 25869
-generic_methods_test: Pass # Issue 25869
-
-[ $compiler == app_jit && $runtime == vm && !$checked ]
-assertion_initializer_const_error_test/01: MissingCompileTimeError
-generic_methods_bounds_test/02: MissingRuntimeError
-generic_methods_dynamic_test/02: MissingRuntimeError
-generic_methods_dynamic_test/04: MissingRuntimeError
-
-[ $compiler != dartk && $mode == product && $runtime == vm ]
-deferred_load_constants_test/02: Fail
-deferred_load_constants_test/03: Fail
-deferred_load_constants_test/05: Fail
-deferred_not_loaded_check_test: RuntimeError
-vm/causal_async_exception_stack2_test: SkipByDesign
-vm/causal_async_exception_stack_test: SkipByDesign
-vm/regress_27201_test: Fail
-vm/type_vm_test/28: MissingRuntimeError
-vm/type_vm_test/29: MissingRuntimeError
-vm/type_vm_test/30: MissingRuntimeError
-vm/type_vm_test/31: MissingRuntimeError
-vm/type_vm_test/32: MissingRuntimeError
-vm/type_vm_test/33: MissingRuntimeError
-vm/type_vm_test/34: MissingRuntimeError
-vm/type_vm_test/35: MissingRuntimeError
-vm/type_vm_test/36: MissingRuntimeError
-
-# The VM does not implement the Dart 2.0 static type errors yet.
-[ $compiler != dartk && $runtime == vm ]
-abstract_beats_arguments_test: MissingCompileTimeError
-abstract_exact_selector_test/01: MissingCompileTimeError
-abstract_factory_constructor_test/00: MissingCompileTimeError
-abstract_getter_test/01: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError
-abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError
-abstract_syntax_test/00: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
-additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError
-argument_assignability_function_typed_test/01: MissingCompileTimeError
-argument_assignability_function_typed_test/02: MissingCompileTimeError
-argument_assignability_function_typed_test/03: RuntimeError
-argument_assignability_function_typed_test/04: RuntimeError
-argument_assignability_function_typed_test/05: RuntimeError
-assertion_initializer_const_function_test/01: MissingCompileTimeError
-assertion_test: RuntimeError # Issue 30326
-assign_static_type_test/01: MissingCompileTimeError
-assign_static_type_test/02: MissingCompileTimeError
-assign_static_type_test/03: MissingCompileTimeError
-assign_static_type_test/04: MissingCompileTimeError
-assign_static_type_test/05: MissingCompileTimeError
-assign_static_type_test/06: MissingCompileTimeError
-assign_to_type_test/01: MissingCompileTimeError
-assign_to_type_test/02: MissingCompileTimeError
-assign_to_type_test/03: MissingCompileTimeError
-assign_to_type_test/04: MissingCompileTimeError
-assign_top_method_test: MissingCompileTimeError
-async_await_syntax_test/a10a: MissingCompileTimeError
-async_await_syntax_test/b10a: MissingCompileTimeError
-async_await_syntax_test/c10a: MissingCompileTimeError
-async_await_syntax_test/d08b: MissingCompileTimeError
-async_await_syntax_test/d10a: MissingCompileTimeError
-async_congruence_local_test/01: MissingCompileTimeError
-async_congruence_local_test/02: MissingCompileTimeError
-async_congruence_local_test/none: RuntimeError
-async_congruence_method_test/01: MissingCompileTimeError
-async_congruence_method_test/none: RuntimeError
-async_congruence_top_level_test: RuntimeError
-async_congruence_unnamed_test/01: MissingCompileTimeError
-async_congruence_unnamed_test/02: MissingCompileTimeError
-async_congruence_unnamed_test/none: RuntimeError
-async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
-async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
-async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError
-async_return_types_test/nestedFuture: MissingCompileTimeError
-async_return_types_test/tooManyTypeParameters: MissingCompileTimeError
-async_return_types_test/wrongReturnType: MissingCompileTimeError
-async_return_types_test/wrongTypeParameter: MissingCompileTimeError
-async_star_test/01: CompileTimeError # Issue 2238.
-async_star_test/02: RuntimeError
-bad_named_parameters2_test/01: MissingCompileTimeError
-bad_named_parameters_test/01: MissingCompileTimeError
-bad_named_parameters_test/02: MissingCompileTimeError
-bad_named_parameters_test/03: MissingCompileTimeError
-bad_named_parameters_test/04: MissingCompileTimeError
-bad_named_parameters_test/05: MissingCompileTimeError
-bad_override_test/01: MissingCompileTimeError
-bad_override_test/02: MissingCompileTimeError
-bad_override_test/06: MissingCompileTimeError
-bug31436_test: RuntimeError
-bug32305_test: MissingCompileTimeError
-bug32372_test: RuntimeError
-built_in_identifier_prefix_test: CompileTimeError
-call_constructor_on_unresolvable_class_test/01: MissingCompileTimeError
-call_constructor_on_unresolvable_class_test/02: MissingCompileTimeError
-call_constructor_on_unresolvable_class_test/03: MissingCompileTimeError
-call_method_as_cast_test/01: RuntimeError
-call_method_as_cast_test/02: RuntimeError
-call_method_as_cast_test/03: RuntimeError
-call_method_as_cast_test/04: RuntimeError
-call_method_as_cast_test/05: RuntimeError
-call_method_implicit_tear_off_assignable_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/01: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/03: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/01: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/03: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
-call_method_implicit_tear_off_test/05: RuntimeError
-call_method_implicit_tear_off_test/06: RuntimeError
-call_method_is_check_test/01: RuntimeError
-call_method_is_check_test/02: RuntimeError
-call_method_is_check_test/03: RuntimeError
-call_method_is_check_test/04: RuntimeError
-call_method_is_check_test/05: RuntimeError
-call_method_must_not_be_field_test/01: MissingCompileTimeError
-call_method_must_not_be_field_test/02: MissingCompileTimeError
-call_method_must_not_be_field_test/03: RuntimeError
-call_method_must_not_be_getter_test/01: MissingCompileTimeError
-call_method_must_not_be_getter_test/02: MissingCompileTimeError
-call_method_must_not_be_getter_test/03: RuntimeError
-call_method_override_test/01: MissingCompileTimeError
-call_method_override_test/02: MissingCompileTimeError
-call_non_method_field_test/01: MissingCompileTimeError
-call_non_method_field_test/02: MissingCompileTimeError
-call_nonexistent_constructor_test/01: MissingCompileTimeError
-call_nonexistent_constructor_test/02: MissingCompileTimeError
-call_nonexistent_static_test/01: MissingCompileTimeError
-call_nonexistent_static_test/02: MissingCompileTimeError
-call_nonexistent_static_test/03: MissingCompileTimeError
-call_nonexistent_static_test/04: MissingCompileTimeError
-call_nonexistent_static_test/05: MissingCompileTimeError
-call_nonexistent_static_test/06: MissingCompileTimeError
-call_nonexistent_static_test/07: MissingCompileTimeError
-call_nonexistent_static_test/08: MissingCompileTimeError
-call_nonexistent_static_test/09: MissingCompileTimeError
-call_nonexistent_static_test/10: MissingCompileTimeError
-call_through_getter_test/01: MissingCompileTimeError
-call_through_getter_test/02: MissingCompileTimeError
-call_type_literal_test/01: MissingCompileTimeError
-callable_test/00: MissingCompileTimeError
-callable_test/01: MissingCompileTimeError
-cast_test/04: MissingCompileTimeError
-cast_test/05: MissingCompileTimeError
-check_member_static_test/01: MissingCompileTimeError
-check_method_override_test/01: MissingCompileTimeError
-check_method_override_test/02: MissingCompileTimeError
-checked_null_test/01: MissingCompileTimeError
-class_literal_test/01: MissingCompileTimeError
-class_literal_test/02: MissingCompileTimeError
-class_literal_test/03: MissingCompileTimeError
-class_literal_test/04: MissingCompileTimeError
-class_literal_test/05: MissingCompileTimeError
-class_literal_test/06: MissingCompileTimeError
-class_literal_test/07: MissingCompileTimeError
-class_literal_test/08: MissingCompileTimeError
-class_literal_test/09: MissingCompileTimeError
-class_literal_test/10: MissingCompileTimeError
-class_literal_test/11: MissingCompileTimeError
-class_literal_test/12: MissingCompileTimeError
-class_literal_test/13: MissingCompileTimeError
-class_literal_test/14: MissingCompileTimeError
-class_literal_test/15: MissingCompileTimeError
-class_literal_test/16: MissingCompileTimeError
-class_literal_test/17: MissingCompileTimeError
-class_literal_test/18: MissingCompileTimeError
-class_literal_test/19: MissingCompileTimeError
-class_literal_test/20: MissingCompileTimeError
-class_literal_test/21: MissingCompileTimeError
-class_literal_test/22: MissingCompileTimeError
-class_literal_test/23: MissingCompileTimeError
-class_literal_test/24: MissingCompileTimeError
-class_literal_test/25: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
-closure_param_null_to_object_test: RuntimeError
-compile_time_constant_o_test/01: MissingCompileTimeError
-compile_time_constant_o_test/02: MissingCompileTimeError
-conditional_method_invocation_test/05: MissingCompileTimeError
-conditional_method_invocation_test/06: MissingCompileTimeError
-conditional_method_invocation_test/07: MissingCompileTimeError
-conditional_method_invocation_test/08: MissingCompileTimeError
-conditional_method_invocation_test/12: MissingCompileTimeError
-conditional_method_invocation_test/13: MissingCompileTimeError
-conditional_method_invocation_test/18: MissingCompileTimeError
-conditional_method_invocation_test/19: MissingCompileTimeError
-conditional_property_access_test/04: MissingCompileTimeError
-conditional_property_access_test/05: MissingCompileTimeError
-conditional_property_access_test/06: MissingCompileTimeError
-conditional_property_access_test/10: MissingCompileTimeError
-conditional_property_access_test/11: MissingCompileTimeError
-conditional_property_access_test/16: MissingCompileTimeError
-conditional_property_access_test/17: MissingCompileTimeError
-conditional_property_assignment_test/04: MissingCompileTimeError
-conditional_property_assignment_test/05: MissingCompileTimeError
-conditional_property_assignment_test/06: MissingCompileTimeError
-conditional_property_assignment_test/10: MissingCompileTimeError
-conditional_property_assignment_test/11: MissingCompileTimeError
-conditional_property_assignment_test/12: MissingCompileTimeError
-conditional_property_assignment_test/13: MissingCompileTimeError
-conditional_property_assignment_test/27: MissingCompileTimeError
-conditional_property_assignment_test/28: MissingCompileTimeError
-conditional_property_assignment_test/32: MissingCompileTimeError
-conditional_property_assignment_test/33: MissingCompileTimeError
-conditional_property_assignment_test/34: MissingCompileTimeError
-conditional_property_assignment_test/35: MissingCompileTimeError
-conditional_property_increment_decrement_test/04: MissingCompileTimeError
-conditional_property_increment_decrement_test/08: MissingCompileTimeError
-conditional_property_increment_decrement_test/12: MissingCompileTimeError
-conditional_property_increment_decrement_test/16: MissingCompileTimeError
-conditional_property_increment_decrement_test/21: MissingCompileTimeError
-conditional_property_increment_decrement_test/22: MissingCompileTimeError
-conditional_property_increment_decrement_test/27: MissingCompileTimeError
-conditional_property_increment_decrement_test/28: MissingCompileTimeError
-conditional_property_increment_decrement_test/33: MissingCompileTimeError
-conditional_property_increment_decrement_test/34: MissingCompileTimeError
-conditional_property_increment_decrement_test/39: MissingCompileTimeError
-conditional_property_increment_decrement_test/40: MissingCompileTimeError
-conflicting_generic_interfaces_simple_test: MissingCompileTimeError
-const_constructor2_test/05: MissingCompileTimeError
-const_constructor2_test/06: MissingCompileTimeError
-const_dynamic_type_literal_test/02: MissingCompileTimeError
-const_types_test/01: MissingCompileTimeError
-const_types_test/02: MissingCompileTimeError
-const_types_test/03: MissingCompileTimeError
-const_types_test/04: MissingCompileTimeError
-const_types_test/05: MissingCompileTimeError
-const_types_test/06: MissingCompileTimeError
-const_types_test/13: MissingCompileTimeError
-const_types_test/34: MissingCompileTimeError
-const_types_test/35: MissingCompileTimeError
-const_types_test/39: MissingCompileTimeError
-const_types_test/40: MissingCompileTimeError
-constructor13_test/01: MissingCompileTimeError
-constructor13_test/02: MissingCompileTimeError
-constructor_call_as_function_test/01: MissingCompileTimeError
-covariant_override/runtime_check_test: RuntimeError
-covariant_tear_off_type_test: RuntimeError
-create_unresolved_type_test/01: MissingCompileTimeError
-cyclic_type_variable_test/01: MissingCompileTimeError
-cyclic_type_variable_test/02: MissingCompileTimeError
-cyclic_type_variable_test/03: MissingCompileTimeError
-cyclic_type_variable_test/04: MissingCompileTimeError
-cyclic_typedef_test/13: MissingCompileTimeError
-default_factory2_test/01: MissingCompileTimeError
-default_factory_test/01: MissingCompileTimeError
-deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
-deferred_constraints_type_annotation_test/catch_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/is_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_before_load: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic4: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_null: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_top_level: MissingCompileTimeError
-deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError
-dynamic_field_test/01: MissingCompileTimeError
-dynamic_field_test/02: MissingCompileTimeError
-dynamic_prefix_core_test/01: MissingCompileTimeError
-dynamic_prefix_core_test/none: RuntimeError
-empty_block_case_test: MissingCompileTimeError
-enum_private_test/02: MissingCompileTimeError
-error_stacktrace_test/00: MissingCompileTimeError
-export_ambiguous_main_test: MissingCompileTimeError
-f_bounded_quantification_test/01: MissingCompileTimeError
-f_bounded_quantification_test/02: MissingCompileTimeError
-factory1_test/00: MissingCompileTimeError
-factory1_test/01: MissingCompileTimeError
-factory2_test/03: MissingCompileTimeError
-factory2_test/none: MissingCompileTimeError
-factory3_test/none: MissingCompileTimeError
-factory4_test/00: MissingCompileTimeError
-factory5_test/00: MissingCompileTimeError
-factory6_test/00: MissingCompileTimeError
-factory_redirection_test/01: MissingCompileTimeError
-factory_redirection_test/02: MissingCompileTimeError
-factory_redirection_test/03: MissingCompileTimeError
-factory_redirection_test/05: MissingCompileTimeError
-factory_redirection_test/06: MissingCompileTimeError
-factory_redirection_test/08: MissingCompileTimeError
-factory_redirection_test/09: MissingCompileTimeError
-factory_redirection_test/10: MissingCompileTimeError
-factory_redirection_test/11: MissingCompileTimeError
-factory_redirection_test/12: MissingCompileTimeError
-factory_redirection_test/13: MissingCompileTimeError
-factory_redirection_test/14: MissingCompileTimeError
-factory_redirection_test/none: MissingCompileTimeError
-factory_return_type_checked_test/00: MissingCompileTimeError
-field3_test/01: MissingCompileTimeError
-field_method4_test: MissingCompileTimeError
-field_override2_test: MissingCompileTimeError
-field_override_test/00: MissingCompileTimeError
-field_override_test/01: MissingCompileTimeError
-field_override_test/02: MissingCompileTimeError
-field_override_test/none: MissingCompileTimeError
-field_type_check_test/01: MissingCompileTimeError
-final_for_in_variable_test: MissingCompileTimeError
-final_param_test: MissingCompileTimeError
-final_super_field_set_test: MissingCompileTimeError
-final_syntax_test/10: MissingCompileTimeError
-final_variable_assignment_test/01: MissingCompileTimeError
-final_variable_assignment_test/02: MissingCompileTimeError
-final_variable_assignment_test/03: MissingCompileTimeError
-final_variable_assignment_test/04: MissingCompileTimeError
-first_class_types_literals_test/03: MissingCompileTimeError
-first_class_types_literals_test/04: MissingCompileTimeError
-first_class_types_literals_test/05: MissingCompileTimeError
-first_class_types_literals_test/06: MissingCompileTimeError
-first_class_types_literals_test/07: MissingCompileTimeError
-first_class_types_literals_test/08: MissingCompileTimeError
-first_class_types_literals_test/09: MissingCompileTimeError
-first_class_types_literals_test/10: MissingCompileTimeError
-first_class_types_literals_test/11: MissingCompileTimeError
-first_class_types_literals_test/12: MissingCompileTimeError
-flatten_test/05: MissingRuntimeError
-flatten_test/08: MissingRuntimeError
-flatten_test/09: MissingRuntimeError
-flatten_test/12: MissingRuntimeError
-for_in3_test: MissingCompileTimeError
-for_in_side_effects_test/01: MissingCompileTimeError
-function_malformed_result_type_test/00: MissingCompileTimeError
-function_propagation_test: RuntimeError
-function_subtype3_test: RuntimeError
-function_subtype_bound_closure1_test: RuntimeError
-function_subtype_bound_closure2_test: RuntimeError
-function_subtype_bound_closure3_test: RuntimeError
-function_subtype_bound_closure4_test: RuntimeError
-function_subtype_bound_closure5_test: RuntimeError
-function_subtype_bound_closure5a_test: RuntimeError
-function_subtype_bound_closure6_test: RuntimeError
-function_subtype_bound_closure7_test: RuntimeError
-function_subtype_call0_test: RuntimeError
-function_subtype_call1_test: RuntimeError
-function_subtype_call2_test: RuntimeError
-function_subtype_cast0_test: RuntimeError
-function_subtype_cast1_test: RuntimeError
-function_subtype_cast2_test: RuntimeError
-function_subtype_cast3_test: RuntimeError
-function_subtype_checked0_test: RuntimeError
-function_subtype_local1_test: RuntimeError
-function_subtype_local2_test: RuntimeError
-function_subtype_local5_test: RuntimeError
-function_subtype_not0_test: RuntimeError
-function_subtype_not1_test: RuntimeError
-function_subtype_not2_test: RuntimeError
-function_subtype_not3_test: RuntimeError
-function_subtype_top_level1_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
-function_type_alias3_test: RuntimeError
-function_type_alias4_test: RuntimeError
-function_type_alias_test: RuntimeError
-function_type_call_getter2_test/00: MissingCompileTimeError
-function_type_call_getter2_test/01: MissingCompileTimeError
-function_type_call_getter2_test/02: MissingCompileTimeError
-function_type_call_getter2_test/03: MissingCompileTimeError
-function_type_call_getter2_test/04: MissingCompileTimeError
-function_type_call_getter2_test/05: MissingCompileTimeError
-fuzzy_arrows_test/01: MissingCompileTimeError
-fuzzy_arrows_test/03: RuntimeError
-generic_closure_test: RuntimeError
-generic_constructor_mixin2_test/01: MissingCompileTimeError
-generic_constructor_mixin3_test/01: MissingCompileTimeError
-generic_constructor_mixin_test/01: MissingCompileTimeError
-generic_field_mixin6_test/01: MissingCompileTimeError
-generic_function_bounds_test: RuntimeError
-generic_function_dcall_test: RuntimeError
-generic_function_type_as_type_argument_test/02: MissingCompileTimeError, OK # No type inference
-generic_function_typedef2_test/04: MissingCompileTimeError
-generic_instanceof_test: RuntimeError
-generic_method_types_test/02: RuntimeError, OK # No support for covariant tear-off in VM.
-generic_methods_bounds_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/03: MissingCompileTimeError
-generic_methods_generic_class_tearoff_test: RuntimeError
-generic_methods_overriding_test/01: MissingCompileTimeError
-generic_methods_overriding_test/03: MissingCompileTimeError
-generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_tearoff_specialization_test: RuntimeError
-generic_methods_unused_parameter_test: RuntimeError
-generic_no_such_method_dispatcher_simple_test: Skip # This test is only for kernel.
-generic_tearoff_test: RuntimeError
-generic_test/01: MissingCompileTimeError
-generic_test/none: RuntimeError # test requires Dart 2 subtyping for `is`
-getter_no_setter2_test/00: MissingCompileTimeError
-getter_no_setter2_test/01: MissingCompileTimeError
-getter_no_setter2_test/03: MissingCompileTimeError
-getter_no_setter_test/00: MissingCompileTimeError
-getter_no_setter_test/01: MissingCompileTimeError
-getter_no_setter_test/03: MissingCompileTimeError
-getter_override_test/03: MissingCompileTimeError
-getters_setters2_test/02: MissingCompileTimeError
-identical_const_test/01: MissingCompileTimeError
-identical_const_test/02: MissingCompileTimeError
-identical_const_test/03: MissingCompileTimeError
-identical_const_test/04: MissingCompileTimeError
-if_null_assignment_behavior_test/03: MissingCompileTimeError
-if_null_assignment_behavior_test/13: MissingCompileTimeError
-if_null_assignment_behavior_test/15: MissingCompileTimeError
-if_null_assignment_static_test/02: MissingCompileTimeError
-if_null_assignment_static_test/04: MissingCompileTimeError
-if_null_assignment_static_test/06: MissingCompileTimeError
-if_null_assignment_static_test/07: MissingCompileTimeError
-if_null_assignment_static_test/09: MissingCompileTimeError
-if_null_assignment_static_test/11: MissingCompileTimeError
-if_null_assignment_static_test/13: MissingCompileTimeError
-if_null_assignment_static_test/14: MissingCompileTimeError
-if_null_assignment_static_test/16: MissingCompileTimeError
-if_null_assignment_static_test/18: MissingCompileTimeError
-if_null_assignment_static_test/20: MissingCompileTimeError
-if_null_assignment_static_test/21: MissingCompileTimeError
-if_null_assignment_static_test/23: MissingCompileTimeError
-if_null_assignment_static_test/25: MissingCompileTimeError
-if_null_assignment_static_test/27: MissingCompileTimeError
-if_null_assignment_static_test/28: MissingCompileTimeError
-if_null_assignment_static_test/30: MissingCompileTimeError
-if_null_assignment_static_test/32: MissingCompileTimeError
-if_null_assignment_static_test/34: MissingCompileTimeError
-if_null_assignment_static_test/35: MissingCompileTimeError
-if_null_assignment_static_test/37: MissingCompileTimeError
-if_null_assignment_static_test/39: MissingCompileTimeError
-if_null_assignment_static_test/41: MissingCompileTimeError
-if_null_assignment_static_test/42: MissingCompileTimeError
-if_null_precedence_test/06: MissingCompileTimeError
-if_null_precedence_test/07: MissingCompileTimeError
-implicit_downcast_during_for_in_iterable_test: RuntimeError
-implicit_downcast_during_function_literal_arrow_test: RuntimeError
-implicit_downcast_during_function_literal_return_test: RuntimeError
-implicit_downcast_during_yield_star_test: RuntimeError
-implicit_downcast_during_yield_test: RuntimeError
-implicit_this_test/01: MissingCompileTimeError
-implicit_this_test/02: MissingCompileTimeError
-implicit_this_test/04: MissingCompileTimeError
-import_combinators2_test/00: MissingCompileTimeError
-import_self_test/01: MissingCompileTimeError
-inferrer_constructor5_test/01: MissingCompileTimeError
-initializing_formal_final_test: MissingCompileTimeError
-initializing_formal_type_test: MissingCompileTimeError
-instanceof2_test: RuntimeError
-instantiate_tearoff_after_contravariance_check_test: RuntimeError
-instantiate_tearoff_of_call_test: RuntimeError
-instantiate_tearoff_test: RuntimeError
-instantiate_type_variable_test/01: MissingCompileTimeError
-interface_test/00: MissingCompileTimeError
-invalid_cast_test/01: MissingCompileTimeError
-invalid_cast_test/02: MissingCompileTimeError
-invalid_cast_test/03: MissingCompileTimeError
-invalid_cast_test/04: MissingCompileTimeError
-invalid_cast_test/07: MissingCompileTimeError
-invalid_cast_test/08: MissingCompileTimeError
-invalid_cast_test/09: MissingCompileTimeError
-invalid_cast_test/10: MissingCompileTimeError
-invalid_cast_test/11: MissingCompileTimeError
-issue31596_override_test/05: MissingCompileTimeError
-issue31596_override_test/06: MissingCompileTimeError
-issue31596_override_test/07: MissingCompileTimeError
-issue31596_override_test/08: MissingCompileTimeError
-issue31596_super_test/02: MissingCompileTimeError
-issue31596_super_test/04: MissingCompileTimeError
-issue31596_super_test/05: RuntimeError
-issue31596_tearoff_test: RuntimeError
-issue32353_2_test: MissingCompileTimeError # Issue 32353
-issue32353_test: RuntimeError
-least_upper_bound_expansive_test/none: CompileTimeError
-least_upper_bound_test/03: MissingCompileTimeError
-least_upper_bound_test/04: MissingCompileTimeError
-least_upper_bound_test/10: MissingCompileTimeError
-least_upper_bound_test/19: MissingCompileTimeError
-least_upper_bound_test/20: MissingCompileTimeError
-least_upper_bound_test/23: MissingCompileTimeError
-least_upper_bound_test/24: MissingCompileTimeError
-least_upper_bound_test/29: MissingCompileTimeError
-least_upper_bound_test/30: MissingCompileTimeError
-least_upper_bound_test/32: MissingCompileTimeError
-library_ambiguous_test/00: MissingCompileTimeError
-library_ambiguous_test/01: MissingCompileTimeError
-library_ambiguous_test/02: MissingCompileTimeError
-library_ambiguous_test/03: MissingCompileTimeError
-library_ambiguous_test/04: MissingCompileTimeError
-list_literal4_test/00: MissingCompileTimeError
-list_literal4_test/01: MissingCompileTimeError
-list_literal4_test/03: MissingCompileTimeError
-list_literal4_test/04: MissingCompileTimeError
-list_literal4_test/05: MissingCompileTimeError
-list_literal_syntax_test/01: MissingCompileTimeError
-list_literal_syntax_test/02: MissingCompileTimeError
-list_literal_syntax_test/03: MissingCompileTimeError
-local_function2_test/01: MissingCompileTimeError
-local_function2_test/02: MissingCompileTimeError
-local_function2_test/none: RuntimeError
-local_function3_test/01: MissingCompileTimeError
-local_function3_test/none: RuntimeError
-local_function_test/01: MissingCompileTimeError
-local_function_test/02: MissingCompileTimeError
-local_function_test/03: MissingCompileTimeError
-local_function_test/04: MissingCompileTimeError
-local_function_test/none: RuntimeError
-logical_expression3_test: MissingCompileTimeError
-main_test/03: RuntimeError
-malbounded_instantiation_test/01: MissingCompileTimeError
-malbounded_instantiation_test/02: MissingCompileTimeError
-malbounded_instantiation_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/02: MissingCompileTimeError
-malbounded_redirecting_factory_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/04: MissingCompileTimeError
-malbounded_redirecting_factory_test/05: MissingCompileTimeError
-malbounded_type_cast2_test: MissingCompileTimeError
-malbounded_type_cast_test/00: MissingCompileTimeError
-malbounded_type_cast_test/01: MissingCompileTimeError
-malbounded_type_cast_test/02: MissingCompileTimeError
-malbounded_type_literal_test/00: MissingCompileTimeError
-malbounded_type_test2_test/00: MissingCompileTimeError
-malbounded_type_test_test/00: MissingCompileTimeError
-malbounded_type_test_test/01: MissingCompileTimeError
-malbounded_type_test_test/02: MissingCompileTimeError
-malformed2_test/01: MissingCompileTimeError
-malformed2_test/02: MissingCompileTimeError
-malformed2_test/03: MissingCompileTimeError
-malformed2_test/04: MissingCompileTimeError
-malformed2_test/05: MissingCompileTimeError
-malformed2_test/06: MissingCompileTimeError
-malformed2_test/07: MissingCompileTimeError
-malformed2_test/08: MissingCompileTimeError
-malformed2_test/09: MissingCompileTimeError
-malformed2_test/10: MissingCompileTimeError
-malformed2_test/11: MissingCompileTimeError
-malformed2_test/12: MissingCompileTimeError
-malformed2_test/13: MissingCompileTimeError
-malformed_bound_test/00: MissingCompileTimeError
-malformed_bound_test/01: MissingCompileTimeError
-malformed_inheritance_test/01: MissingCompileTimeError
-malformed_inheritance_test/03: MissingCompileTimeError
-malformed_inheritance_test/05: MissingCompileTimeError
-malformed_test/00: MissingCompileTimeError
-malformed_test/01: MissingCompileTimeError
-malformed_test/02: MissingCompileTimeError
-malformed_test/03: MissingCompileTimeError
-malformed_test/04: MissingCompileTimeError
-malformed_test/05: MissingCompileTimeError
-malformed_test/06: MissingCompileTimeError
-malformed_test/07: MissingCompileTimeError
-malformed_test/08: MissingCompileTimeError
-malformed_test/09: MissingCompileTimeError
-malformed_test/10: MissingCompileTimeError
-malformed_test/11: MissingCompileTimeError
-malformed_test/12: MissingCompileTimeError
-malformed_test/13: MissingCompileTimeError
-malformed_test/14: MissingCompileTimeError
-malformed_test/15: MissingCompileTimeError
-malformed_test/16: MissingCompileTimeError
-malformed_test/17: MissingCompileTimeError
-malformed_test/18: MissingCompileTimeError
-malformed_test/19: MissingCompileTimeError
-malformed_test/20: MissingCompileTimeError
-malformed_test/21: MissingCompileTimeError
-malformed_test/22: MissingCompileTimeError
-malformed_test/23: MissingCompileTimeError
-malformed_test/24: MissingCompileTimeError
-malformed_type_test: MissingCompileTimeError
-many_generic_instanceof_test: RuntimeError
-method_override2_test/00: MissingCompileTimeError
-method_override2_test/01: MissingCompileTimeError
-method_override2_test/02: MissingCompileTimeError
-method_override2_test/03: MissingCompileTimeError
-method_override3_test/00: MissingCompileTimeError
-method_override3_test/01: MissingCompileTimeError
-method_override3_test/02: MissingCompileTimeError
-method_override4_test/01: MissingCompileTimeError
-method_override4_test/02: MissingCompileTimeError
-method_override4_test/03: MissingCompileTimeError
-method_override5_test/01: MissingCompileTimeError
-method_override5_test/02: MissingCompileTimeError
-method_override5_test/03: MissingCompileTimeError
-method_override6_test/01: MissingCompileTimeError
-method_override6_test/02: MissingCompileTimeError
-method_override6_test/03: MissingCompileTimeError
-method_override7_test/03: MissingCompileTimeError
-method_override8_test/03: MissingCompileTimeError
-method_override_test: RuntimeError, OK # No support for covariant tear-off in VM.
-mixin_illegal_constructor_test/13: MissingCompileTimeError
-mixin_illegal_constructor_test/14: MissingCompileTimeError
-mixin_illegal_constructor_test/15: MissingCompileTimeError
-mixin_illegal_constructor_test/16: MissingCompileTimeError
-mixin_illegal_static_access_test/01: MissingCompileTimeError
-mixin_illegal_static_access_test/02: MissingCompileTimeError
-mixin_illegal_syntax_test/13: MissingCompileTimeError
-mixin_invalid_bound2_test/02: MissingCompileTimeError
-mixin_invalid_bound2_test/03: MissingCompileTimeError
-mixin_invalid_bound2_test/04: MissingCompileTimeError
-mixin_invalid_bound2_test/05: MissingCompileTimeError
-mixin_invalid_bound2_test/06: MissingCompileTimeError
-mixin_invalid_bound2_test/07: MissingCompileTimeError
-mixin_invalid_bound2_test/08: MissingCompileTimeError
-mixin_invalid_bound2_test/09: MissingCompileTimeError
-mixin_invalid_bound2_test/10: MissingCompileTimeError
-mixin_invalid_bound2_test/11: MissingCompileTimeError
-mixin_invalid_bound2_test/12: MissingCompileTimeError
-mixin_invalid_bound2_test/13: MissingCompileTimeError
-mixin_invalid_bound2_test/14: MissingCompileTimeError
-mixin_invalid_bound2_test/15: MissingCompileTimeError
-mixin_invalid_bound_test/02: MissingCompileTimeError
-mixin_invalid_bound_test/03: MissingCompileTimeError
-mixin_invalid_bound_test/04: MissingCompileTimeError
-mixin_invalid_bound_test/05: MissingCompileTimeError
-mixin_invalid_bound_test/06: MissingCompileTimeError
-mixin_invalid_bound_test/07: MissingCompileTimeError
-mixin_invalid_bound_test/08: MissingCompileTimeError
-mixin_invalid_bound_test/09: MissingCompileTimeError
-mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_of_mixin_test/01: MissingCompileTimeError
-mixin_of_mixin_test/02: MissingCompileTimeError
-mixin_of_mixin_test/03: MissingCompileTimeError
-mixin_of_mixin_test/04: MissingCompileTimeError
-mixin_of_mixin_test/05: MissingCompileTimeError
-mixin_of_mixin_test/06: MissingCompileTimeError
-mixin_super_2_test/01: MissingCompileTimeError
-mixin_super_2_test/03: MissingCompileTimeError
-mixin_super_bound_test/01: MissingCompileTimeError
-mixin_super_bound_test/02: MissingCompileTimeError
-mixin_supertype_subclass_test/02: MissingCompileTimeError
-mixin_supertype_subclass_test/05: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/01: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/02: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/03: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/03: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/05: RuntimeError
-mixin_type_parameter_inference_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_test/05: MissingCompileTimeError
-mixin_type_parameter_inference_test/06: MissingCompileTimeError
-mixin_type_parameter_inference_test/07: MissingCompileTimeError
-mixin_type_parameter_inference_test/08: RuntimeError
-mixin_type_parameter_inference_test/09: RuntimeError
-mixin_type_parameter_inference_test/11: MissingCompileTimeError
-mixin_type_parameter_inference_test/14: MissingCompileTimeError
-mixin_type_parameter_inference_test/15: MissingCompileTimeError
-mixin_type_parameters_errors_test/01: MissingCompileTimeError
-mixin_type_parameters_errors_test/02: MissingCompileTimeError
-mixin_type_parameters_errors_test/03: MissingCompileTimeError
-mixin_type_parameters_errors_test/04: MissingCompileTimeError
-mixin_type_parameters_errors_test/05: MissingCompileTimeError
-mixin_with_two_implicit_constructors_test: MissingCompileTimeError
-mock_writable_final_private_field_test: RuntimeError # Issue 30849
-named_constructor_test/01: MissingCompileTimeError
-named_constructor_test/03: MissingCompileTimeError
-named_parameters2_test: MissingCompileTimeError
-named_parameters3_test: MissingCompileTimeError
-named_parameters4_test: MissingCompileTimeError
-named_parameters_aggregated_test/05: MissingCompileTimeError
-named_parameters_test/01: MissingCompileTimeError
-named_parameters_test/02: MissingCompileTimeError
-named_parameters_test/03: MissingCompileTimeError
-named_parameters_test/04: MissingCompileTimeError
-named_parameters_test/05: MissingCompileTimeError
-named_parameters_test/06: MissingCompileTimeError
-named_parameters_test/07: MissingCompileTimeError
-named_parameters_test/08: MissingCompileTimeError
-named_parameters_test/09: MissingCompileTimeError
-named_parameters_test/10: MissingCompileTimeError
-named_parameters_type_test/01: MissingCompileTimeError
-named_parameters_type_test/02: MissingCompileTimeError
-named_parameters_type_test/03: MissingCompileTimeError
-new_expression_type_args_test/00: MissingCompileTimeError
-new_expression_type_args_test/01: MissingCompileTimeError
-new_expression_type_args_test/02: MissingCompileTimeError
-new_prefix_test/01: MissingCompileTimeError
-no_such_constructor_test/01: MissingCompileTimeError
-not_enough_positional_arguments_test/00: MissingCompileTimeError
-not_enough_positional_arguments_test/03: MissingCompileTimeError
-not_enough_positional_arguments_test/06: MissingCompileTimeError
-not_enough_positional_arguments_test/07: MissingCompileTimeError
-object_has_no_call_method_test/02: MissingCompileTimeError
-object_has_no_call_method_test/05: MissingCompileTimeError
-object_has_no_call_method_test/08: MissingCompileTimeError
-optional_named_parameters_test/01: MissingCompileTimeError
-optional_named_parameters_test/02: MissingCompileTimeError
-optional_named_parameters_test/03: MissingCompileTimeError
-optional_named_parameters_test/04: MissingCompileTimeError
-optional_named_parameters_test/05: MissingCompileTimeError
-optional_named_parameters_test/06: MissingCompileTimeError
-optional_named_parameters_test/07: MissingCompileTimeError
-optional_named_parameters_test/08: MissingCompileTimeError
-optional_named_parameters_test/09: MissingCompileTimeError
-override_field_test/02: MissingCompileTimeError
-override_field_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/07: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
-override_inheritance_field_test/05: MissingCompileTimeError
-override_inheritance_field_test/07: MissingCompileTimeError
-override_inheritance_field_test/08: MissingCompileTimeError
-override_inheritance_field_test/09: MissingCompileTimeError
-override_inheritance_field_test/10: MissingCompileTimeError
-override_inheritance_field_test/11: MissingCompileTimeError
-override_inheritance_field_test/28: MissingCompileTimeError
-override_inheritance_field_test/30: MissingCompileTimeError
-override_inheritance_field_test/31: MissingCompileTimeError
-override_inheritance_field_test/32: MissingCompileTimeError
-override_inheritance_field_test/33: MissingCompileTimeError
-override_inheritance_field_test/33a: MissingCompileTimeError
-override_inheritance_field_test/34: MissingCompileTimeError
-override_inheritance_field_test/44: MissingCompileTimeError
-override_inheritance_field_test/47: MissingCompileTimeError
-override_inheritance_field_test/48: MissingCompileTimeError
-override_inheritance_field_test/53: MissingCompileTimeError
-override_inheritance_field_test/54: MissingCompileTimeError
-override_inheritance_generic_test/04: MissingCompileTimeError
-override_inheritance_generic_test/06: MissingCompileTimeError
-override_inheritance_generic_test/07: MissingCompileTimeError
-override_inheritance_generic_test/08: MissingCompileTimeError
-override_inheritance_generic_test/09: MissingCompileTimeError
-override_inheritance_generic_test/10: MissingCompileTimeError
-override_inheritance_method_test/04: MissingCompileTimeError
-override_inheritance_method_test/05: MissingCompileTimeError
-override_inheritance_method_test/06: MissingCompileTimeError
-override_inheritance_method_test/11: MissingCompileTimeError
-override_inheritance_method_test/12: MissingCompileTimeError
-override_inheritance_method_test/13: MissingCompileTimeError
-override_inheritance_method_test/14: MissingCompileTimeError
-override_inheritance_method_test/19: MissingCompileTimeError
-override_inheritance_method_test/20: MissingCompileTimeError
-override_inheritance_method_test/21: MissingCompileTimeError
-override_inheritance_method_test/27: MissingCompileTimeError
-override_inheritance_method_test/30: MissingCompileTimeError
-override_inheritance_method_test/31: MissingCompileTimeError
-override_inheritance_method_test/32: MissingCompileTimeError
-override_inheritance_method_test/33: MissingCompileTimeError
-override_inheritance_mixed_test/06: MissingCompileTimeError
-override_inheritance_mixed_test/07: MissingCompileTimeError
-override_inheritance_mixed_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/06: MissingCompileTimeError
-override_inheritance_no_such_method_test/07: MissingCompileTimeError
-override_inheritance_no_such_method_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/10: MissingCompileTimeError
-override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_method_with_field_test/02: MissingCompileTimeError
-part2_test/01: MissingCompileTimeError
-positional_parameters_type_test/01: MissingCompileTimeError
-positional_parameters_type_test/02: MissingCompileTimeError
-prefix16_test/00: MissingCompileTimeError
-prefix16_test/01: MissingCompileTimeError
-prefix22_test/00: MissingCompileTimeError
-prefix23_test/00: MissingCompileTimeError
-prefix_import_collision_test/01: MissingCompileTimeError
-prefix_shadow_test/01: MissingCompileTimeError
-prefix_shadow_test/02: MissingCompileTimeError
-prefix_transitive_import_prefix_test/01: MissingCompileTimeError
-prefix_transitive_import_prefix_test/02: MissingCompileTimeError
-prefix_transitive_import_prefix_test/03: MissingCompileTimeError
-prefix_transitive_import_test/01: MissingCompileTimeError
-prefix_transitive_import_test/02: MissingCompileTimeError
-private_access_test/01: MissingCompileTimeError
-private_access_test/02: MissingCompileTimeError
-private_access_test/03: MissingCompileTimeError
-private_access_test/04: MissingCompileTimeError
-private_access_test/05: MissingCompileTimeError
-private_access_test/06: MissingCompileTimeError
-regress_12561_test: MissingCompileTimeError
-regress_13494_test: MissingCompileTimeError
-regress_17382_test: MissingCompileTimeError
-regress_19413_test: MissingCompileTimeError
-regress_19728_test: MissingCompileTimeError
-regress_21912_test/01: MissingCompileTimeError
-regress_21912_test/02: MissingCompileTimeError
-regress_22438_test: MissingCompileTimeError
-regress_22936_test: MissingCompileTimeError
-regress_23089_test: MissingCompileTimeError
-regress_23408_test: RuntimeError
-regress_26133_test: MissingCompileTimeError
-regress_27572_test: MissingCompileTimeError
-regress_31591_test: RuntimeError, OK # strong mode only
-return_type_test: MissingCompileTimeError
-rewrite_implicit_this_test/01: MissingCompileTimeError
-runtime_type_function_test: RuntimeError
-setter4_test: MissingCompileTimeError # Issue 14736
-setter_no_getter_call_test/01: MissingCompileTimeError
-setter_override_test/01: MissingCompileTimeError
-setter_override_test/02: MissingCompileTimeError
-static_field1_test/01: MissingCompileTimeError
-static_field1a_test/01: MissingCompileTimeError
-static_field3_test/01: MissingCompileTimeError
-static_field3_test/02: MissingCompileTimeError
-static_field3_test/03: MissingCompileTimeError
-static_field3_test/04: MissingCompileTimeError
-static_field_test/01: MissingCompileTimeError
-static_field_test/02: MissingCompileTimeError
-static_field_test/03: MissingCompileTimeError
-static_field_test/04: MissingCompileTimeError
-static_final_field2_test/01: MissingCompileTimeError
-static_getter_no_setter1_test/01: MissingCompileTimeError
-static_getter_no_setter2_test/01: MissingCompileTimeError
-static_initializer_type_error_test: MissingCompileTimeError
-static_setter_get_test/01: MissingCompileTimeError
-string_interpolation_test/01: MissingCompileTimeError
-string_no_operator_test/01: MissingCompileTimeError
-string_no_operator_test/02: MissingCompileTimeError
-string_no_operator_test/03: MissingCompileTimeError
-string_no_operator_test/04: MissingCompileTimeError
-string_no_operator_test/05: MissingCompileTimeError
-string_no_operator_test/06: MissingCompileTimeError
-string_no_operator_test/07: MissingCompileTimeError
-string_no_operator_test/08: MissingCompileTimeError
-string_no_operator_test/09: MissingCompileTimeError
-string_no_operator_test/10: MissingCompileTimeError
-string_no_operator_test/11: MissingCompileTimeError
-string_no_operator_test/12: MissingCompileTimeError
-string_no_operator_test/13: MissingCompileTimeError
-string_no_operator_test/14: MissingCompileTimeError
-string_no_operator_test/15: MissingCompileTimeError
-string_no_operator_test/16: MissingCompileTimeError
-string_test/01: MissingCompileTimeError
-substring_test/01: MissingCompileTimeError
-super_assign_test/01: MissingCompileTimeError
-super_bound_closure_test/01: MissingCompileTimeError
-super_call4_test/01: MissingCompileTimeError
-super_operator_index_test/01: MissingCompileTimeError
-super_operator_index_test/02: MissingCompileTimeError
-super_operator_index_test/03: MissingCompileTimeError
-super_operator_index_test/04: MissingCompileTimeError
-super_operator_index_test/05: MissingCompileTimeError
-super_operator_index_test/06: MissingCompileTimeError
-super_operator_index_test/07: MissingCompileTimeError
-switch_fallthru_test/01: MissingCompileTimeError
-symbol_literal_test/01: MissingCompileTimeError
-sync_generator1_test/01: MissingCompileTimeError
-syntax_test/59: MissingCompileTimeError, OK # Issue 30516.
-syntax_test/60: MissingCompileTimeError, OK # Issue 30516.
-syntax_test/61: MissingCompileTimeError, OK # Issue 30516.
-top_level_getter_no_setter1_test: MissingCompileTimeError
-top_level_getter_no_setter2_test: MissingCompileTimeError
-transitive_private_library_access_test: MissingCompileTimeError
-try_catch_on_syntax_test/07: MissingCompileTimeError
-try_catch_on_syntax_test/10: MissingCompileTimeError
-try_catch_on_syntax_test/11: MissingCompileTimeError
-try_catch_syntax_test/08: MissingCompileTimeError
-type_checks_in_factory_method_test/01: MissingCompileTimeError
-type_inference_accessor_ref_test/03: MissingCompileTimeError
-type_inference_accessor_ref_test/06: MissingCompileTimeError
-type_inference_circularity_test: MissingCompileTimeError
-type_inference_inconsistent_inheritance_test: MissingCompileTimeError
-type_promotion_functions_test/01: MissingCompileTimeError
-type_promotion_functions_test/05: MissingCompileTimeError
-type_promotion_functions_test/06: MissingCompileTimeError
-type_promotion_functions_test/07: MissingCompileTimeError
-type_promotion_functions_test/08: MissingCompileTimeError
-type_promotion_functions_test/10: MissingCompileTimeError
-type_promotion_parameter_test/01: MissingCompileTimeError
-type_promotion_parameter_test/02: MissingCompileTimeError
-type_promotion_parameter_test/03: MissingCompileTimeError
-type_promotion_parameter_test/04: MissingCompileTimeError
-type_promotion_parameter_test/05: MissingCompileTimeError
-type_promotion_parameter_test/06: MissingCompileTimeError
-type_promotion_parameter_test/07: MissingCompileTimeError
-type_promotion_parameter_test/08: MissingCompileTimeError
-type_promotion_parameter_test/09: MissingCompileTimeError
-type_promotion_parameter_test/10: MissingCompileTimeError
-type_promotion_parameter_test/11: MissingCompileTimeError
-type_promotion_parameter_test/12: MissingCompileTimeError
-type_promotion_parameter_test/13: MissingCompileTimeError
-type_promotion_parameter_test/14: MissingCompileTimeError
-type_promotion_parameter_test/15: MissingCompileTimeError
-type_promotion_parameter_test/16: MissingCompileTimeError
-type_promotion_parameter_test/17: MissingCompileTimeError
-type_promotion_parameter_test/18: MissingCompileTimeError
-type_promotion_parameter_test/19: MissingCompileTimeError
-type_promotion_parameter_test/20: MissingCompileTimeError
-type_promotion_parameter_test/21: MissingCompileTimeError
-type_promotion_parameter_test/22: MissingCompileTimeError
-type_promotion_parameter_test/23: MissingCompileTimeError
-type_promotion_parameter_test/24: MissingCompileTimeError
-type_promotion_parameter_test/25: MissingCompileTimeError
-type_promotion_parameter_test/26: MissingCompileTimeError
-type_promotion_parameter_test/27: MissingCompileTimeError
-type_promotion_parameter_test/28: MissingCompileTimeError
-type_promotion_parameter_test/29: MissingCompileTimeError
-type_promotion_parameter_test/30: MissingCompileTimeError
-type_promotion_parameter_test/31: MissingCompileTimeError
-type_promotion_parameter_test/32: MissingCompileTimeError
-type_promotion_parameter_test/33: MissingCompileTimeError
-type_promotion_parameter_test/34: MissingCompileTimeError
-type_promotion_parameter_test/35: MissingCompileTimeError
-type_promotion_parameter_test/36: MissingCompileTimeError
-type_promotion_parameter_test/37: MissingCompileTimeError
-type_promotion_parameter_test/38: MissingCompileTimeError
-type_promotion_parameter_test/39: MissingCompileTimeError
-type_promotion_parameter_test/40: MissingCompileTimeError
-type_promotion_parameter_test/41: MissingCompileTimeError
-type_promotion_parameter_test/42: MissingCompileTimeError
-type_promotion_parameter_test/43: MissingCompileTimeError
-type_promotion_parameter_test/44: MissingCompileTimeError
-type_promotion_parameter_test/45: MissingCompileTimeError
-type_promotion_parameter_test/46: MissingCompileTimeError
-type_promotion_parameter_test/47: MissingCompileTimeError
-type_promotion_parameter_test/48: MissingCompileTimeError
-type_promotion_parameter_test/49: MissingCompileTimeError
-type_promotion_parameter_test/50: MissingCompileTimeError
-type_promotion_parameter_test/51: MissingCompileTimeError
-type_promotion_parameter_test/52: MissingCompileTimeError
-type_promotion_parameter_test/54: MissingCompileTimeError
-type_promotion_parameter_test/55: MissingCompileTimeError
-type_promotion_parameter_test/56: MissingCompileTimeError
-type_variable_bounds2_test: MissingCompileTimeError
-type_variable_bounds3_test/00: MissingCompileTimeError
-type_variable_bounds4_test/01: MissingCompileTimeError
-type_variable_bounds_test/00: MissingCompileTimeError
-type_variable_bounds_test/01: MissingCompileTimeError
-type_variable_bounds_test/02: MissingCompileTimeError
-type_variable_bounds_test/03: MissingCompileTimeError
-type_variable_bounds_test/04: MissingCompileTimeError
-type_variable_bounds_test/05: MissingCompileTimeError
-type_variable_bounds_test/06: MissingCompileTimeError
-type_variable_bounds_test/07: MissingCompileTimeError
-type_variable_bounds_test/08: MissingCompileTimeError
-type_variable_bounds_test/09: MissingCompileTimeError
-type_variable_bounds_test/10: MissingCompileTimeError
-type_variable_bounds_test/11: MissingCompileTimeError
-type_variable_conflict2_test/01: MissingCompileTimeError
-type_variable_conflict2_test/03: MissingCompileTimeError
-type_variable_conflict2_test/04: MissingCompileTimeError
-type_variable_conflict2_test/05: MissingCompileTimeError
-type_variable_conflict2_test/07: MissingCompileTimeError
-type_variable_conflict2_test/09: MissingCompileTimeError
-type_variable_identifier_expression_test: MissingCompileTimeError
-type_variable_scope2_test: MissingCompileTimeError
-type_variable_scope_test/00: MissingCompileTimeError
-type_variable_scope_test/01: MissingCompileTimeError
-type_variable_scope_test/02: MissingCompileTimeError
-type_variable_scope_test/04: MissingCompileTimeError
-type_variable_scope_test/05: MissingCompileTimeError
-type_variable_static_context_test: MissingCompileTimeError
-typed_selector2_test: MissingCompileTimeError
-unbound_getter_test: MissingCompileTimeError
-unresolved_default_constructor_test/01: MissingCompileTimeError
-unresolved_in_factory_test: MissingCompileTimeError
-unresolved_top_level_method_test: MissingCompileTimeError
-unresolved_top_level_var_test: MissingCompileTimeError
-variable_shadow_class_test/01: MissingCompileTimeError
-
-[ $compiler != dartk && $runtime == vm && $checked ]
-call_method_as_cast_test/06: RuntimeError
-call_method_implicit_invoke_local_test/05: MissingCompileTimeError
-call_method_implicit_tear_off_implements_function_test/05: RuntimeError
-call_method_implicit_tear_off_implements_function_test/06: RuntimeError
-call_method_is_check_test/06: RuntimeError
-call_operator_test/01: RuntimeError
-call_operator_test/02: RuntimeError
-call_type_literal_test: RuntimeError
-call_with_no_such_method_test: RuntimeError
-class_literal_static_test/none: RuntimeError
-class_literal_test/none: RuntimeError
-constructor_call_as_function_test: RuntimeError
-constructor_call_as_function_test/01: MissingCompileTimeError
-covariance_type_parameter_test/01: RuntimeError
-covariance_type_parameter_test/02: RuntimeError
-covariance_type_parameter_test/03: RuntimeError
-covariance_type_parameter_test/none: RuntimeError
-covariant_subtyping_test: RuntimeError
-factory_implementation_test/00: Fail
-function_call_generic_test: RuntimeError # Type argument not inferred.
-function_type/function_type0_test: RuntimeError # Issue 30475
-function_type/function_type10_test: RuntimeError # Issue 30475
-function_type/function_type12_test: RuntimeError # Issue 30475
-function_type/function_type13_test: RuntimeError # Issue 30475
-function_type/function_type14_test: RuntimeError # Issue 30475
-function_type/function_type15_test: RuntimeError # Issue 30475
-function_type/function_type16_test: RuntimeError # Issue 30475
-function_type/function_type17_test: RuntimeError # Issue 30475
-function_type/function_type18_test: RuntimeError # Issue 30475
-function_type/function_type19_test: RuntimeError # Issue 30475
-function_type/function_type1_test: RuntimeError # Issue 30475
-function_type/function_type20_test: RuntimeError # Issue 30475
-function_type/function_type21_test: RuntimeError # Issue 30475
-function_type/function_type22_test: RuntimeError # Issue 30475
-function_type/function_type24_test: RuntimeError # Issue 30475
-function_type/function_type25_test: RuntimeError # Issue 30475
-function_type/function_type26_test: RuntimeError # Issue 30475
-function_type/function_type27_test: RuntimeError # Issue 30475
-function_type/function_type28_test: RuntimeError # Issue 30475
-function_type/function_type29_test: RuntimeError # Issue 30475
-function_type/function_type2_test: RuntimeError # Issue 30475
-function_type/function_type30_test: RuntimeError # Issue 30475
-function_type/function_type31_test: RuntimeError # Issue 30475
-function_type/function_type32_test: RuntimeError # Issue 30475
-function_type/function_type33_test: RuntimeError # Issue 30475
-function_type/function_type34_test: RuntimeError # Issue 30475
-function_type/function_type36_test: RuntimeError # Issue 30475
-function_type/function_type3_test: RuntimeError # Issue 30475
-function_type/function_type44_test: RuntimeError # Issue 30475
-function_type/function_type45_test: RuntimeError # Issue 30475
-function_type/function_type46_test: RuntimeError # Issue 30475
-function_type/function_type47_test: RuntimeError # Issue 30475
-function_type/function_type48_test: RuntimeError # Issue 30475
-function_type/function_type49_test: RuntimeError # Issue 30475
-function_type/function_type4_test: RuntimeError # Issue 30475
-function_type/function_type50_test: RuntimeError # Issue 30475
-function_type/function_type51_test: RuntimeError # Issue 30475
-function_type/function_type52_test: RuntimeError # Issue 30475
-function_type/function_type53_test: RuntimeError # Issue 30475
-function_type/function_type54_test: RuntimeError # Issue 30475
-function_type/function_type56_test: RuntimeError # Issue 30475
-function_type/function_type57_test: RuntimeError # Issue 30475
-function_type/function_type58_test: RuntimeError # Issue 30475
-function_type/function_type59_test: RuntimeError # Issue 30475
-function_type/function_type5_test: RuntimeError # Issue 30475
-function_type/function_type60_test: RuntimeError # Issue 30475
-function_type/function_type61_test: RuntimeError # Issue 30475
-function_type/function_type62_test: RuntimeError # Issue 30475
-function_type/function_type63_test: RuntimeError # Issue 30475
-function_type/function_type64_test: RuntimeError # Issue 30475
-function_type/function_type65_test: RuntimeError # Issue 30475
-function_type/function_type66_test: RuntimeError # Issue 30475
-function_type/function_type6_test: RuntimeError # Issue 30475
-function_type/function_type7_test: RuntimeError # Issue 30475
-function_type/function_type80_test: RuntimeError # Issue 30475
-function_type/function_type81_test: RuntimeError # Issue 30475
-function_type/function_type82_test: RuntimeError # Issue 30475
-function_type/function_type83_test: RuntimeError # Issue 30475
-function_type/function_type84_test: RuntimeError # Issue 30475
-function_type/function_type85_test: RuntimeError # Issue 30475
-function_type/function_type86_test: RuntimeError # Issue 30475
-function_type/function_type87_test: RuntimeError # Issue 30475
-function_type/function_type88_test: RuntimeError # Issue 30475
-function_type/function_type89_test: RuntimeError # Issue 30475
-function_type/function_type8_test: RuntimeError # Issue 30475
-function_type/function_type90_test: RuntimeError # Issue 30475
-function_type/function_type96_test: RuntimeError # Issue 30475
-function_type/function_type9_test: RuntimeError # Issue 30475
-function_type_alias2_test: RuntimeError
-function_type_alias6_test/none: RuntimeError
-invalid_override_in_mixin_test/01: MissingCompileTimeError
-type_literal_prefix_call_test: RuntimeError
-vm/regress_33040_instantiation_test: RuntimeError
-
-# The VM and does not implement the Dart 2.0 runtime checks yet unless
-# --checked is explicitly passed).
-[ $compiler != dartk && $runtime == vm && !$checked && !$strong ]
-bool_check_test: RuntimeError
-bool_condition_check_test: RuntimeError
-callable_test/none: RuntimeError
-cascaded_forwarding_stubs_generic_test: RuntimeError
-cascaded_forwarding_stubs_test: RuntimeError
-checked_setter2_test: RuntimeError
-checked_setter3_test: RuntimeError
-checked_setter_test: RuntimeError
-const_constructor2_test/13: MissingCompileTimeError
-const_constructor2_test/14: MissingCompileTimeError
-const_constructor2_test/15: MissingCompileTimeError
-const_constructor2_test/16: MissingCompileTimeError
-const_constructor2_test/17: MissingCompileTimeError
-const_constructor2_test/18: MissingCompileTimeError
-const_constructor2_test/20: MissingCompileTimeError
-const_constructor2_test/22: MissingCompileTimeError
-const_constructor2_test/24: MissingCompileTimeError
-const_constructor3_test/02: MissingCompileTimeError
-const_constructor3_test/04: MissingCompileTimeError
-const_init2_test/02: MissingCompileTimeError
-covariance_field_test/01: RuntimeError
-covariance_field_test/02: RuntimeError
-covariance_field_test/03: RuntimeError
-covariance_field_test/04: RuntimeError
-covariance_field_test/05: RuntimeError
-covariance_method_test/01: RuntimeError
-covariance_method_test/02: RuntimeError
-covariance_method_test/03: RuntimeError
-covariance_method_test/04: RuntimeError
-covariance_method_test/05: RuntimeError
-covariance_method_test/06: RuntimeError
-covariance_setter_test/01: RuntimeError
-covariance_setter_test/02: RuntimeError
-covariance_setter_test/03: RuntimeError
-covariance_setter_test/04: RuntimeError
-covariance_setter_test/05: RuntimeError
-covariance_setter_test/06: RuntimeError
-covariance_type_parameter_test/01: RuntimeError
-covariance_type_parameter_test/02: RuntimeError
-covariance_type_parameter_test/03: RuntimeError
-covariant_subtyping_tearoff1_test: RuntimeError
-covariant_subtyping_tearoff2_test: RuntimeError
-covariant_subtyping_tearoff3_test: RuntimeError
-covariant_subtyping_test: RuntimeError
-covariant_subtyping_unsafe_call1_test: RuntimeError
-covariant_subtyping_unsafe_call2_test: RuntimeError
-covariant_subtyping_unsafe_call3_test: RuntimeError
-field_override_optimization_test: RuntimeError
-field_type_check2_test/01: MissingRuntimeError
-forwarding_semi_stub_test: RuntimeError
-forwarding_stub_tearoff_generic_test: RuntimeError
-forwarding_stub_tearoff_test: RuntimeError
-function_subtype_checked0_test: RuntimeError
-function_subtype_closure0_test: RuntimeError
-function_subtype_closure1_test: RuntimeError
-function_subtype_factory1_test: RuntimeError
-function_subtype_inline1_test: RuntimeError
-function_subtype_inline2_test: RuntimeError
-function_subtype_regression_ddc_588_test: RuntimeError
-function_subtype_setter0_test: RuntimeError
-function_type2_test: RuntimeError
-function_type_alias2_test: RuntimeError
-function_type_call_getter2_test/none: RuntimeError
-function_type_test: RuntimeError
-generic_field_mixin6_test/none: RuntimeError
-generic_list_checked_test: RuntimeError
-getters_setters2_test/01: RuntimeError
-getters_setters2_test/none: RuntimeError
-if_null_precedence_test/none: RuntimeError
-implicit_downcast_during_assignment_test: RuntimeError
-implicit_downcast_during_combiner_test: RuntimeError
-implicit_downcast_during_compound_assignment_test: RuntimeError
-implicit_downcast_during_conditional_expression_test: RuntimeError
-implicit_downcast_during_constructor_initializer_test: RuntimeError
-implicit_downcast_during_constructor_invocation_test: RuntimeError
-implicit_downcast_during_do_test: RuntimeError
-implicit_downcast_during_factory_constructor_invocation_test: RuntimeError
-implicit_downcast_during_field_declaration_test: RuntimeError
-implicit_downcast_during_for_condition_test: RuntimeError
-implicit_downcast_during_for_in_element_test: RuntimeError
-implicit_downcast_during_for_initializer_expression_test: RuntimeError
-implicit_downcast_during_for_initializer_var_test: RuntimeError
-implicit_downcast_during_if_null_assignment_test: RuntimeError
-implicit_downcast_during_if_statement_test: RuntimeError
-implicit_downcast_during_indexed_assignment_test: RuntimeError
-implicit_downcast_during_indexed_compound_assignment_test: RuntimeError
-implicit_downcast_during_indexed_get_test: RuntimeError
-implicit_downcast_during_indexed_if_null_assignment_test: RuntimeError
-implicit_downcast_during_invocation_test: RuntimeError
-implicit_downcast_during_list_literal_test: RuntimeError
-implicit_downcast_during_logical_expression_test: RuntimeError
-implicit_downcast_during_map_literal_test: RuntimeError
-implicit_downcast_during_method_invocation_test: RuntimeError
-implicit_downcast_during_not_test: RuntimeError
-implicit_downcast_during_null_aware_method_invocation_test: RuntimeError
-implicit_downcast_during_redirecting_initializer_test: RuntimeError
-implicit_downcast_during_return_async_test: RuntimeError
-implicit_downcast_during_return_test: RuntimeError
-implicit_downcast_during_static_method_invocation_test: RuntimeError
-implicit_downcast_during_super_initializer_test: RuntimeError
-implicit_downcast_during_super_method_invocation_test: RuntimeError
-implicit_downcast_during_variable_declaration_test: RuntimeError
-implicit_downcast_during_while_statement_test: RuntimeError
-inferrer_synthesized_constructor_test: RuntimeError
-issue31596_implement_covariant_test: RuntimeError
-issue31596_test: RuntimeError
-list_is_test: RuntimeError
-list_literal1_test/01: MissingCompileTimeError
-malformed2_test/00: MissingCompileTimeError
-type_argument_in_super_type_test: RuntimeError
-type_check_const_function_typedef2_test: MissingCompileTimeError
-typevariable_substitution2_test/02: RuntimeError
-
-[ $compiler != dartk && $runtime == vm && !$strong ]
-covariant_subtyping_with_substitution_test: RuntimeError
-function_subtype_named1_test: RuntimeError
-function_subtype_named2_test: RuntimeError
-function_subtype_optional1_test: RuntimeError
-function_subtype_optional2_test: RuntimeError
-function_subtype_typearg2_test: RuntimeError
-function_subtype_typearg3_test: RuntimeError
-generic_function_typedef_test/01: RuntimeError
-generic_methods_named_parameters_test: RuntimeError
-generic_methods_optional_parameters_test: RuntimeError
-instanceof4_test/01: RuntimeError
-instanceof4_test/none: RuntimeError
-list_is_test: RuntimeError
-malbounded_type_cast_test/none: RuntimeError
-malbounded_type_test_test/none: RuntimeError
-map_literal8_test: RuntimeError
-mixin_type_parameters_mixin_extends_test: RuntimeError
-mixin_type_parameters_mixin_test: RuntimeError
-mixin_type_parameters_super_extends_test: RuntimeError
-mixin_type_parameters_super_test: RuntimeError
-no_such_method_mock_test: RuntimeError
-override_inheritance_mixed_test/08: MissingCompileTimeError
-regress_28341_test: Fail # Issue 28340
-type_variable_nested_test/01: RuntimeError
-type_variable_promotion_test: RuntimeError
-
-[ $compiler != dartkp && $mode == product && $runtime == dart_precompiled ]
-vm/type_vm_test/28: MissingRuntimeError
-vm/type_vm_test/29: MissingRuntimeError
-vm/type_vm_test/30: MissingRuntimeError
-vm/type_vm_test/31: MissingRuntimeError
-vm/type_vm_test/32: MissingRuntimeError
-vm/type_vm_test/33: MissingRuntimeError
-vm/type_vm_test/34: MissingRuntimeError
-vm/type_vm_test/35: MissingRuntimeError
-vm/type_vm_test/36: MissingRuntimeError
-
-[ $compiler == none && $mode != product && $runtime == vm ]
-vm/type_vm_test/none: RuntimeError
-
-[ $compiler == none && $runtime == vm ]
-async_star_cancel_while_paused_test: RuntimeError
-async_star_pause_test: Fail, OK
-async_star_regression_2238_test: CompileTimeError, RuntimeError
-class_keyword_test/02: MissingCompileTimeError # Issue 13627
-constructor3_test: Fail, OK, Pass
-cyclic_type2_test: Fail, OK
-cyclic_type_test/00: RuntimeError, OK # Not running in strong mode.
-cyclic_type_test/02: Fail, OK # Non-contractive types are not supported in the vm.
-cyclic_type_test/03: RuntimeError, OK # Not running in strong mode.
-cyclic_type_test/04: Fail, OK
-deferred_redirecting_factory_test: Fail, Crash # Issue 23408
-duplicate_export_negative_test: Fail # Issue 6134
-dynamic_prefix_core_test/01: RuntimeError # Issue 12478
-example_constructor_test: Fail, OK
-export_ambiguous_main_negative_test: Fail # Issue 14763
-f_bounded_quantification4_test: RuntimeError, OK # Not running in strong mode.
-field_initialization_order_test: Fail, OK
-generic_methods_bounds_test/02: MissingRuntimeError
-library_env_test/has_html_support: RuntimeError, OK
-library_env_test/has_no_io_support: RuntimeError, OK
-main_not_a_function_test: Skip
-mixin_illegal_super_use_test: Skip # Issues 24478 and 23773
-mixin_illegal_superclass_test: Skip # Issues 24478 and 23773
-mixin_mixin6_test: RuntimeError, OK # Not running in strong mode.
-multiline_strings_test: Fail # Issue 23020
-no_main_test/01: Skip
-regress_19413_test: MissingCompileTimeError
-regress_21793_test/01: MissingCompileTimeError
-super_test: Fail, OK
-type_variable_scope_test/03: MissingCompileTimeError
-unicode_bom_test: Fail # Issue 16067
-vm/debug_break_enabled_vm_test/01: Crash, OK # Expected to hit breakpoint.
-vm/regress_29145_test: Skip # Issue 29145
-vm/regress_33073_test: Skip # Issue 33073
-
-[ $compiler == none && $runtime == vm && $system == fuchsia ]
-async_await_test: RuntimeError
-async_star_test: RuntimeError
-closure_cycles_test: Pass, Crash
-vm/causal_async_exception_stack2_test: RuntimeError
-vm/causal_async_exception_stack_test: RuntimeError
-vm/math_vm_test: Crash
-
-[ $compiler == none && $runtime == vm && $checked ]
-assert_initializer_test/4*: MissingCompileTimeError # Issue 392. The VM doesn't enforce that potentially const expressions are actually const expressions when the constructor is called with `const`.
-dynamic_test: RuntimeError
-generic_functions_test: Pass # Issue 25869
-generic_local_functions_test: Pass # Issue 25869
-generic_methods_function_type_test: Pass # Issue 25869
-generic_methods_generic_function_parameter_test: Pass # Issue 25869
-generic_methods_new_test: Pass # Issue 25869
-generic_methods_test: Pass # Issue 25869
-library_test/01: MissingCompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError
-nsm5_test: MissingCompileTimeError
-override_inheritance_no_such_method_test/05: MissingCompileTimeError
-type_alias_equality_test/01: RuntimeError # Issue 32783
-type_alias_equality_test/02: RuntimeError # Issue 32783
-type_alias_equality_test/03: RuntimeError # Issue 32783
-type_alias_equality_test/04: RuntimeError # Issue 32783
-
-[ $compiler == none && $runtime == vm && !$checked ]
-assertion_initializer_const_error_test/01: MissingCompileTimeError
-assertion_initializer_const_function_error_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/02: MissingRuntimeError
-generic_methods_dynamic_test/04: MissingRuntimeError
-type_parameter_test/05: MissingCompileTimeError
-
-[ ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-const_cast2_test/01: CompileTimeError
-
-[ $compiler != dartk && $runtime == vm || $compiler != dartkp && $runtime == dart_precompiled ]
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Error only in strong mode
-int64_literal_test/*: Skip # This is testing Dart 2.0 int64 semantics.
-invalid_type_argument_count_test/01: MissingCompileTimeError # Error only in strong mode
-invalid_type_argument_count_test/02: MissingCompileTimeError # Error only in strong mode
-invalid_type_argument_count_test/03: MissingCompileTimeError # Error only in strong mode
-invalid_type_argument_count_test/04: MissingCompileTimeError # Error only in strong mode
-partial_tearoff_instantiation_test/none: CompileTimeError
+[ !$strong && ($runtime == dart_precompiled || $runtime == vm) ]
+*: SkipByDesign # tests/language has the non-strong mode versions of these tests.
diff --git a/tests/language_2/no_such_method_mock_test.dart b/tests/language_2/no_such_method_mock_test.dart
index 49d8f24..62f83bf 100644
--- a/tests/language_2/no_such_method_mock_test.dart
+++ b/tests/language_2/no_such_method_mock_test.dart
@@ -82,7 +82,7 @@
var mock3 = new MockCat3();
Expect.isTrue(mock3.eatFood("cat food", amount: 0.9));
Expect.isFalse(mock3.eatFood("cat food", amount: 0.3));
- Expect.equals("chair", mock3.scratch("chair"));
+ Expect.equals("chair,null", mock3.scratch("chair"));
Expect.equals("chair,couch", mock3.scratch("chair", "couch"));
Expect.equals("chair,null", mock3.scratch("chair", null));
Expect.equals("chair,", mock3.scratch("chair", ""));
diff --git a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
index 126c2c0..01a59e7 100644
--- a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
+++ b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
@@ -14,10 +14,12 @@
Expect.equals(invoke.positionalArguments[1], 2);
return null;
} else if (invoke.memberName == #test1) {
- Expect.isTrue(invoke.namedArguments.isEmpty);
+ Expect.isTrue(invoke.namedArguments.length == 1);
+ Expect.equals(null, invoke.namedArguments[#x]);
return null;
} else if (invoke.memberName == #test2) {
- Expect.isTrue(invoke.namedArguments.isEmpty);
+ Expect.isTrue(invoke.namedArguments.length == 1);
+ Expect.equals("w/e", invoke.namedArguments[#x]);
return null;
} else if (invoke.memberName == #test3) {
Expect.equals(invoke.namedArguments[#x], "ok");
@@ -42,6 +44,9 @@
Expect.equals(invoke.namedArguments.length, 1);
Expect.equals(invoke.namedArguments[#foo], const <num>[3, 4]);
+ } else if (invoke.memberName == #test8) {
+ Expect.equals(1, invoke.positionalArguments.length);
+ Expect.equals(null, invoke.positionalArguments[0]);
}
}
@@ -56,6 +61,8 @@
int get test7;
void set test7(int x);
+ void test8([String x]);
+
T allTogetherNow<T, S extends T>(S x1, {List<T> foo: const <Null>[]});
}
@@ -89,4 +96,6 @@
Expect.throwsTypeError(() => (a as dynamic).test7 = "hi");
a.allTogetherNow<num, double>(2.0, foo: const <num>[3, 4]);
+
+ a.test8();
}
diff --git a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test.dart b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test.dart
new file mode 100644
index 0000000..69a554f
--- /dev/null
+++ b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing that `noSuchMethod` forwarders can be partially instantiated, and
+// that their delayed type arguments are transparently passed to `noSuchMethod`.
+
+import 'package:expect/expect.dart';
+
+class C {
+ T test1<T>(T x);
+
+ dynamic noSuchMethod(Invocation invoke) {
+ Expect.equals(invoke.typeArguments.length, 1);
+ Expect.equals(invoke.typeArguments[0].toString(), 'int');
+ Expect.equals(invoke.positionalArguments[0], 1);
+ return null;
+ }
+}
+
+void main() {
+ var c = new C();
+ int Function(int) k1 = c.test1;
+ k1(1);
+}
diff --git a/tests/language_2/vm/regress_31946_test.dart b/tests/language_2/vm/regress_31946_test.dart
new file mode 100644
index 0000000..19554a0
--- /dev/null
+++ b/tests/language_2/vm/regress_31946_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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=--no_background_compilation --optimization_counter_threshold=10
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+var root = [];
+var tests = <dynamic>[
+ () async {},
+ () async {
+ await new Future.value();
+ root.singleWhere((f) => f.name == 'optimizedFunction');
+ },
+];
+
+main(args) async {
+ for (int i = 0; i < 100; ++i) {
+ int exceptions = 0;
+ for (final test in tests) {
+ try {
+ await test();
+ } on StateError {
+ exceptions++;
+ }
+ }
+ Expect.isTrue(exceptions == 1);
+ }
+}
diff --git a/tests/language_2/vm/regress_33095_test.dart b/tests/language_2/vm/regress_33095_test.dart
new file mode 100644
index 0000000..9dd97c0
--- /dev/null
+++ b/tests/language_2/vm/regress_33095_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for 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";
+
+typedef String IntFunctionType(int _);
+
+class Box {
+ final IntFunctionType fun;
+ const Box(this.fun);
+}
+
+String genericFunction<T>(T v) => '$v';
+
+void main() {
+ const list = const [const Box(genericFunction)];
+ Expect.equals('42', list.first.fun(42));
+}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 092573e..9177102 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -700,8 +700,6 @@
html/js_typed_interop_default_arg_test/explicit_argument: CompileTimeError
html/js_typed_interop_side_cast_exp_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
html/js_typed_interop_test: CompileTimeError
-typed_data/typed_data_list_test: Crash
-typed_data/typed_list_iterable_test: Crash
[ $compiler == dart2js && $fasta && $minified ]
html/audiobuffersourcenode_test/functional: RuntimeError
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index bf33435..65dbd6b 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -30,6 +30,9 @@
mirrors/reflected_type_test/03: MissingCompileTimeError
mirrors/variable_is_const_test/01: MissingCompileTimeError
+[ $arch == simdbc64 && $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
+isolate/isolate_complex_messages_test: Crash # http://dartbug.com/33128
+
[ $arch == x64 && $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
mirrors/invocation_fuzz_test: Skip # Because it times out, issue 29439.
mirrors/variable_is_const_test/01: Crash
@@ -49,7 +52,6 @@
isolate/browser/package_resolve_browser_test: CompileTimeError
[ $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
-isolate/isolate_complex_messages_test: Crash
mirrors/other_declarations_location_test: Crash # assertion error, TypeParameter not having position.
[ $compiler == dartk && $mode == debug && $strong ]
@@ -260,7 +262,6 @@
*: SkipByDesign
[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled && $strong ]
-isolate/isolate_complex_messages_test: Crash
isolate/static_function_test: Skip # Flaky (https://github.com/dart-lang/sdk/issues/30063).
# ===== dartkp + dart_precompiled status lines =====
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 05c6d9c..22bb3c2 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -69,6 +69,9 @@
io/socket_invalid_arguments_test: Fail, OK # These tests have type errors on purpose.
io/stdout_bad_argument_test: Fail, OK # These tests have type errors on purpose.
+[ !$strong && ($compiler == dartk || $compiler == dartkp) ]
+*: Skip
+
[ $compiler == app_jit || $compiler == precompiler ]
io/compile_all_test: Skip # Incompatible flag --compile_all
diff --git a/tests/standalone_2/io/secure_client_server_test.dart b/tests/standalone_2/io/secure_client_server_test.dart
index ac76bbb..c8cb48e 100644
--- a/tests/standalone_2/io/secure_client_server_test.dart
+++ b/tests/standalone_2/io/secure_client_server_test.dart
@@ -41,10 +41,27 @@
});
}
+void checkServerCertificate(X509Certificate serverCert) {
+ String serverCertString = serverCert.pem;
+ String certFile =
+ new File(localFile('certificates/server_chain.pem')).readAsStringSync();
+ Expect.isTrue(certFile.contains(serverCertString));
+
+ // Computed with:
+ // openssl x509 -noout -sha1 -fingerprint -in certificates/server_chain.pem
+ List<int> serverSha1 = <int>[
+ 0xB3, 0x01, 0xCB, 0x7E, 0x6F, 0xEF, 0xBE, 0xEF, //
+ 0x75, 0x6D, 0xA8, 0x80, 0x60, 0xA8, 0x5D, 0x6F, //
+ 0xC4, 0xED, 0xCD, 0x48, //
+ ];
+ Expect.listEquals(serverSha1, serverCert.sha1);
+}
+
Future testClient(server) {
return SecureSocket
.connect(HOST, server.port, context: clientContext)
.then((socket) {
+ checkServerCertificate(socket.peerCertificate);
socket.write("Hello server.");
socket.close();
return socket.fold(<int>[], (message, data) => message..addAll(data)).then(
diff --git a/tests/standalone_2/standalone_2_precompiled.status b/tests/standalone_2/standalone_2_precompiled.status
index 99e6eb8..bbaa92a 100644
--- a/tests/standalone_2/standalone_2_precompiled.status
+++ b/tests/standalone_2/standalone_2_precompiled.status
@@ -19,6 +19,7 @@
io/http_server_close_response_after_error_test: Skip
io/https_unauthorized_test: Skip
io/named_pipe_script_test: Skip
+io/namespace_test: Skip # Issue 33168
io/platform_resolved_executable_test: Skip
io/platform_test: RuntimeError # Expects to be running from 'dart' instead of 'dart_precompiled_runtime'
io/print_sync_test: Skip
@@ -45,6 +46,7 @@
io/stdio_nonblocking_test: Skip
io/test_extension_fail_test: Skip
io/test_extension_test: Skip
+io/test_runner_test: RuntimeError # Issue 33168
io/windows_environment_test: Skip
[ $arch == arm && $mode == release && $runtime == dart_precompiled && $system == android ]
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index 4b95f11..03479a7 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -9,9 +9,17 @@
[ $compiler == app_jit ]
full_coverage_test: Skip # Platform.executable
io/code_collection_test: Skip # Platform.executable
+io/namespace_test: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/00: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/01: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/02: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/03: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/04: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/05: RuntimeError # Issue 33168
io/platform_test: Skip # Platform.executable
io/test_extension_fail_test: Skip # Platform.executable
io/test_extension_test: Skip # Platform.executable
+io/test_runner_test: RuntimeError # Issue 33168
regress_26031_test: Skip # Platform.resolvedExecutable
[ $system == android ]
diff --git a/third_party/tcmalloc/BUILD.gn b/third_party/tcmalloc/BUILD.gn
index bea0427..9ab294d 100644
--- a/third_party/tcmalloc/BUILD.gn
+++ b/third_party/tcmalloc/BUILD.gn
@@ -31,6 +31,8 @@
"-fno-builtin-posix_memalign",
"-fno-builtin-valloc",
"-fno-builtin-pvalloc",
+ "-fsized-deallocation",
+ "-faligned-new",
]
if (is_clang) {
cflags += [ "-Wno-unused-const-variable" ]
diff --git a/third_party/tcmalloc/include/config.h b/third_party/tcmalloc/include/config.h
index 2cd633a..16b2d7d 100644
--- a/third_party/tcmalloc/include/config.h
+++ b/third_party/tcmalloc/include/config.h
@@ -6,6 +6,9 @@
#define GPERFTOOLS_CONFIG_H_
+/* Build new/delete operators for overaligned types */
+/* #undef ENABLE_ALIGNED_NEW_DELETE */
+
/* Build runtime detection for sized delete */
/* #undef ENABLE_DYNAMIC_SIZED_DELETE */
@@ -206,6 +209,9 @@
/* define if your compiler has __attribute__ */
#define HAVE___ATTRIBUTE__ 1
+/* define if your compiler supports alignment of functions */
+#define HAVE___ATTRIBUTE__ALIGNED_FN 1
+
/* Define to 1 if compiler supports __environ */
#if !defined(__ANDROID__)
#define HAVE___ENVIRON 1
@@ -220,13 +226,9 @@
/* Define to 1 if int32_t is equivalent to intptr_t */
/* #undef INT32_EQUALS_INTPTR */
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
-/* Define to 'volatile' if __malloc_hook is declared volatile */
-#define MALLOC_HOOK_MAYBE_VOLATILE volatile
-
/* Name of package */
#define PACKAGE "gperftools"
@@ -237,7 +239,7 @@
#define PACKAGE_NAME "gperftools"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gperftools 2.5"
+#define PACKAGE_STRING "gperftools 2.7"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "gperftools"
@@ -246,7 +248,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.5"
+#define PACKAGE_VERSION "2.7"
/* How to access the PC from a struct ucontext */
/* #undef PC_FROM_UCONTEXT */
@@ -293,7 +295,7 @@
/* #undef TCMALLOC_ALIGN_8BYTES */
/* Version number of package */
-#define VERSION "2.5"
+#define VERSION "2.7"
/* C99 says: define this to get the PRI... macros from stdint.h */
#ifndef __STDC_FORMAT_MACROS
@@ -312,3 +314,4 @@
#endif
#endif /* #ifndef GPERFTOOLS_CONFIG_H_ */
+
diff --git a/third_party/tcmalloc/include/gperftools/tcmalloc.h b/third_party/tcmalloc/include/gperftools/tcmalloc.h
index 138d1f9..7935081 100644
--- a/third_party/tcmalloc/include/gperftools/tcmalloc.h
+++ b/third_party/tcmalloc/include/gperftools/tcmalloc.h
@@ -37,30 +37,38 @@
#define TCMALLOC_TCMALLOC_H_
#include <stddef.h> /* for size_t */
+#ifdef __cplusplus
+#include <new> /* for std::nothrow_t, std::align_val_t */
+#endif
/* Define the version number so folks can check against it */
#define TC_VERSION_MAJOR 2
-#define TC_VERSION_MINOR 5
+#define TC_VERSION_MINOR 7
#define TC_VERSION_PATCH ""
-#define TC_VERSION_STRING "gperftools 2.5"
+#define TC_VERSION_STRING "gperftools 2.7"
/* For struct mallinfo, if it's defined. */
#if 1
# include <malloc.h>
#endif
-#ifdef __cplusplus
-#define PERFTOOLS_THROW throw()
+#ifndef PERFTOOLS_NOTHROW
+
+#if __cplusplus >= 201103L
+#define PERFTOOLS_NOTHROW noexcept
+#elif defined(__cplusplus)
+#define PERFTOOLS_NOTHROW throw()
#else
# ifdef __GNUC__
-# define PERFTOOLS_THROW __attribute__((__nothrow__))
+# define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
# else
-# define PERFTOOLS_THROW
+# define PERFTOOLS_NOTHROW
# endif
#endif
+#endif
+
#ifndef PERFTOOLS_DLL_DECL
-#define PERFTOOLS_DLL_DECL_DEFINED
# ifdef _WIN32
# define PERFTOOLS_DLL_DECL __declspec(dllimport)
# else
@@ -69,10 +77,6 @@
#endif
#ifdef __cplusplus
-namespace std {
-struct nothrow_t;
-}
-
extern "C" {
#endif
/*
@@ -81,27 +85,27 @@
* minor version, and patch-code (a string, usually "").
*/
PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
- const char** patch) PERFTOOLS_THROW;
+ const char** patch) PERFTOOLS_NOTHROW;
- PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_THROW;
+ PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
- size_t __size) PERFTOOLS_THROW;
+ size_t __size) PERFTOOLS_NOTHROW;
PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
- size_t align, size_t size) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_THROW;
+ size_t align, size_t size) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
- PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_THROW;
+ PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
#if 1
- PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_THROW;
+ PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW;
#endif
/*
@@ -111,36 +115,48 @@
* glibc: malloc_usable_size()
* Windows: _msize()
*/
- PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_THROW;
+ PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
#ifdef __cplusplus
- PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_THROW;
+ PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
PERFTOOLS_DLL_DECL void* tc_new(size_t size);
PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
- const std::nothrow_t&) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) throw();
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
- const std::nothrow_t&) PERFTOOLS_THROW;
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
- const std::nothrow_t&) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_THROW;
- PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) throw();
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
- const std::nothrow_t&) PERFTOOLS_THROW;
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
+
+#if 1 && __cplusplus >= 201703L
+ PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
+ PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
+ PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
+ const std::nothrow_t&) PERFTOOLS_NOTHROW;
+#endif
}
#endif
-/* We're only un-defining those for public */
+/* We're only un-defining for public */
#if !defined(GPERFTOOLS_CONFIG_H_)
-#undef PERFTOOLS_THROW
-
-#ifdef PERFTOOLS_DLL_DECL_DEFINED
-#undef PERFTOOLS_DLL_DECL
-#undef PERFTOOLS_DLL_DECL_DEFINED
-#endif
+#undef PERFTOOLS_NOTHROW
#endif /* GPERFTOOLS_CONFIG_H_ */
diff --git a/tools/VERSION b/tools/VERSION
index b5da02e..b7ef033 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 0
PATCH 0
-PRERELEASE 55
+PRERELEASE 56
PRERELEASE_PATCH 0
diff --git a/tools/bots/dart2js_d8_hostchecked_tests.isolate b/tools/bots/dart2js_d8_hostchecked_tests.isolate
index 23c2346..1b53302 100644
--- a/tools/bots/dart2js_d8_hostchecked_tests.isolate
+++ b/tools/bots/dart2js_d8_hostchecked_tests.isolate
@@ -19,7 +19,23 @@
'third_party/pkg/',
'third_party/pkg_tested/',
'third_party/d8/',
- 'tests/',
+ 'tests/angular/',
+ 'tests/co19/',
+ 'tests/compiler/',
+ 'tests/corelib/',
+ 'tests/corelib_2/',
+ 'tests/dart/',
+ 'tests/html/',
+ 'tests/isolate/',
+ 'tests/kernel/',
+ 'tests/language/',
+ 'tests/language_2/',
+ 'tests/lib/',
+ 'tests/lib_2/',
+ 'tests/light_unittest.dart',
+ 'tests/search/',
+ 'tests/standalone/',
+ 'tests/standalone_2/',
'pkg/async_helper/',
'pkg/compiler/',
'pkg/dart_internal/',
diff --git a/tools/bots/dart_tests.isolate b/tools/bots/dart_tests.isolate
index 74ac8b4..d2b7a74 100644
--- a/tools/bots/dart_tests.isolate
+++ b/tools/bots/dart_tests.isolate
@@ -12,7 +12,23 @@
'third_party/d8/',
'third_party/firefox_jsshell/',
'third_party/observatory_pub_packages/packages/web_components/',
- 'tests/',
+ 'tests/angular/',
+ 'tests/co19/',
+ 'tests/compiler/',
+ 'tests/corelib/',
+ 'tests/corelib_2/',
+ 'tests/dart/',
+ 'tests/html/',
+ 'tests/isolate/',
+ 'tests/kernel/',
+ 'tests/language/',
+ 'tests/language_2/',
+ 'tests/lib/',
+ 'tests/lib_2/',
+ 'tests/light_unittest.dart',
+ 'tests/search/',
+ 'tests/standalone/',
+ 'tests/standalone_2/',
'pkg/async_helper/',
'pkg/browser/',
'pkg/compiler/',
diff --git a/tools/bots/pub_integration_test.py b/tools/bots/pub_integration_test.py
new file mode 100755
index 0000000..61168c2
--- /dev/null
+++ b/tools/bots/pub_integration_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for 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 os
+import subprocess
+import sys
+import shutil
+import tempfile
+
+PUBSPEC = """name: pub_integration_test
+dependencies:
+ shelf:
+ test:
+"""
+
+def Main():
+ out_dir = 'xcodebuild' if sys.platform == 'darwin' else 'out'
+ extension = '' if not sys.platform == 'win32' else '.bat'
+ pub = os.path.abspath(
+ '%s/ReleaseX64/dart-sdk/bin/pub%s' % (out_dir, extension))
+
+ working_dir = tempfile.mkdtemp()
+ try:
+ pub_cache_dir = working_dir + '/pub_cache'
+ env = os.environ.copy()
+ env['PUB_CACHE'] = pub_cache_dir
+
+ with open(working_dir + '/pubspec.yaml', 'w') as pubspec_yaml:
+ pubspec_yaml.write(PUBSPEC)
+
+ exit_code = subprocess.call([pub, 'get'], cwd=working_dir, env=env)
+ if exit_code is not 0:
+ return exit_code
+
+ exit_code = subprocess.call([pub, 'upgrade'], cwd=working_dir, env=env)
+ if exit_code is not 0:
+ return exit_code
+ finally:
+ shutil.rmtree(working_dir);
+
+if __name__ == '__main__':
+ sys.exit(Main())
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 585a075..8695c4c 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -18,7 +18,23 @@
"runtime/tests/",
"samples-dev/",
"samples/",
- "tests/",
+ "tests/angular/",
+ "tests/co19/",
+ "tests/compiler/",
+ "tests/corelib/",
+ "tests/corelib_2/",
+ "tests/dart/",
+ "tests/html/",
+ "tests/isolate/",
+ "tests/kernel/",
+ "tests/language/",
+ "tests/language_2/",
+ "tests/lib/",
+ "tests/lib_2/",
+ "tests/light_unittest.dart",
+ "tests/search/",
+ "tests/standalone/",
+ "tests/standalone_2/",
"third_party/d8/",
"third_party/observatory_pub_packages/packages/web_components/",
"third_party/pkg/",
@@ -728,7 +744,7 @@
{
"name": "build dart",
"script": "tools/build.py",
- "arguments": ["dart2js_bot", "compile_dart2js_platform"]
+ "arguments": ["dart2js_bot"]
},
{
"name": "dart2js tests",
@@ -1613,14 +1629,8 @@
"tests": ["pkg_tested"]
},
{
- "name": "pub get dependencies",
- "arguments": [
- "--use-sdk",
- "--compiler=none",
- "--runtime=vm",
- "--checked"
- ],
- "tests": ["pkgbuild"]
+ "name": "pub integration tests",
+ "script": "tools/bots/pub_integration_test.py"
}
]
},
diff --git a/tools/infra/config/cq.cfg b/tools/infra/config/cq.cfg
index 2bf13e2..508d716 100644
--- a/tools/infra/config/cq.cfg
+++ b/tools/infra/config/cq.cfg
@@ -31,8 +31,9 @@
builders { name: "pkg-linux-release-try" }
builders { name: "vm-canary-linux-debug-try" }
builders { name: "vm-kernel-legacy-linux-release-x64-try" }
- builders { name: "vm-kernel-mac-release-x64-try" experiment_percentage: 100 }
+ builders { name: "vm-kernel-linux-release-simdbc64-try" }
builders { name: "vm-kernel-linux-release-x64-try" }
+ builders { name: "vm-kernel-mac-release-x64-try" experiment_percentage: 100 }
builders { name: "vm-linux-product-x64-try" }
builders { name: "vm-linux-release-x64-try" }
builders { name: "vm-mac-release-x64-try" }
diff --git a/tools/sdks/linux/dart-sdk.tar.gz.sha1 b/tools/sdks/linux/dart-sdk.tar.gz.sha1
index d3e10bd..c32cb3c 100644
--- a/tools/sdks/linux/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/linux/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-bcfe42edaebd8c1a13a78590aab6235769160858
\ No newline at end of file
+dbd141e72b88a1a30768af3acf75eba45963a896
\ No newline at end of file
diff --git a/tools/sdks/mac/dart-sdk.tar.gz.sha1 b/tools/sdks/mac/dart-sdk.tar.gz.sha1
index a34fc3f..cf501d1 100644
--- a/tools/sdks/mac/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/mac/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-f1c33b5acdf0a3a4bd7838f98d71cf6199d38aa1
\ No newline at end of file
+6b686b5dd4a33806fc136cf01fa4bf3ac7f661b7
\ No newline at end of file
diff --git a/tools/sdks/win/dart-sdk.tar.gz.sha1 b/tools/sdks/win/dart-sdk.tar.gz.sha1
index cc0bdcf..902188f 100644
--- a/tools/sdks/win/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/win/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-0a1a4fbd27281366e873ab5135260583286a2190
\ No newline at end of file
+898a3784afca3a8f0e8624fda56d243aadd1b95d
\ No newline at end of file
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 4bc4061..5f930c6 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -498,7 +498,6 @@
List<String> ddcOptions,
List<String> args) {
var result = sharedOptions.toList()..addAll(ddcOptions);
-
// The file being compiled is the last argument.
result.add(args.last);
@@ -1062,6 +1061,8 @@
bool get _useSdk;
bool get _isStrong;
bool get _isAot;
+ bool get _isChecked;
+ bool get _useEnableAsserts;
String get executableScriptSuffix;
@@ -1107,6 +1108,10 @@
}
args.add(arguments.where((name) => name.endsWith('.dart')).single);
+ args.addAll(arguments.where((name) => name.startsWith('-D')));
+ if (_isChecked || _useEnableAsserts) {
+ args.add('--enable_asserts');
+ }
// Pass environment variable to the gen_kernel script as
// arguments are not passed if gen_kernel runs in batch mode.
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 8260858..52974f7 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1053,13 +1053,14 @@
'%TEST_SCRIPTS%', '<script src="$nameNoExt.js"></script>');
} else {
// Synthesize an HTML file for the test.
- var scriptPath = _createUrlPathFromFile(new Path(jsWrapperFileName));
-
if (configuration.compiler == Compiler.dart2js) {
+ var scriptPath = _createUrlPathFromFile(new Path(jsWrapperFileName));
content = dart2jsHtml(fileName, scriptPath);
} else {
var jsDir =
new Path(compilationTempDir).relativeTo(Repository.dir).toString();
+ jsWrapperFileName =
+ new Path('$compilationTempDir/$nameNoExt.js').toNativePath();
// Always run with synchronous starts of `async` functions.
// If we want to make this dependent on other parameters or flags,
// this flag could be become conditional.
@@ -1095,50 +1096,36 @@
// browser test. For running Dart in DRT, this will be noop commands.
var commands = <Command>[];
- switch (configuration.compiler) {
- case Compiler.dart2js:
- commands.add(_dart2jsCompileCommand(
- fileName, jsWrapperFileName, tempDir, optionsFromFile));
- break;
-
- case Compiler.dartdevc:
- case Compiler.dartdevk:
- var toPath =
- new Path('$compilationTempDir/$nameNoExt.js').toNativePath();
- commands.add(configuration.compilerConfiguration.createCommand(
- fileName,
- toPath,
- optionsFromFile["sharedOptions"] as List<String>,
- environmentOverrides));
- break;
-
- default:
- assert(false);
- }
-
- // Some tests require compiling multiple input scripts.
- for (var name in optionsFromFile['otherScripts'] as List<String>) {
- var namePath = new Path(name);
- var fromPath = info.filePath.directoryPath.join(namePath);
- var toPath = new Path('$tempDir/${namePath.filename}.js').toNativePath();
-
+ void addCompileCommand(String fileName, String toPath) {
switch (configuration.compiler) {
case Compiler.dart2js:
commands.add(_dart2jsCompileCommand(
- fromPath.toNativePath(), toPath, tempDir, optionsFromFile));
+ fileName, toPath, tempDir, optionsFromFile));
break;
case Compiler.dartdevc:
case Compiler.dartdevk:
+ var ddcOptions = optionsFromFile["sharedOptions"] as List<String>;
+ ddcOptions.addAll(optionsFromFile["ddcOptions"] as List<String>);
commands.add(configuration.compilerConfiguration.createCommand(
- fromPath.toNativePath(),
- toPath,
- optionsFromFile["sharedOptions"] as List<String>,
- environmentOverrides));
+ fileName, toPath, ddcOptions, environmentOverrides));
break;
+
+ default:
+ assert(false);
}
}
+ addCompileCommand(fileName, jsWrapperFileName);
+
+ // Some tests require compiling multiple input scripts.
+ for (var name in optionsFromFile['otherScripts'] as List<String>) {
+ var namePath = new Path(name);
+ var fromPath = info.filePath.directoryPath.join(namePath).toNativePath();
+ var toPath = new Path('$tempDir/${namePath.filename}.js').toNativePath();
+ addCompileCommand(fromPath, toPath);
+ }
+
if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
// Variables for browser multi-tests.
var subtestNames = info.optionsFromFile['subtestNames'] as List<String>;
diff --git a/utils/compile_platform.gni b/utils/compile_platform.gni
index 8c933ce..5158a53 100644
--- a/utils/compile_platform.gni
+++ b/utils/compile_platform.gni
@@ -5,6 +5,12 @@
import("../build/dart/dart_host_sdk_toolchain.gni")
import("../build/dart/prebuilt_dart_sdk.gni")
+_is_fuchsia = defined(is_fuchsia_tree) && is_fuchsia_tree
+
+if (_is_fuchsia) {
+ import("//build/dart/dart.gni")
+}
+
_dart_root = get_path_info("..", "abspath")
template("compile_platform") {
@@ -35,7 +41,12 @@
depfile = outputs[0] + ".d"
- if (!prebuilt_dart_exe_works) {
+ if (_is_fuchsia) {
+ args += [
+ "--dart-executable",
+ rebase_path(prebuilt_dart),
+ ]
+ } else if (!prebuilt_dart_exe_works) {
deps += [ "$_dart_root/runtime/bin:dart_bootstrap($dart_host_toolchain)" ]
dart_out_dir = get_label_info(
"$_dart_root/runtime/bin:dart_bootstrap($dart_host_toolchain)",
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 0350464..0c5c4e2 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -11,6 +11,10 @@
sdk_dill = "$target_gen_dir/kernel/ddc_sdk.dill"
application_snapshot("dartdevc") {
+ vm_args = [
+ "--preview-dart-2",
+ ]
+
main_dart = "../../pkg/dev_compiler/bin/dartdevc.dart"
training_args = [
diff --git a/utils/pub/BUILD.gn b/utils/pub/BUILD.gn
index b2f724c..f34a69a 100644
--- a/utils/pub/BUILD.gn
+++ b/utils/pub/BUILD.gn
@@ -8,3 +8,11 @@
main_dart = "../../third_party/pkg/pub/bin/pub.dart"
training_args = [ "--help" ]
}
+
+application_snapshot("pub2") {
+ main_dart = "../../third_party/pkg/pub/bin/pub.dart"
+ training_args = [ "--help" ]
+ vm_args = [
+ "--preview-dart-2",
+ ]
+}